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. 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