OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // This application is a test for AudioRendererAlgorithmOLA. It reads in a |
| 6 // specified wav file (so far only 8, 16 and 32 bit are supported) and uses |
| 7 // ARAO to scale the playback by a specified rate. Then it outputs the result |
| 8 // to the specified location. Command line calls should be as follows: |
| 9 // |
| 10 // wav_ola_test RATE INFILE OUTFILE |
| 11 |
| 12 #include <iostream> |
| 13 #include <string> |
| 14 |
| 15 #include "base/command_line.h" |
| 16 #include "base/file_util.h" |
| 17 #include "base/ref_counted.h" |
| 18 #include "base/string_util.h" |
| 19 #include "media/base/data_buffer.h" |
| 20 #include "media/filters/audio_renderer_algorithm_ola.h" |
| 21 |
| 22 using file_util::ScopedFILE; |
| 23 using media::AudioRendererAlgorithmOLA; |
| 24 using media::DataBuffer; |
| 25 |
| 26 const size_t kDefaultWindowSize = 4096; |
| 27 |
| 28 struct WavHeader { |
| 29 int32 riff; |
| 30 int32 chunk_size; |
| 31 char unused0[8]; |
| 32 int32 subchunk1_size; |
| 33 int16 audio_format; |
| 34 int16 channels; |
| 35 int32 sample_rate; |
| 36 char unused1[6]; |
| 37 int16 bit_rate; |
| 38 char unused2[4]; |
| 39 int32 subchunk2_size; |
| 40 }; |
| 41 |
| 42 // Dummy class to feed data to OLA algorithm. Necessary to create callback. |
| 43 class Dummy { |
| 44 public: |
| 45 Dummy(FILE* in, AudioRendererAlgorithmOLA* ola) |
| 46 : input_(in), |
| 47 ola_(ola) { |
| 48 } |
| 49 |
| 50 void ReadDataForAlg() { |
| 51 scoped_refptr<DataBuffer> b(new DataBuffer()); |
| 52 uint8* buf = b->GetWritableData(kDefaultWindowSize); |
| 53 if (fread(buf, 1, kDefaultWindowSize, input_) > 0) { |
| 54 ola_->EnqueueBuffer(b.get()); |
| 55 } |
| 56 } |
| 57 |
| 58 private: |
| 59 FILE* input_; |
| 60 AudioRendererAlgorithmOLA* ola_; |
| 61 |
| 62 DISALLOW_COPY_AND_ASSIGN(Dummy); |
| 63 }; |
| 64 |
| 65 int main(int argc, const char** argv) { |
| 66 AudioRendererAlgorithmOLA ola; |
| 67 CommandLine::Init(argc, argv); |
| 68 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 69 |
| 70 std::vector<std::wstring> filenames(cmd_line->GetLooseValues()); |
| 71 if (filenames.empty()) { |
| 72 std::cerr << "Usage: alg_test RATE INFILE OUTFILE\n" |
| 73 << std::endl; |
| 74 return 1; |
| 75 } |
| 76 |
| 77 // Retrieve command line options. |
| 78 std::string in_path(WideToUTF8(filenames[1])); |
| 79 std::string out_path(WideToUTF8(filenames[2])); |
| 80 double playback_rate = 0.0; |
| 81 |
| 82 // Determine speed of rerecord. |
| 83 if (!StringToDouble(WideToUTF8(filenames[0]), &playback_rate)) |
| 84 playback_rate = 0.0; |
| 85 |
| 86 // Open input file. |
| 87 ScopedFILE input(file_util::OpenFile(in_path.c_str(), "rb")); |
| 88 if (!(input.get())) { |
| 89 LOG(ERROR) << "could not open input"; |
| 90 return 1; |
| 91 } |
| 92 |
| 93 // Open output file. |
| 94 ScopedFILE output(file_util::OpenFile(out_path.c_str(), "wb")); |
| 95 if (!(output.get())) { |
| 96 LOG(ERROR) << "could not open output"; |
| 97 return 1; |
| 98 } |
| 99 |
| 100 // Read in header. |
| 101 WavHeader wav; |
| 102 if (fread(&wav, sizeof(wav), 1, input.get()) < 1) { |
| 103 LOG(ERROR) << "could not read WAV header"; |
| 104 return 1; |
| 105 } |
| 106 |
| 107 // Instantiate dummy class and callback to feed data to |ola|. |
| 108 Dummy guy(input.get(), &ola); |
| 109 AudioRendererAlgorithmOLA::RequestReadCallback* cb = |
| 110 NewCallback(&guy, &Dummy::ReadDataForAlg); |
| 111 ola.Initialize(wav.channels, |
| 112 wav.bit_rate, |
| 113 static_cast<float>(playback_rate), |
| 114 cb); |
| 115 |
| 116 // Print out input format. |
| 117 std::cout << in_path << "\n" |
| 118 << "Channels: " << wav.channels << "\n" |
| 119 << "Sample Rate: " << wav.sample_rate << "\n" |
| 120 << "Bit Rate: " << wav.bit_rate << "\n" |
| 121 << "\n" |
| 122 << "Scaling audio by " << playback_rate << "x..." << std::endl; |
| 123 |
| 124 // Write the header back out again. |
| 125 if (fwrite(&wav, sizeof(wav), 1, output.get()) < 1) { |
| 126 LOG(ERROR) << "could not write WAV header"; |
| 127 return 1; |
| 128 } |
| 129 |
| 130 // Create buffer to be filled by |ola|. |
| 131 scoped_refptr<DataBuffer> buffer(new DataBuffer()); |
| 132 uint8* buf = buffer->GetWritableData(kDefaultWindowSize); |
| 133 |
| 134 // Keep track of bytes written to disk and bytes copied to |b|. |
| 135 size_t bytes_written = 0; |
| 136 size_t bytes; |
| 137 while ((bytes = ola.FillBuffer(buffer.get())) > 0) { |
| 138 if (fwrite(buf, 1, bytes, output.get()) != bytes) { |
| 139 LOG(ERROR) << "could not write data after " << bytes_written; |
| 140 } else { |
| 141 bytes_written += bytes; |
| 142 } |
| 143 } |
| 144 |
| 145 // Seek back to the beginning of our output file and update the header. |
| 146 wav.chunk_size = 36 + bytes_written; |
| 147 wav.subchunk1_size = 16; |
| 148 wav.subchunk2_size = bytes_written; |
| 149 fseek(output.get(), 0, SEEK_SET); |
| 150 fwrite(&wav, sizeof(wav), 1, output.get()); |
| 151 |
| 152 return 0; |
| 153 } |
OLD | NEW |