OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 |
11 #include "webrtc/voice_engine/file_recorder.h" | 11 #include "webrtc/voice_engine/file_recorder.h" |
12 | 12 |
13 #include <list> | 13 #include <list> |
14 | 14 |
15 #include "webrtc/base/platform_thread.h" | 15 #include "webrtc/base/platform_thread.h" |
16 #include "webrtc/common_audio/resampler/include/resampler.h" | 16 #include "webrtc/common_audio/resampler/include/resampler.h" |
17 #include "webrtc/common_types.h" | 17 #include "webrtc/common_types.h" |
18 #include "webrtc/modules/include/module_common_types.h" | 18 #include "webrtc/modules/include/module_common_types.h" |
19 #include "webrtc/modules/media_file/media_file.h" | 19 #include "webrtc/modules/media_file/media_file.h" |
20 #include "webrtc/modules/media_file/media_file_defines.h" | 20 #include "webrtc/modules/media_file/media_file_defines.h" |
21 #include "webrtc/system_wrappers/include/event_wrapper.h" | 21 #include "webrtc/system_wrappers/include/event_wrapper.h" |
22 #include "webrtc/system_wrappers/include/logging.h" | |
23 #include "webrtc/typedefs.h" | 22 #include "webrtc/typedefs.h" |
24 #include "webrtc/voice_engine/coder.h" | 23 #include "webrtc/voice_engine/coder.h" |
25 | 24 |
26 namespace webrtc { | 25 namespace webrtc { |
27 | 26 |
28 namespace { | 27 namespace { |
29 | 28 |
30 // The largest decoded frame size in samples (60ms with 32kHz sample rate). | 29 // The largest decoded frame size in samples (60ms with 32kHz sample rate). |
31 enum { MAX_AUDIO_BUFFER_IN_SAMPLES = 60 * 32 }; | 30 enum { MAX_AUDIO_BUFFER_IN_SAMPLES = 60 * 32 }; |
32 enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES * 2 }; | 31 enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES * 2 }; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 97 } |
99 codec_info_ = codecInst; | 98 codec_info_ = codecInst; |
100 int32_t retVal = 0; | 99 int32_t retVal = 0; |
101 retVal = _moduleFile->StartRecordingAudioFile(fileName, _fileFormat, | 100 retVal = _moduleFile->StartRecordingAudioFile(fileName, _fileFormat, |
102 codecInst, notificationTimeMs); | 101 codecInst, notificationTimeMs); |
103 | 102 |
104 if (retVal == 0) { | 103 if (retVal == 0) { |
105 retVal = SetUpAudioEncoder(); | 104 retVal = SetUpAudioEncoder(); |
106 } | 105 } |
107 if (retVal != 0) { | 106 if (retVal != 0) { |
108 LOG(LS_WARNING) << "Failed to initialize file " << fileName | |
109 << " for recording."; | |
110 | 107 |
111 if (IsRecording()) { | 108 if (IsRecording()) { |
112 StopRecording(); | 109 StopRecording(); |
113 } | 110 } |
114 } | 111 } |
115 return retVal; | 112 return retVal; |
116 } | 113 } |
117 | 114 |
118 int32_t FileRecorderImpl::StartRecordingAudioFile(OutStream* destStream, | 115 int32_t FileRecorderImpl::StartRecordingAudioFile(OutStream* destStream, |
119 const CodecInst& codecInst, | 116 const CodecInst& codecInst, |
120 uint32_t notificationTimeMs) { | 117 uint32_t notificationTimeMs) { |
121 codec_info_ = codecInst; | 118 codec_info_ = codecInst; |
122 int32_t retVal = _moduleFile->StartRecordingAudioStream( | 119 int32_t retVal = _moduleFile->StartRecordingAudioStream( |
123 *destStream, _fileFormat, codecInst, notificationTimeMs); | 120 *destStream, _fileFormat, codecInst, notificationTimeMs); |
124 | 121 |
125 if (retVal == 0) { | 122 if (retVal == 0) { |
126 retVal = SetUpAudioEncoder(); | 123 retVal = SetUpAudioEncoder(); |
127 } | 124 } |
128 if (retVal != 0) { | 125 if (retVal != 0) { |
129 LOG(LS_WARNING) << "Failed to initialize outStream for recording."; | |
130 | 126 |
131 if (IsRecording()) { | 127 if (IsRecording()) { |
132 StopRecording(); | 128 StopRecording(); |
133 } | 129 } |
134 } | 130 } |
135 return retVal; | 131 return retVal; |
136 } | 132 } |
137 | 133 |
138 int32_t FileRecorderImpl::StopRecording() { | 134 int32_t FileRecorderImpl::StopRecording() { |
139 memset(&codec_info_, 0, sizeof(CodecInst)); | 135 memset(&codec_info_, 0, sizeof(CodecInst)); |
140 return _moduleFile->StopRecording(); | 136 return _moduleFile->StopRecording(); |
141 } | 137 } |
142 | 138 |
143 bool FileRecorderImpl::IsRecording() const { | 139 bool FileRecorderImpl::IsRecording() const { |
144 return _moduleFile->IsRecording(); | 140 return _moduleFile->IsRecording(); |
145 } | 141 } |
146 | 142 |
147 int32_t FileRecorderImpl::RecordAudioToFile( | 143 int32_t FileRecorderImpl::RecordAudioToFile( |
148 const AudioFrame& incomingAudioFrame) { | 144 const AudioFrame& incomingAudioFrame) { |
149 if (codec_info_.plfreq == 0) { | 145 if (codec_info_.plfreq == 0) { |
150 LOG(LS_WARNING) << "RecordAudioToFile() recording audio is not " | |
151 << "turned on."; | |
152 return -1; | 146 return -1; |
153 } | 147 } |
154 AudioFrame tempAudioFrame; | 148 AudioFrame tempAudioFrame; |
155 tempAudioFrame.samples_per_channel_ = 0; | 149 tempAudioFrame.samples_per_channel_ = 0; |
156 if (incomingAudioFrame.num_channels_ == 2 && !_moduleFile->IsStereo()) { | 150 if (incomingAudioFrame.num_channels_ == 2 && !_moduleFile->IsStereo()) { |
157 // Recording mono but incoming audio is (interleaved) stereo. | 151 // Recording mono but incoming audio is (interleaved) stereo. |
158 tempAudioFrame.num_channels_ = 1; | 152 tempAudioFrame.num_channels_ = 1; |
159 tempAudioFrame.sample_rate_hz_ = incomingAudioFrame.sample_rate_hz_; | 153 tempAudioFrame.sample_rate_hz_ = incomingAudioFrame.sample_rate_hz_; |
160 tempAudioFrame.samples_per_channel_ = | 154 tempAudioFrame.samples_per_channel_ = |
161 incomingAudioFrame.samples_per_channel_; | 155 incomingAudioFrame.samples_per_channel_; |
(...skipping 26 matching lines...) Expand all Loading... |
188 // Encode the audio data before writing to file. Don't encode if the codec | 182 // Encode the audio data before writing to file. Don't encode if the codec |
189 // is PCM. | 183 // is PCM. |
190 // NOTE: stereo recording is only supported for WAV files. | 184 // NOTE: stereo recording is only supported for WAV files. |
191 // TODO(hellner): WAV expect PCM in little endian byte order. Not | 185 // TODO(hellner): WAV expect PCM in little endian byte order. Not |
192 // "encoding" with PCM coder should be a problem for big endian systems. | 186 // "encoding" with PCM coder should be a problem for big endian systems. |
193 size_t encodedLenInBytes = 0; | 187 size_t encodedLenInBytes = 0; |
194 if (_fileFormat == kFileFormatPreencodedFile || | 188 if (_fileFormat == kFileFormatPreencodedFile || |
195 STR_CASE_CMP(codec_info_.plname, "L16") != 0) { | 189 STR_CASE_CMP(codec_info_.plname, "L16") != 0) { |
196 if (_audioEncoder.Encode(*ptrAudioFrame, _audioBuffer, | 190 if (_audioEncoder.Encode(*ptrAudioFrame, _audioBuffer, |
197 &encodedLenInBytes) == -1) { | 191 &encodedLenInBytes) == -1) { |
198 LOG(LS_WARNING) << "RecordAudioToFile() codec " << codec_info_.plname | |
199 << " not supported or failed to encode stream."; | |
200 return -1; | 192 return -1; |
201 } | 193 } |
202 } else { | 194 } else { |
203 size_t outLen = 0; | 195 size_t outLen = 0; |
204 _audioResampler.ResetIfNeeded(ptrAudioFrame->sample_rate_hz_, | 196 _audioResampler.ResetIfNeeded(ptrAudioFrame->sample_rate_hz_, |
205 codec_info_.plfreq, | 197 codec_info_.plfreq, |
206 ptrAudioFrame->num_channels_); | 198 ptrAudioFrame->num_channels_); |
207 _audioResampler.Push( | 199 _audioResampler.Push( |
208 ptrAudioFrame->data_, | 200 ptrAudioFrame->data_, |
209 ptrAudioFrame->samples_per_channel_ * ptrAudioFrame->num_channels_, | 201 ptrAudioFrame->samples_per_channel_ * ptrAudioFrame->num_channels_, |
(...skipping 10 matching lines...) Expand all Loading... |
220 return -1; | 212 return -1; |
221 } | 213 } |
222 } | 214 } |
223 return 0; | 215 return 0; |
224 } | 216 } |
225 | 217 |
226 int32_t FileRecorderImpl::SetUpAudioEncoder() { | 218 int32_t FileRecorderImpl::SetUpAudioEncoder() { |
227 if (_fileFormat == kFileFormatPreencodedFile || | 219 if (_fileFormat == kFileFormatPreencodedFile || |
228 STR_CASE_CMP(codec_info_.plname, "L16") != 0) { | 220 STR_CASE_CMP(codec_info_.plname, "L16") != 0) { |
229 if (_audioEncoder.SetEncodeCodec(codec_info_) == -1) { | 221 if (_audioEncoder.SetEncodeCodec(codec_info_) == -1) { |
230 LOG(LS_ERROR) << "SetUpAudioEncoder() codec " << codec_info_.plname | |
231 << " not supported."; | |
232 return -1; | 222 return -1; |
233 } | 223 } |
234 } | 224 } |
235 return 0; | 225 return 0; |
236 } | 226 } |
237 | 227 |
238 int32_t FileRecorderImpl::codec_info(CodecInst* codecInst) const { | 228 int32_t FileRecorderImpl::codec_info(CodecInst* codecInst) const { |
239 if (codec_info_.plfreq == 0) { | 229 if (codec_info_.plfreq == 0) { |
240 return -1; | 230 return -1; |
241 } | 231 } |
242 *codecInst = codec_info_; | 232 *codecInst = codec_info_; |
243 return 0; | 233 return 0; |
244 } | 234 } |
245 | 235 |
246 int32_t FileRecorderImpl::WriteEncodedAudioData(const int8_t* audioBuffer, | 236 int32_t FileRecorderImpl::WriteEncodedAudioData(const int8_t* audioBuffer, |
247 size_t bufferLength) { | 237 size_t bufferLength) { |
248 return _moduleFile->IncomingAudioData(audioBuffer, bufferLength); | 238 return _moduleFile->IncomingAudioData(audioBuffer, bufferLength); |
249 } | 239 } |
250 | 240 |
251 } // namespace | 241 } // namespace |
252 | 242 |
253 std::unique_ptr<FileRecorder> FileRecorder::CreateFileRecorder( | 243 std::unique_ptr<FileRecorder> FileRecorder::CreateFileRecorder( |
254 uint32_t instanceID, | 244 uint32_t instanceID, |
255 FileFormats fileFormat) { | 245 FileFormats fileFormat) { |
256 return std::unique_ptr<FileRecorder>( | 246 return std::unique_ptr<FileRecorder>( |
257 new FileRecorderImpl(instanceID, fileFormat)); | 247 new FileRecorderImpl(instanceID, fileFormat)); |
258 } | 248 } |
259 | 249 |
260 } // namespace webrtc | 250 } // namespace webrtc |
OLD | NEW |