mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 21:01:05 +08:00
Fixed opus header after code was rewritten, make more use of RAII
This commit is contained in:
parent
d1774b21e6
commit
1b09926a50
@ -91,7 +91,7 @@ bool SoundFileWriterOpus::open(const std::string& filename, unsigned int sampleR
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = OPUS_OK;
|
int status = OPUS_INTERNAL_ERROR;
|
||||||
m_opus = opus_encoder_create(sampleRate, channelCount, OPUS_APPLICATION_AUDIO, &status);
|
m_opus = opus_encoder_create(sampleRate, channelCount, OPUS_APPLICATION_AUDIO, &status);
|
||||||
if (status != OPUS_OK)
|
if (status != OPUS_OK)
|
||||||
{
|
{
|
||||||
@ -113,12 +113,20 @@ bool SoundFileWriterOpus::open(const std::string& filename, unsigned int sampleR
|
|||||||
// Set bitrate (VBR is default)
|
// Set bitrate (VBR is default)
|
||||||
opus_encoder_ctl(m_opus, OPUS_SET_BITRATE(128000));
|
opus_encoder_ctl(m_opus, OPUS_SET_BITRATE(128000));
|
||||||
|
|
||||||
// Create opus header MAGICBYTES VERSION
|
// Create opus header MAGICBYTES, C++11: init headerData with initializer_list
|
||||||
std::string magicBytes("OpusHead1");
|
std::string magicBytes("OpusHead");
|
||||||
std::vector<unsigned char> headerData(magicBytes.begin(), magicBytes.end());
|
std::vector<unsigned char> headerData(magicBytes.begin(), magicBytes.end());
|
||||||
|
|
||||||
|
headerData.push_back(1); // Version
|
||||||
headerData.push_back(channelCount);
|
headerData.push_back(channelCount);
|
||||||
|
headerData.push_back(0); // Preskip
|
||||||
|
headerData.push_back(0);
|
||||||
|
|
||||||
writeUint32(headerData, static_cast<Uint32>(sampleRate));
|
writeUint32(headerData, static_cast<Uint32>(sampleRate));
|
||||||
|
|
||||||
|
headerData.push_back(0); // Gain
|
||||||
|
headerData.push_back(0);
|
||||||
|
|
||||||
headerData.push_back(channelCount > 8 ? 255 : (channelCount > 2)); // Mapping family
|
headerData.push_back(channelCount > 8 ? 255 : (channelCount > 2)); // Mapping family
|
||||||
|
|
||||||
// Map opus header to ogg packet
|
// Map opus header to ogg packet
|
||||||
@ -169,53 +177,52 @@ void SoundFileWriterOpus::write(const Int16* samples, Uint64 count)
|
|||||||
{
|
{
|
||||||
assert(m_opus);
|
assert(m_opus);
|
||||||
|
|
||||||
const opus_uint32 frame_size = 960;
|
const opus_uint32 frameSize = 960;
|
||||||
const opus_int32 buffer_size = frame_size * m_channelCount * sizeof(Int16);
|
std::vector<unsigned char> buffer(frameSize * m_channelCount);
|
||||||
unsigned char* buffer = new unsigned char[buffer_size];
|
|
||||||
|
|
||||||
Uint32 frame_number = 0;
|
Uint32 frameNumber = 0;
|
||||||
Uint8 endOfStream = 0;
|
Uint8 endOfStream = 0;
|
||||||
|
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
ogg_packet op;
|
opus_int32 packetSize;
|
||||||
opus_int32 packet_size;
|
|
||||||
|
|
||||||
// Check if wee need to pad the input
|
// Check if wee need to pad the input
|
||||||
if (count < frame_size * m_channelCount)
|
if (count < frameSize * m_channelCount)
|
||||||
{
|
{
|
||||||
const Uint32 begin = (frame_number * frame_size * m_channelCount);
|
const Uint32 begin = frameNumber * frameSize * m_channelCount;
|
||||||
std::vector<opus_int16> pad(samples + begin, samples + begin + count);
|
std::vector<opus_int16> pad(samples + begin, samples + begin + count);
|
||||||
pad.insert(pad.end(), (frame_size * m_channelCount) - pad.size(),0);
|
pad.insert(pad.end(), (frameSize * m_channelCount) - pad.size(),0);
|
||||||
packet_size = opus_encode(m_opus, &pad.front(), frame_size, buffer, buffer_size);
|
packetSize = opus_encode(m_opus, &pad.front(), frameSize, &buffer.front(), buffer.size()); // C++11: replace &buffer.front() with buffer.data()
|
||||||
endOfStream = 1;
|
endOfStream = 1;
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet_size = opus_encode(m_opus, samples + (frame_number * frame_size * m_channelCount), frame_size, buffer, buffer_size);
|
packetSize = opus_encode(m_opus, samples + (frameNumber * frameSize * m_channelCount), frameSize, &buffer.front(), buffer.size());
|
||||||
count -= frame_size * m_channelCount;
|
count -= frameSize * m_channelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet_size < 0)
|
if (packetSize < 0)
|
||||||
{
|
{
|
||||||
err() << "An error occurred when encoding sound to opus." << std::endl;
|
err() << "An error occurred when encoding sound to opus." << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
op.packet = buffer;
|
|
||||||
op.bytes = packet_size;
|
ogg_packet op;
|
||||||
op.granulepos = frame_number * frame_size * 48000ul / m_sampleRate;
|
op.packet = &buffer.front();
|
||||||
|
op.bytes = packetSize;
|
||||||
|
op.granulepos = frameNumber * frameSize * 48000ul / m_sampleRate;
|
||||||
op.packetno = m_packageNumber++;
|
op.packetno = m_packageNumber++;
|
||||||
op.b_o_s = 0;
|
op.b_o_s = 0;
|
||||||
op.e_o_s = endOfStream;
|
op.e_o_s = endOfStream;
|
||||||
ogg_stream_packetin(&m_ogg, &op);
|
ogg_stream_packetin(&m_ogg, &op);
|
||||||
|
|
||||||
frame_number++;
|
frameNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush any produced block
|
// Flush any produced block
|
||||||
flushBlocks();
|
flushBlocks();
|
||||||
delete[] buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,6 +249,7 @@ void SoundFileWriterOpus::close()
|
|||||||
|
|
||||||
// Clear all the ogg/opus structures
|
// Clear all the ogg/opus structures
|
||||||
ogg_stream_clear(&m_ogg);
|
ogg_stream_clear(&m_ogg);
|
||||||
|
|
||||||
if (m_opus != NULL)
|
if (m_opus != NULL)
|
||||||
{
|
{
|
||||||
opus_encoder_destroy(m_opus);
|
opus_encoder_destroy(m_opus);
|
||||||
|
Loading…
Reference in New Issue
Block a user