1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <cfloat>
12 #include <cstdio>
13 #include <cstdlib>
14 #include <vector>
15
16 #include "webrtc/modules/audio_processing/transient/transient_detector.h"
17 #include "webrtc/modules/audio_processing/transient/file_utils.h"
18 #include "webrtc/base/scoped_ptr.h"
19 #include "webrtc/system_wrappers/include/file_wrapper.h"
20
21 using rtc::scoped_ptr;
22 using webrtc::FileWrapper;
23 using webrtc::TransientDetector;
24
25 // Application to generate a RTP timing file.
26 // Opens the PCM file and divides the signal in frames.
27 // Creates a send times array, one for each step.
28 // Each block that contains a transient, has an infinite send time.
29 // The resultant array is written to a DAT file
30 // Returns -1 on error or |lost_packets| otherwise.
main(int argc,char * argv[])31 int main(int argc, char* argv[]) {
32 if (argc != 5) {
33 printf("\n%s - Application to generate a RTP timing file.\n\n", argv[0]);
34 printf("%s PCMfile DATfile chunkSize sampleRate\n\n", argv[0]);
35 printf("Opens the PCMfile with sampleRate in Hertz.\n");
36 printf("Creates a send times array, one for each chunkSize ");
37 printf("milliseconds step.\n");
38 printf("Each block that contains a transient, has an infinite send time. ");
39 printf("The resultant array is written to a DATfile.\n\n");
40 return 0;
41 }
42
43 scoped_ptr<FileWrapper> pcm_file(FileWrapper::Create());
44 pcm_file->OpenFile(argv[1], true, false, false);
45 if (!pcm_file->Open()) {
46 printf("\nThe %s could not be opened.\n\n", argv[1]);
47 return -1;
48 }
49
50 scoped_ptr<FileWrapper> dat_file(FileWrapper::Create());
51 dat_file->OpenFile(argv[2], false, false, false);
52 if (!dat_file->Open()) {
53 printf("\nThe %s could not be opened.\n\n", argv[2]);
54 return -1;
55 }
56
57 int chunk_size_ms = atoi(argv[3]);
58 if (chunk_size_ms <= 0) {
59 printf("\nThe chunkSize must be a positive integer\n\n");
60 return -1;
61 }
62
63 int sample_rate_hz = atoi(argv[4]);
64 if (sample_rate_hz <= 0) {
65 printf("\nThe sampleRate must be a positive integer\n\n");
66 return -1;
67 }
68
69 TransientDetector detector(sample_rate_hz);
70 int lost_packets = 0;
71 size_t audio_buffer_length = chunk_size_ms * sample_rate_hz / 1000;
72 scoped_ptr<float[]> audio_buffer(new float[audio_buffer_length]);
73 std::vector<float> send_times;
74
75 // Read first buffer from the PCM test file.
76 size_t file_samples_read = ReadInt16FromFileToFloatBuffer(
77 pcm_file.get(),
78 audio_buffer_length,
79 audio_buffer.get());
80 for (int time = 0; file_samples_read > 0; time += chunk_size_ms) {
81 // Pad the rest of the buffer with zeros.
82 for (size_t i = file_samples_read; i < audio_buffer_length; ++i) {
83 audio_buffer[i] = 0.0;
84 }
85 float value =
86 detector.Detect(audio_buffer.get(), audio_buffer_length, NULL, 0);
87 if (value < 0.5f) {
88 value = time;
89 } else {
90 value = FLT_MAX;
91 ++lost_packets;
92 }
93 send_times.push_back(value);
94
95 // Read next buffer from the PCM test file.
96 file_samples_read = ReadInt16FromFileToFloatBuffer(pcm_file.get(),
97 audio_buffer_length,
98 audio_buffer.get());
99 }
100
101 size_t floats_written = WriteFloatBufferToFile(dat_file.get(),
102 send_times.size(),
103 &send_times[0]);
104
105 if (floats_written == 0) {
106 printf("\nThe send times could not be written to DAT file\n\n");
107 return -1;
108 }
109
110 pcm_file->CloseFile();
111 dat_file->CloseFile();
112
113 return lost_packets;
114 }
115