| /* |
| * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include <cfloat> |
| #include <cstdio> |
| #include <cstdlib> |
| #include <memory> |
| #include <vector> |
| |
| #include "modules/audio_processing/transient/transient_detector.h" |
| #include "modules/audio_processing/transient/file_utils.h" |
| #include "system_wrappers/include/file_wrapper.h" |
| |
| using webrtc::FileWrapper; |
| using webrtc::TransientDetector; |
| |
| // Application to generate a RTP timing file. |
| // Opens the PCM file and divides the signal in frames. |
| // Creates a send times array, one for each step. |
| // Each block that contains a transient, has an infinite send time. |
| // The resultant array is written to a DAT file |
| // Returns -1 on error or |lost_packets| otherwise. |
| int main(int argc, char* argv[]) { |
| if (argc != 5) { |
| printf("\n%s - Application to generate a RTP timing file.\n\n", argv[0]); |
| printf("%s PCMfile DATfile chunkSize sampleRate\n\n", argv[0]); |
| printf("Opens the PCMfile with sampleRate in Hertz.\n"); |
| printf("Creates a send times array, one for each chunkSize "); |
| printf("milliseconds step.\n"); |
| printf("Each block that contains a transient, has an infinite send time. "); |
| printf("The resultant array is written to a DATfile.\n\n"); |
| return 0; |
| } |
| |
| std::unique_ptr<FileWrapper> pcm_file(FileWrapper::Create()); |
| pcm_file->OpenFile(argv[1], true); |
| if (!pcm_file->is_open()) { |
| printf("\nThe %s could not be opened.\n\n", argv[1]); |
| return -1; |
| } |
| |
| std::unique_ptr<FileWrapper> dat_file(FileWrapper::Create()); |
| dat_file->OpenFile(argv[2], false); |
| if (!dat_file->is_open()) { |
| printf("\nThe %s could not be opened.\n\n", argv[2]); |
| return -1; |
| } |
| |
| int chunk_size_ms = atoi(argv[3]); |
| if (chunk_size_ms <= 0) { |
| printf("\nThe chunkSize must be a positive integer\n\n"); |
| return -1; |
| } |
| |
| int sample_rate_hz = atoi(argv[4]); |
| if (sample_rate_hz <= 0) { |
| printf("\nThe sampleRate must be a positive integer\n\n"); |
| return -1; |
| } |
| |
| TransientDetector detector(sample_rate_hz); |
| int lost_packets = 0; |
| size_t audio_buffer_length = chunk_size_ms * sample_rate_hz / 1000; |
| std::unique_ptr<float[]> audio_buffer(new float[audio_buffer_length]); |
| std::vector<float> send_times; |
| |
| // Read first buffer from the PCM test file. |
| size_t file_samples_read = ReadInt16FromFileToFloatBuffer( |
| pcm_file.get(), |
| audio_buffer_length, |
| audio_buffer.get()); |
| for (int time = 0; file_samples_read > 0; time += chunk_size_ms) { |
| // Pad the rest of the buffer with zeros. |
| for (size_t i = file_samples_read; i < audio_buffer_length; ++i) { |
| audio_buffer[i] = 0.0; |
| } |
| float value = |
| detector.Detect(audio_buffer.get(), audio_buffer_length, NULL, 0); |
| if (value < 0.5f) { |
| value = time; |
| } else { |
| value = FLT_MAX; |
| ++lost_packets; |
| } |
| send_times.push_back(value); |
| |
| // Read next buffer from the PCM test file. |
| file_samples_read = ReadInt16FromFileToFloatBuffer(pcm_file.get(), |
| audio_buffer_length, |
| audio_buffer.get()); |
| } |
| |
| size_t floats_written = WriteFloatBufferToFile(dat_file.get(), |
| send_times.size(), |
| &send_times[0]); |
| |
| if (floats_written == 0) { |
| printf("\nThe send times could not be written to DAT file\n\n"); |
| return -1; |
| } |
| |
| pcm_file->CloseFile(); |
| dat_file->CloseFile(); |
| |
| return lost_packets; |
| } |