82 lines
1.7 KiB
C++
82 lines
1.7 KiB
C++
|
|
#pragma once
|
|
|
|
#include <stdio.h>
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <opusenc.h>
|
|
|
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
|
|
|
class OpusFileWriter
|
|
{
|
|
public:
|
|
OpusFileWriter()
|
|
{
|
|
}
|
|
|
|
~OpusFileWriter()
|
|
{
|
|
assert(!m_Enc);
|
|
}
|
|
|
|
void Init(const char* file, uint32_t sampleRate)
|
|
{
|
|
assert(!m_Enc);
|
|
m_Samples = 0;
|
|
|
|
m_Comments = ope_comments_create();
|
|
|
|
int error;
|
|
m_Enc = ope_encoder_create_file(file, m_Comments, sampleRate, 1, 0, &error);
|
|
assert(error == 0);
|
|
|
|
ope_encoder_ctl(m_Enc, OPUS_SET_DTX(1));
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
if(!m_Enc)
|
|
return;
|
|
|
|
ope_encoder_drain(m_Enc);
|
|
ope_encoder_destroy(m_Enc);
|
|
ope_comments_destroy(m_Comments);
|
|
m_Enc = nullptr;
|
|
m_Comments = nullptr;
|
|
}
|
|
|
|
void WriteSamples(const int16_t* samples, uint32_t numSamples)
|
|
{
|
|
if(!m_Enc)
|
|
return;
|
|
|
|
ope_encoder_write(m_Enc, samples, numSamples);
|
|
m_Samples += numSamples;
|
|
}
|
|
|
|
void PadSilence(uint32_t numSamples)
|
|
{
|
|
if(!m_Enc || m_Samples >= numSamples)
|
|
return;
|
|
|
|
static const int16_t silence[128] = {0};
|
|
uint32_t pad = numSamples - m_Samples;
|
|
while(pad > 0)
|
|
{
|
|
const int samples = MIN(sizeof(silence) / bytesPerSample, pad);
|
|
ope_encoder_write(m_Enc, silence, samples);
|
|
pad -= samples;
|
|
}
|
|
m_Samples = numSamples;
|
|
}
|
|
|
|
private:
|
|
OggOpusComments *m_Comments = nullptr;
|
|
OggOpusEnc *m_Enc = nullptr;
|
|
uint32_t m_Samples = 0;
|
|
|
|
static const uint32_t bytesPerSample = 2;
|
|
};
|