Delete unused recording functionality from MediaFile.
Bug: None Change-Id: I84ba7abc1a5eeab8ce01b8aa00dfe4efa4d9b2b6 Reviewed-on: https://webrtc-review.googlesource.com/27381 Reviewed-by: Magnus Flodman <mflodman@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20954}
This commit is contained in:
parent
319a675318
commit
1bec1b497c
@ -104,70 +104,10 @@ public:
|
||||
virtual int32_t PlayoutPositionMs(
|
||||
uint32_t& durationMs) const = 0;
|
||||
|
||||
// Write one audio frame, i.e. the bufferLength first bytes of audioBuffer,
|
||||
// to file. The audio frame size is determined by the codecInst.pacsize
|
||||
// parameter of the last sucessfull StartRecordingAudioFile(..) call.
|
||||
// Note: bufferLength must be exactly one frame.
|
||||
virtual int32_t IncomingAudioData(
|
||||
const int8_t* audioBuffer,
|
||||
const size_t bufferLength) = 0;
|
||||
|
||||
// Open/creates file specified by fileName for writing (relative path is
|
||||
// allowed). FileCallback::RecordNotification(..) will be called after
|
||||
// notificationTimeMs of audio data has been recorded if
|
||||
// notificationTimeMs is greater than zero.
|
||||
// format specifies the type of file that should be created/opened.
|
||||
// codecInst specifies the encoding of the audio data. maxSizeBytes
|
||||
// specifies the number of bytes allowed to be written to file if it is
|
||||
// greater than zero.
|
||||
// Note: codecInst.channels should be set to 2 for stereo (and 1 for
|
||||
// mono). Stereo is only supported for WAV files.
|
||||
virtual int32_t StartRecordingAudioFile(
|
||||
const char* fileName,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs = 0,
|
||||
const uint32_t maxSizeBytes = 0) = 0;
|
||||
|
||||
// Prepare for recording audio to stream.
|
||||
// FileCallback::RecordNotification(..) will be called after
|
||||
// notificationTimeMs of audio data has been recorded if
|
||||
// notificationTimeMs is greater than zero.
|
||||
// format specifies the type of file that stream should correspond to.
|
||||
// codecInst specifies the encoding of the audio data.
|
||||
// Note: codecInst.channels should be set to 2 for stereo (and 1 for
|
||||
// mono). Stereo is only supported for WAV files.
|
||||
virtual int32_t StartRecordingAudioStream(
|
||||
OutStream& stream,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs = 0) = 0;
|
||||
|
||||
// Stop recording to file or stream.
|
||||
virtual int32_t StopRecording() = 0;
|
||||
|
||||
// Return true if recording.
|
||||
virtual bool IsRecording() = 0;
|
||||
|
||||
// Set durationMs to the number of ms that has been recorded to file.
|
||||
virtual int32_t RecordDurationMs(uint32_t& durationMs) = 0;
|
||||
|
||||
// Return true if recording or playing is stereo.
|
||||
virtual bool IsStereo() = 0;
|
||||
|
||||
// Register callback to receive media file related notifications. Disables
|
||||
// callbacks if callback is NULL.
|
||||
virtual int32_t SetModuleFileCallback(FileCallback* callback) = 0;
|
||||
|
||||
// Set durationMs to the size of the file (in ms) specified by fileName.
|
||||
// format specifies the type of file fileName refers to. freqInHz specifies
|
||||
// the sampling frequency of the file.
|
||||
virtual int32_t FileDurationMs(
|
||||
const char* fileName,
|
||||
uint32_t& durationMs,
|
||||
const FileFormats format,
|
||||
const uint32_t freqInHz = 16000) = 0;
|
||||
|
||||
// Update codecInst according to the current audio codec being used for
|
||||
// reading or writing.
|
||||
virtual int32_t codec_info(CodecInst& codecInst) const = 0;
|
||||
|
||||
@ -31,11 +31,9 @@ MediaFileImpl::MediaFileImpl(const int32_t id)
|
||||
_ptrInStream(NULL),
|
||||
_ptrOutStream(NULL),
|
||||
_fileFormat((FileFormats)-1),
|
||||
_recordDurationMs(0),
|
||||
_playoutPositionMs(0),
|
||||
_notificationMs(0),
|
||||
_playingActive(false),
|
||||
_recordingActive(false),
|
||||
_isStereo(false),
|
||||
_openFile(false),
|
||||
_fileName(),
|
||||
@ -55,10 +53,6 @@ MediaFileImpl::~MediaFileImpl() {
|
||||
StopPlaying();
|
||||
}
|
||||
|
||||
if (_recordingActive) {
|
||||
StopRecording();
|
||||
}
|
||||
|
||||
delete _ptrFileUtilityObj;
|
||||
|
||||
if (_openFile) {
|
||||
@ -333,9 +327,9 @@ int32_t MediaFileImpl::StartPlayingStream(InStream& stream,
|
||||
}
|
||||
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (_playingActive || _recordingActive) {
|
||||
if (_playingActive) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "StartPlaying called, but already playing or recording file "
|
||||
<< "StartPlaying called, but already playing file "
|
||||
<< ((_fileName[0] == '\0') ? "(name not set)" : _fileName);
|
||||
return -1;
|
||||
}
|
||||
@ -465,322 +459,6 @@ bool MediaFileImpl::IsPlaying() {
|
||||
return _playingActive;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::IncomingAudioData(const int8_t* buffer,
|
||||
const size_t bufferLengthInBytes) {
|
||||
RTC_LOG(LS_INFO) << "MediaFile::IncomingData(buffer= "
|
||||
<< static_cast<const void*>(buffer)
|
||||
<< ", bufLen= " << bufferLengthInBytes << ")";
|
||||
|
||||
if (buffer == NULL || bufferLengthInBytes == 0) {
|
||||
RTC_LOG(LS_ERROR) << "Buffer pointer or length is NULL!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool recordingEnded = false;
|
||||
uint32_t callbackNotifyMs = 0;
|
||||
{
|
||||
rtc::CritScope lock(&_crit);
|
||||
|
||||
if (!_recordingActive) {
|
||||
RTC_LOG(LS_WARNING) << "Not currently recording!";
|
||||
return -1;
|
||||
}
|
||||
if (_ptrOutStream == NULL) {
|
||||
RTC_LOG(LS_ERROR) << "Recording is active, but output stream is NULL!";
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t bytesWritten = 0;
|
||||
uint32_t samplesWritten = codec_info_.pacsize;
|
||||
if (_ptrFileUtilityObj) {
|
||||
switch (_fileFormat) {
|
||||
case kFileFormatPcm8kHzFile:
|
||||
case kFileFormatPcm16kHzFile:
|
||||
case kFileFormatPcm32kHzFile:
|
||||
case kFileFormatPcm48kHzFile:
|
||||
bytesWritten = _ptrFileUtilityObj->WritePCMData(
|
||||
*_ptrOutStream, buffer, bufferLengthInBytes);
|
||||
|
||||
// Sample size is 2 bytes.
|
||||
if (bytesWritten > 0) {
|
||||
samplesWritten = bytesWritten / sizeof(int16_t);
|
||||
}
|
||||
break;
|
||||
case kFileFormatCompressedFile:
|
||||
bytesWritten = _ptrFileUtilityObj->WriteCompressedData(
|
||||
*_ptrOutStream, buffer, bufferLengthInBytes);
|
||||
break;
|
||||
case kFileFormatWavFile:
|
||||
bytesWritten = _ptrFileUtilityObj->WriteWavData(
|
||||
*_ptrOutStream, buffer, bufferLengthInBytes);
|
||||
if (bytesWritten > 0 &&
|
||||
STR_NCASE_CMP(codec_info_.plname, "L16", 4) == 0) {
|
||||
// Sample size is 2 bytes.
|
||||
samplesWritten = bytesWritten / sizeof(int16_t);
|
||||
}
|
||||
break;
|
||||
case kFileFormatPreencodedFile:
|
||||
bytesWritten = _ptrFileUtilityObj->WritePreEncodedData(
|
||||
*_ptrOutStream, buffer, bufferLengthInBytes);
|
||||
break;
|
||||
default:
|
||||
RTC_LOG(LS_ERROR) << "Invalid file format: " << _fileFormat;
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// TODO (hellner): quick look at the code makes me think that this
|
||||
// code is never executed. Remove?
|
||||
if (_ptrOutStream) {
|
||||
if (_ptrOutStream->Write(buffer, bufferLengthInBytes)) {
|
||||
bytesWritten = static_cast<int32_t>(bufferLengthInBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_recordDurationMs += samplesWritten / (codec_info_.plfreq / 1000);
|
||||
|
||||
// Check if it's time for RecordNotification(..).
|
||||
if (_notificationMs) {
|
||||
if (_recordDurationMs >= _notificationMs) {
|
||||
_notificationMs = 0;
|
||||
callbackNotifyMs = _recordDurationMs;
|
||||
}
|
||||
}
|
||||
if (bytesWritten < (int32_t)bufferLengthInBytes) {
|
||||
RTC_LOG(LS_WARNING) << "Failed to write all requested bytes!";
|
||||
StopRecording();
|
||||
recordingEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Only _callbackCrit may and should be taken when making callbacks.
|
||||
rtc::CritScope lock(&_callbackCrit);
|
||||
if (_ptrCallback) {
|
||||
if (callbackNotifyMs) {
|
||||
_ptrCallback->RecordNotification(_id, callbackNotifyMs);
|
||||
}
|
||||
if (recordingEnded) {
|
||||
_ptrCallback->RecordFileEnded(_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::StartRecordingAudioFile(
|
||||
const char* fileName,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs,
|
||||
const uint32_t maxSizeBytes) {
|
||||
if (!ValidFileName(fileName)) {
|
||||
return -1;
|
||||
}
|
||||
if (!ValidFileFormat(format, &codecInst)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FileWrapper* outputStream = FileWrapper::Create();
|
||||
if (outputStream == NULL) {
|
||||
RTC_LOG(LS_INFO) << "Failed to allocate memory for output stream";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!outputStream->OpenFile(fileName, false)) {
|
||||
delete outputStream;
|
||||
RTC_LOG(LS_ERROR) << "Could not open output file '" << fileName
|
||||
<< "' for writing!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (maxSizeBytes) {
|
||||
outputStream->SetMaxFileSize(maxSizeBytes);
|
||||
}
|
||||
|
||||
if (StartRecordingAudioStream(*outputStream, format, codecInst,
|
||||
notificationTimeMs) == -1) {
|
||||
outputStream->CloseFile();
|
||||
delete outputStream;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc::CritScope lock(&_crit);
|
||||
_openFile = true;
|
||||
strncpy(_fileName, fileName, sizeof(_fileName));
|
||||
_fileName[sizeof(_fileName) - 1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::StartRecordingAudioStream(
|
||||
OutStream& stream,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs) {
|
||||
// Check codec info
|
||||
if (!ValidFileFormat(format, &codecInst)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (_recordingActive || _playingActive) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "StartRecording called, but already recording or playing file "
|
||||
<< _fileName << "!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_ptrFileUtilityObj != NULL) {
|
||||
RTC_LOG(LS_ERROR)
|
||||
<< "StartRecording called, but fileUtilityObj already exists!";
|
||||
StopRecording();
|
||||
return -1;
|
||||
}
|
||||
|
||||
_ptrFileUtilityObj = new ModuleFileUtility();
|
||||
if (_ptrFileUtilityObj == NULL) {
|
||||
RTC_LOG(LS_INFO) << "Cannot allocate fileUtilityObj!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
CodecInst tmpAudioCodec;
|
||||
memcpy(&tmpAudioCodec, &codecInst, sizeof(CodecInst));
|
||||
switch (format) {
|
||||
case kFileFormatWavFile: {
|
||||
if (_ptrFileUtilityObj->InitWavWriting(stream, codecInst) == -1) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize WAV file!";
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
return -1;
|
||||
}
|
||||
_fileFormat = kFileFormatWavFile;
|
||||
break;
|
||||
}
|
||||
case kFileFormatCompressedFile: {
|
||||
// Write compression codec name at beginning of file
|
||||
if (_ptrFileUtilityObj->InitCompressedWriting(stream, codecInst) == -1) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize Compressed file!";
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
return -1;
|
||||
}
|
||||
_fileFormat = kFileFormatCompressedFile;
|
||||
break;
|
||||
}
|
||||
case kFileFormatPcm8kHzFile:
|
||||
case kFileFormatPcm16kHzFile:
|
||||
case kFileFormatPcm32kHzFile:
|
||||
case kFileFormatPcm48kHzFile: {
|
||||
if (!ValidFrequency(codecInst.plfreq) ||
|
||||
_ptrFileUtilityObj->InitPCMWriting(stream, codecInst.plfreq) == -1) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize PCM file!";
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
return -1;
|
||||
}
|
||||
_fileFormat = format;
|
||||
break;
|
||||
}
|
||||
case kFileFormatPreencodedFile: {
|
||||
if (_ptrFileUtilityObj->InitPreEncodedWriting(stream, codecInst) == -1) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize Pre-Encoded file!";
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_fileFormat = kFileFormatPreencodedFile;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
RTC_LOG(LS_ERROR) << "Invalid file format " << format << " specified!";
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_isStereo = (tmpAudioCodec.channels == 2);
|
||||
if (_isStereo) {
|
||||
if (_fileFormat != kFileFormatWavFile) {
|
||||
RTC_LOG(LS_WARNING) << "Stereo is only allowed for WAV files";
|
||||
StopRecording();
|
||||
return -1;
|
||||
}
|
||||
if ((STR_NCASE_CMP(tmpAudioCodec.plname, "L16", 4) != 0) &&
|
||||
(STR_NCASE_CMP(tmpAudioCodec.plname, "PCMU", 5) != 0) &&
|
||||
(STR_NCASE_CMP(tmpAudioCodec.plname, "PCMA", 5) != 0)) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "Stereo is only allowed for codec PCMU, PCMA and L16 ";
|
||||
StopRecording();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
memcpy(&codec_info_, &tmpAudioCodec, sizeof(CodecInst));
|
||||
_recordingActive = true;
|
||||
_ptrOutStream = &stream;
|
||||
_notificationMs = notificationTimeMs;
|
||||
_recordDurationMs = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::StopRecording() {
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (!_recordingActive) {
|
||||
RTC_LOG(LS_WARNING) << "recording is not active!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
_isStereo = false;
|
||||
|
||||
if (_ptrFileUtilityObj != NULL) {
|
||||
// Both AVI and WAV header has to be updated before closing the stream
|
||||
// because they contain size information.
|
||||
if ((_fileFormat == kFileFormatWavFile) && (_ptrOutStream != NULL)) {
|
||||
_ptrFileUtilityObj->UpdateWavHeader(*_ptrOutStream);
|
||||
}
|
||||
delete _ptrFileUtilityObj;
|
||||
_ptrFileUtilityObj = NULL;
|
||||
}
|
||||
|
||||
if (_ptrOutStream != NULL) {
|
||||
// If MediaFileImpl opened the OutStream it must be reclaimed here.
|
||||
if (_openFile) {
|
||||
delete _ptrOutStream;
|
||||
_openFile = false;
|
||||
}
|
||||
_ptrOutStream = NULL;
|
||||
}
|
||||
|
||||
_recordingActive = false;
|
||||
codec_info_.pltype = 0;
|
||||
codec_info_.plname[0] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MediaFileImpl::IsRecording() {
|
||||
RTC_LOG(LS_VERBOSE) << "MediaFileImpl::IsRecording()";
|
||||
rtc::CritScope lock(&_crit);
|
||||
return _recordingActive;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::RecordDurationMs(uint32_t& durationMs) {
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (!_recordingActive) {
|
||||
durationMs = 0;
|
||||
return -1;
|
||||
}
|
||||
durationMs = _recordDurationMs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MediaFileImpl::IsStereo() {
|
||||
RTC_LOG(LS_VERBOSE) << "MediaFileImpl::IsStereo()";
|
||||
rtc::CritScope lock(&_crit);
|
||||
return _isStereo;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback) {
|
||||
rtc::CritScope lock(&_callbackCrit);
|
||||
|
||||
@ -788,35 +466,6 @@ int32_t MediaFileImpl::SetModuleFileCallback(FileCallback* callback) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::FileDurationMs(const char* fileName,
|
||||
uint32_t& durationMs,
|
||||
const FileFormats format,
|
||||
const uint32_t freqInHz) {
|
||||
if (!ValidFileName(fileName)) {
|
||||
return -1;
|
||||
}
|
||||
if (!ValidFrequency(freqInHz)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ModuleFileUtility* utilityObj = new ModuleFileUtility();
|
||||
if (utilityObj == NULL) {
|
||||
RTC_LOG(LS_ERROR) << "failed to allocate utility object!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const int32_t duration =
|
||||
utilityObj->FileDurationMs(fileName, format, freqInHz);
|
||||
delete utilityObj;
|
||||
if (duration == -1) {
|
||||
durationMs = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
durationMs = duration;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const {
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (!_playingActive) {
|
||||
@ -829,14 +478,12 @@ int32_t MediaFileImpl::PlayoutPositionMs(uint32_t& positionMs) const {
|
||||
|
||||
int32_t MediaFileImpl::codec_info(CodecInst& codecInst) const {
|
||||
rtc::CritScope lock(&_crit);
|
||||
if (!_playingActive && !_recordingActive) {
|
||||
RTC_LOG(LS_ERROR) << "Neither playout nor recording has been initialized!";
|
||||
if (!_playingActive) {
|
||||
RTC_LOG(LS_ERROR) << "Playout has not been initialized!";
|
||||
return -1;
|
||||
}
|
||||
if (codec_info_.pltype == 0 && codec_info_.plname[0] == '\0') {
|
||||
RTC_LOG(LS_ERROR) << "The CodecInst for "
|
||||
<< (_playingActive ? "Playback" : "Recording")
|
||||
<< " is unknown!";
|
||||
RTC_LOG(LS_ERROR) << "The CodecInst for Playback is unknown!";
|
||||
return -1;
|
||||
}
|
||||
memcpy(&codecInst, &codec_info_, sizeof(CodecInst));
|
||||
|
||||
@ -60,36 +60,8 @@ public:
|
||||
|
||||
int32_t PlayoutPositionMs(uint32_t& positionMs) const override;
|
||||
|
||||
int32_t IncomingAudioData(const int8_t* audioBuffer,
|
||||
const size_t bufferLength) override;
|
||||
|
||||
int32_t StartRecordingAudioFile(const char* fileName,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs = 0,
|
||||
const uint32_t maxSizeBytes = 0) override;
|
||||
|
||||
int32_t StartRecordingAudioStream(
|
||||
OutStream& stream,
|
||||
const FileFormats format,
|
||||
const CodecInst& codecInst,
|
||||
const uint32_t notificationTimeMs = 0) override;
|
||||
|
||||
int32_t StopRecording() override;
|
||||
|
||||
bool IsRecording() override;
|
||||
|
||||
int32_t RecordDurationMs(uint32_t& durationMs) override;
|
||||
|
||||
bool IsStereo() override;
|
||||
|
||||
int32_t SetModuleFileCallback(FileCallback* callback) override;
|
||||
|
||||
int32_t FileDurationMs(const char* fileName,
|
||||
uint32_t& durationMs,
|
||||
const FileFormats format,
|
||||
const uint32_t freqInHz = 16000) override;
|
||||
|
||||
int32_t codec_info(CodecInst& codecInst) const override;
|
||||
|
||||
private:
|
||||
@ -130,12 +102,10 @@ private:
|
||||
OutStream* _ptrOutStream;
|
||||
|
||||
FileFormats _fileFormat;
|
||||
uint32_t _recordDurationMs;
|
||||
uint32_t _playoutPositionMs;
|
||||
uint32_t _notificationMs;
|
||||
|
||||
bool _playingActive;
|
||||
bool _recordingActive;
|
||||
bool _isStereo;
|
||||
bool _openFile;
|
||||
|
||||
|
||||
@ -51,56 +51,3 @@ TEST_F(MediaFileTest, MAYBE_StartPlayingAudioFileWithoutError) {
|
||||
|
||||
ASSERT_EQ(0, media_file_->StopPlaying());
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
#define MAYBE_WriteWavFile DISABLED_WriteWavFile
|
||||
#else
|
||||
#define MAYBE_WriteWavFile WriteWavFile
|
||||
#endif
|
||||
TEST_F(MediaFileTest, MAYBE_WriteWavFile) {
|
||||
// Write file.
|
||||
static const size_t kHeaderSize = 44;
|
||||
static const size_t kPayloadSize = 320;
|
||||
webrtc::CodecInst codec = {
|
||||
0, "L16", 16000, static_cast<int>(kPayloadSize), 1
|
||||
};
|
||||
std::string outfile = webrtc::test::OutputPath() + "wavtest.wav";
|
||||
ASSERT_EQ(0,
|
||||
media_file_->StartRecordingAudioFile(
|
||||
outfile.c_str(), webrtc::kFileFormatWavFile, codec));
|
||||
static const int8_t kFakeData[kPayloadSize] = {0};
|
||||
ASSERT_EQ(0, media_file_->IncomingAudioData(kFakeData, kPayloadSize));
|
||||
ASSERT_EQ(0, media_file_->StopRecording());
|
||||
|
||||
// Check the file we just wrote.
|
||||
static const uint8_t kExpectedHeader[] = {
|
||||
'R', 'I', 'F', 'F',
|
||||
0x64, 0x1, 0, 0, // size of whole file - 8: 320 + 44 - 8
|
||||
'W', 'A', 'V', 'E',
|
||||
'f', 'm', 't', ' ',
|
||||
0x10, 0, 0, 0, // size of fmt block - 8: 24 - 8
|
||||
0x1, 0, // format: PCM (1)
|
||||
0x1, 0, // channels: 1
|
||||
0x80, 0x3e, 0, 0, // sample rate: 16000
|
||||
0, 0x7d, 0, 0, // byte rate: 2 * 16000
|
||||
0x2, 0, // block align: NumChannels * BytesPerSample
|
||||
0x10, 0, // bits per sample: 2 * 8
|
||||
'd', 'a', 't', 'a',
|
||||
0x40, 0x1, 0, 0, // size of payload: 320
|
||||
};
|
||||
static_assert(sizeof(kExpectedHeader) == kHeaderSize, "header size");
|
||||
|
||||
EXPECT_EQ(kHeaderSize + kPayloadSize, webrtc::test::GetFileSize(outfile));
|
||||
FILE* f = fopen(outfile.c_str(), "rb");
|
||||
ASSERT_TRUE(f);
|
||||
|
||||
uint8_t header[kHeaderSize];
|
||||
ASSERT_EQ(1u, fread(header, kHeaderSize, 1, f));
|
||||
EXPECT_EQ(0, memcmp(kExpectedHeader, header, kHeaderSize));
|
||||
|
||||
uint8_t payload[kPayloadSize];
|
||||
ASSERT_EQ(1u, fread(payload, kPayloadSize, 1, f));
|
||||
EXPECT_EQ(0, memcmp(kFakeData, payload, kPayloadSize));
|
||||
|
||||
EXPECT_EQ(0, fclose(f));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user