Rewrote c99 like code to valid code, more changes to comply coding style

This commit is contained in:
Ferdinand Thiessen 2016-04-03 20:23:32 +02:00 committed by Lukas Dürrenberger
parent 2a85734694
commit d1774b21e6
2 changed files with 41 additions and 46 deletions

View File

@ -65,7 +65,7 @@ namespace
return static_cast<opus_int64>(stream->tell()); return static_cast<opus_int64>(stream->tell());
} }
static OpusFileCallbacks callbacks = {&read, &seek, &tell, NULL}; const OpusFileCallbacks callbacks = {&read, &seek, &tell, NULL};
} }
namespace sf namespace sf
@ -149,7 +149,6 @@ Uint64 SoundFileReaderOpus::read(Int16* samples, Uint64 maxCount)
Uint64 count = 0; Uint64 count = 0;
while (maxCount > 0) while (maxCount > 0)
{ {
// since maxCount is uint64 we have to ensure that samplesToRead is <= INT_MAX (int overflow) // since maxCount is uint64 we have to ensure that samplesToRead is <= INT_MAX (int overflow)
if (maxCount > INT_MAX) if (maxCount > INT_MAX)
{ {
@ -185,6 +184,7 @@ void SoundFileReaderOpus::close()
if (m_opus != NULL) if (m_opus != NULL)
{ {
op_free(m_opus); op_free(m_opus);
m_opus = NULL;
m_channelCount = 0; m_channelCount = 0;
} }
} }

View File

@ -28,21 +28,19 @@
#include <SFML/Audio/SoundFileWriterOpus.hpp> #include <SFML/Audio/SoundFileWriterOpus.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm> #include <algorithm>
#include <cstring>
#include <ctime>
#include <cassert> #include <cassert>
#include <vector>
// Anonymous namespace // Anonymous namespace
namespace namespace
{ {
// Make sure to write int into buffer little endian // Make sure to write int into buffer little endian
void writeUint32(unsigned char* buffer, sf::Uint32 value) void writeUint32(std::vector<unsigned char>& buffer, const sf::Uint32 value)
{ {
buffer[0] = static_cast<unsigned char>(value & 0x000000FF); buffer.push_back(static_cast<unsigned char>(value & 0x000000FF));
buffer[1] = static_cast<unsigned char>((value & 0x0000FF00) >> 8); buffer.push_back(static_cast<unsigned char>((value & 0x0000FF00) >> 8));
buffer[2] = static_cast<unsigned char>((value & 0x00FF0000) >> 16); buffer.push_back(static_cast<unsigned char>((value & 0x00FF0000) >> 16));
buffer[3] = static_cast<unsigned char>((value & 0xFF000000) >> 24); buffer.push_back(static_cast<unsigned char>((value & 0xFF000000) >> 24));
} }
} }
@ -84,7 +82,6 @@ bool SoundFileWriterOpus::open(const std::string& filename, unsigned int sampleR
// Save the channel count // Save the channel count
m_channelCount = channelCount; m_channelCount = channelCount;
m_sampleRate = sampleRate; m_sampleRate = sampleRate;
std::srand(std::time(0));
// Initialize the ogg/opus stream // Initialize the ogg/opus stream
if (ogg_stream_init(&m_ogg, std::rand()) == -1) if (ogg_stream_init(&m_ogg, std::rand()) == -1)
@ -93,13 +90,14 @@ bool SoundFileWriterOpus::open(const std::string& filename, unsigned int sampleR
close(); close();
return false; return false;
} }
int status = 0;
int status = OPUS_OK;
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)
{ {
err() << "Failed to write ogg/opus file \"" << filename << "\"" << std::endl; err() << "Failed to write ogg/opus file \"" << filename << "\"" << std::endl;
if (status == OPUS_BAD_ARG) if (status == OPUS_BAD_ARG)
err() << "Possible wrong sample rate, allowed are 8000, 12000, 16000, 24000, or 48000 Hz." << std::endl; err() << "Possibly wrong sample rate, allowed are 8000, 12000, 16000, 24000, or 48000 Hz." << std::endl;
close(); close();
return false; return false;
} }
@ -115,19 +113,18 @@ 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 // Create opus header MAGICBYTES VERSION
unsigned char headerData[19]; std::string magicBytes("OpusHead1");
memset(static_cast<void*>(headerData), 0, 19); std::vector<unsigned char> headerData(magicBytes.begin(), magicBytes.end());
memcpy(static_cast<void*>(headerData), "OpusHead", 8);
headerData[8] = 1; // Version headerData.push_back(channelCount);
headerData[9] = channelCount; writeUint32(headerData, static_cast<Uint32>(sampleRate));
writeUint32(headerData + 12, static_cast<Uint32>(sampleRate)); headerData.push_back(channelCount > 8 ? 255 : (channelCount > 2)); // Mapping family
headerData[18] = channelCount > 8 ? 255 : (channelCount > 2); // Mapping family
// Map opus header to ogg packet // Map opus header to ogg packet
ogg_packet op; ogg_packet op;
op.packet = headerData; op.packet = &headerData.front(); // C++11: headerData.data();
op.bytes = 19; op.bytes = headerData.size();
op.b_o_s = 1; op.b_o_s = 1;
op.e_o_s = 0; op.e_o_s = 0;
op.granulepos = 0; op.granulepos = 0;
@ -138,26 +135,22 @@ bool SoundFileWriterOpus::open(const std::string& filename, unsigned int sampleR
flushBlocks(); flushBlocks();
// Create comment header, needs to be in a new page // Create comment header, needs to be in a new page
const char* opusVersion = opus_get_version_string(); // commentData initialized with magic bytes
Uint32 opusVersionLength = strlen(opusVersion); magicBytes = "OpusTags";
const int commentLength = 8 + 4 + opusVersionLength + 4; std::vector<unsigned char> commentData(magicBytes.begin(), magicBytes.end()); // C++11: commentData({'O', 'p', 'u', 's', 'T', 'a', 'g', 's'});
unsigned char commentData[commentLength];
// Magic bytes
memcpy(static_cast<void*>(commentData), "OpusTags", 8);
// unsigned 32bit integer: Length of vendor string (encoding library)
writeUint32(commentData + 8, opusVersionLength);
// Vendor string // Vendor string
memcpy(static_cast<void*>(commentData+12), opusVersion, opusVersionLength); const std::string opusVersion(opus_get_version_string());
// unsigned 32bit integer: Length of vendor string (encoding library)
writeUint32(commentData, opusVersion.size());
commentData.insert(commentData.end(), opusVersion.begin(), opusVersion.end());
// Length of user comments (E.g. you can add a ENCODER tag for SFML) // Length of user comments (E.g. you can add a ENCODER tag for SFML)
writeUint32(commentData + 12+opusVersionLength, 0); writeUint32(commentData, 0);
op.packet = commentData; op.packet = &commentData.front();
op.bytes = commentLength; op.bytes = commentData.size();
op.b_o_s = 0; op.b_o_s = 0;
op.e_o_s = 0; op.e_o_s = 0;
op.granulepos = 0; op.granulepos = 0;
@ -178,22 +171,23 @@ void SoundFileWriterOpus::write(const Int16* samples, Uint64 count)
const opus_uint32 frame_size = 960; const opus_uint32 frame_size = 960;
const opus_int32 buffer_size = frame_size * m_channelCount * sizeof(Int16); const opus_int32 buffer_size = frame_size * m_channelCount * sizeof(Int16);
unsigned char buffer[buffer_size]; unsigned char* buffer = new unsigned char[buffer_size];
Uint32 frame_number = 0; Uint32 frame_number = 0;
Uint8 endOfStream = 0; Uint8 endOfStream = 0;
ogg_packet op;
while (count > 0) while (count > 0)
{ {
ogg_packet op;
opus_int32 packet_size; 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 < frame_size * m_channelCount)
{ {
Int16 pad[frame_size*m_channelCount]; const Uint32 begin = (frame_number * frame_size * m_channelCount);
memset(pad, 0, frame_size * m_channelCount); std::vector<opus_int16> pad(samples + begin, samples + begin + count);
memcpy(pad, samples + (frame_number * frame_size * m_channelCount), count); pad.insert(pad.end(), (frame_size * m_channelCount) - pad.size(),0);
packet_size = opus_encode(m_opus, pad, frame_size, buffer, buffer_size); packet_size = opus_encode(m_opus, &pad.front(), frame_size, buffer, buffer_size);
endOfStream = 1; endOfStream = 1;
count = 0; count = 0;
} }
@ -221,6 +215,7 @@ void SoundFileWriterOpus::write(const Int16* samples, Uint64 count)
// Flush any produced block // Flush any produced block
flushBlocks(); flushBlocks();
delete[] buffer;
} }
@ -228,7 +223,7 @@ void SoundFileWriterOpus::write(const Int16* samples, Uint64 count)
void SoundFileWriterOpus::flushBlocks() void SoundFileWriterOpus::flushBlocks()
{ {
ogg_page page; ogg_page page;
while (ogg_stream_pageout(&m_ogg, &page) > 0 || ogg_stream_flush(&m_ogg, &page) > 0) while ((ogg_stream_pageout(&m_ogg, &page) > 0) || (ogg_stream_flush(&m_ogg, &page) > 0))
{ {
m_file.write(reinterpret_cast<const char*>(page.header), page.header_len); m_file.write(reinterpret_cast<const char*>(page.header), page.header_len);
m_file.write(reinterpret_cast<const char*>(page.body), page.body_len); m_file.write(reinterpret_cast<const char*>(page.body), page.body_len);