Reputation: 5505
I'm trying to record the audio transferred by a WebRTC PeerConnection
MediaStream
. I added a sink to the audio track which implements AudioTrackSinkInterface
. It implements the OnData
method:
void TestAudioTrackSink::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) {
size_t valueCount = number_of_channels * number_of_frames;
int16_t *_data = (int16_t*)audio_data;
f.write((char*)&_data, sizeof(int16_t) * valueCount);
f.flush();
}
f
is an ofstream
. Bits per sample is 16, sample rate is 16000, channels is 1, frames is 160.
But when I open the created file with AudaCity raw import (signed 16bit PCM, little endian, mono, sample rate 16000) I am not getting meaningful audio.
How to I correctly write that raw audio date?
Upvotes: 5
Views: 2893
Reputation: 15207
To add some more details to @ZoolWay already correct answer, I had file corruption issues when not opening the file in binary mode in Windows platform. In short, ensure the file has the ios_base::binary
flag:
std::ofstream stream(LR"(D:\test.pcm)", ios_base::binary);
[...]
void TestAudioTrackSink::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames)
{
size_t number_of_bytes = number_of_channels * number_of_frames * sizeof(int16_t); //assuming bits_per_sample is 16
stream.write(reinterpret_cast<const char*>(audio_data), number_of_bytes);
stream.flush();
}
Fixed the issue for me.
Upvotes: 0
Reputation: 5505
Turned out in the end I access the data where the pointer itself was stored and not where it was pointing to, a classic. The correct implementation of my method would look like:
void TestAudioTrackSink::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) {
size_t number_of_bytes = number_of_channels * number_of_frames * sizeof(int16_t); //assuming bits_per_sample is 16
f.write(reinterpret_cast<const char*>(audio_data), number_of_bytes);
f.flush();
}
Note: For more processing of webrtc native retrieved and sent audio data I am checking out a custom AudioDeviceModule now.
Upvotes: 4