OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 virtual size_t Read(void* buf, size_t num_bytes) { | 32 virtual size_t Read(void* buf, size_t num_bytes) { |
33 return fread(buf, 1, num_bytes, file_); | 33 return fread(buf, 1, num_bytes, file_); |
34 } | 34 } |
35 | 35 |
36 private: | 36 private: |
37 FILE* file_; | 37 FILE* file_; |
38 }; | 38 }; |
39 | 39 |
40 WavReader::WavReader(const std::string& filename) | 40 WavReader::WavReader(const std::string& filename) |
41 : file_handle_(fopen(filename.c_str(), "rb")) { | 41 : file_handle_(fopen(filename.c_str(), "rb")) { |
42 CHECK(file_handle_ && "Could not open wav file for reading."); | 42 RTC_CHECK(file_handle_ && "Could not open wav file for reading."); |
43 | 43 |
44 ReadableWavFile readable(file_handle_); | 44 ReadableWavFile readable(file_handle_); |
45 WavFormat format; | 45 WavFormat format; |
46 int bytes_per_sample; | 46 int bytes_per_sample; |
47 CHECK(ReadWavHeader(&readable, &num_channels_, &sample_rate_, &format, | 47 RTC_CHECK(ReadWavHeader(&readable, &num_channels_, &sample_rate_, &format, |
48 &bytes_per_sample, &num_samples_)); | 48 &bytes_per_sample, &num_samples_)); |
49 num_samples_remaining_ = num_samples_; | 49 num_samples_remaining_ = num_samples_; |
50 CHECK_EQ(kWavFormat, format); | 50 RTC_CHECK_EQ(kWavFormat, format); |
51 CHECK_EQ(kBytesPerSample, bytes_per_sample); | 51 RTC_CHECK_EQ(kBytesPerSample, bytes_per_sample); |
52 } | 52 } |
53 | 53 |
54 WavReader::~WavReader() { | 54 WavReader::~WavReader() { |
55 Close(); | 55 Close(); |
56 } | 56 } |
57 | 57 |
58 size_t WavReader::ReadSamples(size_t num_samples, int16_t* samples) { | 58 size_t WavReader::ReadSamples(size_t num_samples, int16_t* samples) { |
59 #ifndef WEBRTC_ARCH_LITTLE_ENDIAN | 59 #ifndef WEBRTC_ARCH_LITTLE_ENDIAN |
60 #error "Need to convert samples to big-endian when reading from WAV file" | 60 #error "Need to convert samples to big-endian when reading from WAV file" |
61 #endif | 61 #endif |
62 // There could be metadata after the audio; ensure we don't read it. | 62 // There could be metadata after the audio; ensure we don't read it. |
63 num_samples = std::min(rtc::checked_cast<uint32_t>(num_samples), | 63 num_samples = std::min(rtc::checked_cast<uint32_t>(num_samples), |
64 num_samples_remaining_); | 64 num_samples_remaining_); |
65 const size_t read = | 65 const size_t read = |
66 fread(samples, sizeof(*samples), num_samples, file_handle_); | 66 fread(samples, sizeof(*samples), num_samples, file_handle_); |
67 // If we didn't read what was requested, ensure we've reached the EOF. | 67 // If we didn't read what was requested, ensure we've reached the EOF. |
68 CHECK(read == num_samples || feof(file_handle_)); | 68 RTC_CHECK(read == num_samples || feof(file_handle_)); |
69 CHECK_LE(read, num_samples_remaining_); | 69 RTC_CHECK_LE(read, num_samples_remaining_); |
70 num_samples_remaining_ -= rtc::checked_cast<uint32_t>(read); | 70 num_samples_remaining_ -= rtc::checked_cast<uint32_t>(read); |
71 return read; | 71 return read; |
72 } | 72 } |
73 | 73 |
74 size_t WavReader::ReadSamples(size_t num_samples, float* samples) { | 74 size_t WavReader::ReadSamples(size_t num_samples, float* samples) { |
75 static const size_t kChunksize = 4096 / sizeof(uint16_t); | 75 static const size_t kChunksize = 4096 / sizeof(uint16_t); |
76 size_t read = 0; | 76 size_t read = 0; |
77 for (size_t i = 0; i < num_samples; i += kChunksize) { | 77 for (size_t i = 0; i < num_samples; i += kChunksize) { |
78 int16_t isamples[kChunksize]; | 78 int16_t isamples[kChunksize]; |
79 size_t chunk = std::min(kChunksize, num_samples - i); | 79 size_t chunk = std::min(kChunksize, num_samples - i); |
80 chunk = ReadSamples(chunk, isamples); | 80 chunk = ReadSamples(chunk, isamples); |
81 for (size_t j = 0; j < chunk; ++j) | 81 for (size_t j = 0; j < chunk; ++j) |
82 samples[i + j] = isamples[j]; | 82 samples[i + j] = isamples[j]; |
83 read += chunk; | 83 read += chunk; |
84 } | 84 } |
85 return read; | 85 return read; |
86 } | 86 } |
87 | 87 |
88 void WavReader::Close() { | 88 void WavReader::Close() { |
89 CHECK_EQ(0, fclose(file_handle_)); | 89 RTC_CHECK_EQ(0, fclose(file_handle_)); |
90 file_handle_ = NULL; | 90 file_handle_ = NULL; |
91 } | 91 } |
92 | 92 |
93 WavWriter::WavWriter(const std::string& filename, int sample_rate, | 93 WavWriter::WavWriter(const std::string& filename, int sample_rate, |
94 int num_channels) | 94 int num_channels) |
95 : sample_rate_(sample_rate), | 95 : sample_rate_(sample_rate), |
96 num_channels_(num_channels), | 96 num_channels_(num_channels), |
97 num_samples_(0), | 97 num_samples_(0), |
98 file_handle_(fopen(filename.c_str(), "wb")) { | 98 file_handle_(fopen(filename.c_str(), "wb")) { |
99 CHECK(file_handle_ && "Could not open wav file for writing."); | 99 RTC_CHECK(file_handle_ && "Could not open wav file for writing."); |
100 CHECK(CheckWavParameters(num_channels_, | 100 RTC_CHECK(CheckWavParameters(num_channels_, sample_rate_, kWavFormat, |
101 sample_rate_, | 101 kBytesPerSample, num_samples_)); |
102 kWavFormat, | |
103 kBytesPerSample, | |
104 num_samples_)); | |
105 | 102 |
106 // Write a blank placeholder header, since we need to know the total number | 103 // Write a blank placeholder header, since we need to know the total number |
107 // of samples before we can fill in the real data. | 104 // of samples before we can fill in the real data. |
108 static const uint8_t blank_header[kWavHeaderSize] = {0}; | 105 static const uint8_t blank_header[kWavHeaderSize] = {0}; |
109 CHECK_EQ(1u, fwrite(blank_header, kWavHeaderSize, 1, file_handle_)); | 106 RTC_CHECK_EQ(1u, fwrite(blank_header, kWavHeaderSize, 1, file_handle_)); |
110 } | 107 } |
111 | 108 |
112 WavWriter::~WavWriter() { | 109 WavWriter::~WavWriter() { |
113 Close(); | 110 Close(); |
114 } | 111 } |
115 | 112 |
116 void WavWriter::WriteSamples(const int16_t* samples, size_t num_samples) { | 113 void WavWriter::WriteSamples(const int16_t* samples, size_t num_samples) { |
117 #ifndef WEBRTC_ARCH_LITTLE_ENDIAN | 114 #ifndef WEBRTC_ARCH_LITTLE_ENDIAN |
118 #error "Need to convert samples to little-endian when writing to WAV file" | 115 #error "Need to convert samples to little-endian when writing to WAV file" |
119 #endif | 116 #endif |
120 const size_t written = | 117 const size_t written = |
121 fwrite(samples, sizeof(*samples), num_samples, file_handle_); | 118 fwrite(samples, sizeof(*samples), num_samples, file_handle_); |
122 CHECK_EQ(num_samples, written); | 119 RTC_CHECK_EQ(num_samples, written); |
123 num_samples_ += static_cast<uint32_t>(written); | 120 num_samples_ += static_cast<uint32_t>(written); |
124 CHECK(written <= std::numeric_limits<uint32_t>::max() || | 121 RTC_CHECK(written <= std::numeric_limits<uint32_t>::max() || |
125 num_samples_ >= written); // detect uint32_t overflow | 122 num_samples_ >= written); // detect uint32_t overflow |
126 } | 123 } |
127 | 124 |
128 void WavWriter::WriteSamples(const float* samples, size_t num_samples) { | 125 void WavWriter::WriteSamples(const float* samples, size_t num_samples) { |
129 static const size_t kChunksize = 4096 / sizeof(uint16_t); | 126 static const size_t kChunksize = 4096 / sizeof(uint16_t); |
130 for (size_t i = 0; i < num_samples; i += kChunksize) { | 127 for (size_t i = 0; i < num_samples; i += kChunksize) { |
131 int16_t isamples[kChunksize]; | 128 int16_t isamples[kChunksize]; |
132 const size_t chunk = std::min(kChunksize, num_samples - i); | 129 const size_t chunk = std::min(kChunksize, num_samples - i); |
133 FloatS16ToS16(samples + i, chunk, isamples); | 130 FloatS16ToS16(samples + i, chunk, isamples); |
134 WriteSamples(isamples, chunk); | 131 WriteSamples(isamples, chunk); |
135 } | 132 } |
136 } | 133 } |
137 | 134 |
138 void WavWriter::Close() { | 135 void WavWriter::Close() { |
139 CHECK_EQ(0, fseek(file_handle_, 0, SEEK_SET)); | 136 RTC_CHECK_EQ(0, fseek(file_handle_, 0, SEEK_SET)); |
140 uint8_t header[kWavHeaderSize]; | 137 uint8_t header[kWavHeaderSize]; |
141 WriteWavHeader(header, num_channels_, sample_rate_, kWavFormat, | 138 WriteWavHeader(header, num_channels_, sample_rate_, kWavFormat, |
142 kBytesPerSample, num_samples_); | 139 kBytesPerSample, num_samples_); |
143 CHECK_EQ(1u, fwrite(header, kWavHeaderSize, 1, file_handle_)); | 140 RTC_CHECK_EQ(1u, fwrite(header, kWavHeaderSize, 1, file_handle_)); |
144 CHECK_EQ(0, fclose(file_handle_)); | 141 RTC_CHECK_EQ(0, fclose(file_handle_)); |
145 file_handle_ = NULL; | 142 file_handle_ = NULL; |
146 } | 143 } |
147 | 144 |
148 } // namespace webrtc | 145 } // namespace webrtc |
149 | 146 |
150 rtc_WavWriter* rtc_WavOpen(const char* filename, | 147 rtc_WavWriter* rtc_WavOpen(const char* filename, |
151 int sample_rate, | 148 int sample_rate, |
152 int num_channels) { | 149 int num_channels) { |
153 return reinterpret_cast<rtc_WavWriter*>( | 150 return reinterpret_cast<rtc_WavWriter*>( |
154 new webrtc::WavWriter(filename, sample_rate, num_channels)); | 151 new webrtc::WavWriter(filename, sample_rate, num_channels)); |
(...skipping 13 matching lines...) Expand all Loading... |
168 return reinterpret_cast<const webrtc::WavWriter*>(wf)->sample_rate(); | 165 return reinterpret_cast<const webrtc::WavWriter*>(wf)->sample_rate(); |
169 } | 166 } |
170 | 167 |
171 int rtc_WavNumChannels(const rtc_WavWriter* wf) { | 168 int rtc_WavNumChannels(const rtc_WavWriter* wf) { |
172 return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_channels(); | 169 return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_channels(); |
173 } | 170 } |
174 | 171 |
175 uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf) { | 172 uint32_t rtc_WavNumSamples(const rtc_WavWriter* wf) { |
176 return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_samples(); | 173 return reinterpret_cast<const webrtc::WavWriter*>(wf)->num_samples(); |
177 } | 174 } |
OLD | NEW |