Unverified Commit 8ba32081 authored by Wolle's avatar Wolle Committed by GitHub

Merge pull request #636 from schreibfaul1/dev

Arduino V3
parents 961b320c 7caef301
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
* *
* Created on: Oct 26.2018 * Created on: Oct 26.2018
* *
* Version 3.0.7z * Version 3.0.8
* Updated on: Dec 16.2023 * Updated on: Dec 22.2023
* Author: Wolle (schreibfaul1) * Author: Wolle (schreibfaul1)
* *
*/ */
...@@ -2130,30 +2130,33 @@ bool Audio::pauseResume() { ...@@ -2130,30 +2130,33 @@ bool Audio::pauseResume() {
return retVal; return retVal;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool Audio::playChunk() { void Audio::playChunk() {
// If we've got data, try and pump it out..
int16_t sample[2]; int16_t sample[2];
if(getBitsPerSample() == 8) {
if(getChannels() == 1) { auto pc = [&](int16_t *s16) { // lambda, inner function
while(m_validSamples) { if(playSample(s16)){
m_validSamples--;
m_curSample++;
return true;
}
return false;
};
// If we've got data, try and pump it out..
while(m_validSamples){
if(getBitsPerSample() == 8) {
if(getChannels() == 1) {
uint8_t x = m_outBuff[m_curSample] & 0x00FF; uint8_t x = m_outBuff[m_curSample] & 0x00FF;
uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8; uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8;
sample[RIGHTCHANNEL] = x; sample[RIGHTCHANNEL] = x;
sample[LEFTCHANNEL] = x; sample[LEFTCHANNEL] = x;
while(1) { if(!pc(sample)){ break;} // playSample in lambda
if(playSample(sample)) break;
} // Can't send?
sample[RIGHTCHANNEL] = y; sample[RIGHTCHANNEL] = y;
sample[LEFTCHANNEL] = y; sample[LEFTCHANNEL] = y;
while(1) { if(!pc(sample)){ break;} // playSample in lambda
if(playSample(sample)) break;
} // Can't send?
m_validSamples--;
m_curSample++;
} }
} if(getChannels() == 2) {
if(getChannels() == 2) {
while(m_validSamples) {
uint8_t x = m_outBuff[m_curSample] & 0x00FF; uint8_t x = m_outBuff[m_curSample] & 0x00FF;
uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8; uint8_t y = (m_outBuff[m_curSample] & 0xFF00) >> 8;
if(!m_f_forceMono) { // stereo mode if(!m_f_forceMono) { // stereo mode
...@@ -2165,54 +2168,29 @@ bool Audio::playChunk() { ...@@ -2165,54 +2168,29 @@ bool Audio::playChunk() {
sample[RIGHTCHANNEL] = xy; sample[RIGHTCHANNEL] = xy;
sample[LEFTCHANNEL] = xy; sample[LEFTCHANNEL] = xy;
} }
if(!pc(sample)){ break;} // playSample in lambda
while(1) {
if(playSample(sample)) break;
} // Can't send?
m_validSamples--;
m_curSample++;
} }
} }
m_curSample = 0;
return true; if(getBitsPerSample() == 16) {
} if(getChannels() == 1) {
if(getBitsPerSample() == 16) {
if(getChannels() == 1) {
while(m_validSamples) {
sample[RIGHTCHANNEL] = m_outBuff[m_curSample]; sample[RIGHTCHANNEL] = m_outBuff[m_curSample];
sample[LEFTCHANNEL] = m_outBuff[m_curSample]; sample[LEFTCHANNEL] = m_outBuff[m_curSample];
if(!playSample(sample)) {
log_e("can't send");
return false;
} // Can't send
m_validSamples--;
m_curSample++;
} }
} if(getChannels() == 2) {
if(getChannels() == 2) { if(!m_f_forceMono) { // stereo mode
m_curSample = 0; sample[RIGHTCHANNEL] = m_outBuff[m_curSample * 2];
while(m_validSamples) { sample[LEFTCHANNEL] = m_outBuff[m_curSample * 2 + 1];
if(!m_f_forceMono) { // stereo mode }
sample[RIGHTCHANNEL] = m_outBuff[m_curSample * 2]; else { // mono mode, #100
sample[LEFTCHANNEL] = m_outBuff[m_curSample * 2 + 1]; int16_t xy = (m_outBuff[m_curSample * 2] + m_outBuff[m_curSample * 2 + 1]) / 2;
} sample[RIGHTCHANNEL] = xy;
else { // mono mode, #100 sample[LEFTCHANNEL] = xy;
int16_t xy = (m_outBuff[m_curSample * 2] + m_outBuff[m_curSample * 2 + 1]) / 2; }
sample[RIGHTCHANNEL] = xy;
sample[LEFTCHANNEL] = xy;
}
playSample(sample);
m_validSamples--;
m_curSample++;
} }
} }
m_curSample = 0; if(!pc(sample)){ break;} // playSample in lambda
return true;
} }
log_e("BitsPer Sample must be 8 or 16!");
m_validSamples = 0;
stopSong();
return false;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void Audio::loop() { void Audio::loop() {
...@@ -2952,6 +2930,7 @@ void Audio::processLocalFile() { ...@@ -2952,6 +2930,7 @@ void Audio::processLocalFile() {
if(f_fileDataComplete && InBuff.bufferFilled() < InBuff.getMaxBlockSize()) { if(f_fileDataComplete && InBuff.bufferFilled() < InBuff.getMaxBlockSize()) {
if(InBuff.bufferFilled()) { if(InBuff.bufferFilled()) {
if(!readID3V1Tag()) { if(!readID3V1Tag()) {
if(m_validSamples) {playChunk(); return;} // play samples first
int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.bufferFilled()); int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.bufferFilled());
if(bytesDecoded <= InBuff.bufferFilled()) { // avoid InBuff overrun (can be if file is corrupt) if(bytesDecoded <= InBuff.bufferFilled()) { // avoid InBuff overrun (can be if file is corrupt)
if(m_f_playing) { if(m_f_playing) {
...@@ -3001,17 +2980,7 @@ void Audio::processLocalFile() { ...@@ -3001,17 +2980,7 @@ void Audio::processLocalFile() {
// play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if(f_stream) { if(f_stream) {
static uint8_t cnt = 0; playAudioData();
uint8_t compression;
if(m_codec == CODEC_WAV) compression = 1;
if(m_codec == CODEC_FLAC) compression = 2;
else
compression = 3;
cnt++;
if(cnt == compression) {
playAudioData();
cnt = 0;
}
} }
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
...@@ -3091,17 +3060,7 @@ void Audio::processWebStream() { ...@@ -3091,17 +3060,7 @@ void Audio::processWebStream() {
// play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if(f_stream) { if(f_stream) {
static uint8_t cnt = 0; playAudioData();
uint8_t compression;
if(m_codec == CODEC_WAV) compression = 1;
if(m_codec == CODEC_FLAC) compression = 2;
else
compression = 3;
cnt++;
if(cnt == compression) {
playAudioData();
cnt = 0;
}
} }
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
...@@ -3200,6 +3159,7 @@ void Audio::processWebFile() { ...@@ -3200,6 +3159,7 @@ void Audio::processWebFile() {
if(f_webFileDataComplete && InBuff.bufferFilled() < InBuff.getMaxBlockSize()) { if(f_webFileDataComplete && InBuff.bufferFilled() < InBuff.getMaxBlockSize()) {
if(InBuff.bufferFilled()) { if(InBuff.bufferFilled()) {
if(!readID3V1Tag()) { if(!readID3V1Tag()) {
if(m_validSamples) {playChunk(); return;} // play samples first
int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.bufferFilled()); int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.bufferFilled());
if(bytesDecoded > 2) { if(bytesDecoded > 2) {
InBuff.bytesWasRead(bytesDecoded); InBuff.bytesWasRead(bytesDecoded);
...@@ -3233,17 +3193,7 @@ void Audio::processWebFile() { ...@@ -3233,17 +3193,7 @@ void Audio::processWebFile() {
// play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if(f_stream) { if(f_stream) {
static uint8_t cnt = 0; playAudioData();
uint8_t compression;
if(m_codec == CODEC_WAV) compression = 1;
if(m_codec == CODEC_FLAC) compression = 2;
else
compression = 3;
cnt++;
if(cnt == compression) {
playAudioData();
cnt = 0;
}
} }
return; return;
} }
...@@ -3356,12 +3306,7 @@ void Audio::processWebStreamTS() { ...@@ -3356,12 +3306,7 @@ void Audio::processWebStreamTS() {
// play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if(f_stream) { if(f_stream) {
static uint8_t cnt = 0; playAudioData();
cnt++;
if(cnt == 3) {
playAudioData();
cnt = 0;
} // aac only
} }
return; return;
} }
...@@ -3479,17 +3424,14 @@ void Audio::processWebStreamHLS() { ...@@ -3479,17 +3424,14 @@ void Audio::processWebStreamHLS() {
// play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // play audio data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if(f_stream) { if(f_stream) {
static uint8_t cnt = 0; playAudioData();
cnt++;
if(cnt == 2) {
playAudioData();
cnt = 0;
} // aac only
} }
return; return;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void Audio::playAudioData() { void Audio::playAudioData() {
if(m_validSamples) {playChunk(); return;} // play samples first
if(InBuff.bufferFilled() < InBuff.getMaxBlockSize()) return; // guard if(InBuff.bufferFilled() < InBuff.getMaxBlockSize()) return; // guard
int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.getMaxBlockSize()); int bytesDecoded = sendBytes(InBuff.getReadPtr(), InBuff.getMaxBlockSize());
...@@ -3506,7 +3448,7 @@ void Audio::playAudioData() { ...@@ -3506,7 +3448,7 @@ void Audio::playAudioData() {
InBuff.bytesWasRead(bytesDecoded); InBuff.bytesWasRead(bytesDecoded);
return; return;
} }
if(bytesDecoded == 0) return; // syncword at pos0 found if(bytesDecoded == 0) return; // syncword at pos0
} }
return; return;
...@@ -4245,6 +4187,7 @@ void Audio::setDecoderItems() { ...@@ -4245,6 +4187,7 @@ void Audio::setDecoderItems() {
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
int Audio::sendBytes(uint8_t* data, size_t len) { int Audio::sendBytes(uint8_t* data, size_t len) {
int bytesLeft; int bytesLeft;
static bool f_setDecodeParamsOnce = true; static bool f_setDecodeParamsOnce = true;
int nextSync = 0; int nextSync = 0;
...@@ -4365,7 +4308,8 @@ int Audio::sendBytes(uint8_t* data, size_t len) { ...@@ -4365,7 +4308,8 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
audio_process_extern(m_outBuff, m_validSamples, &continueI2S); audio_process_extern(m_outBuff, m_validSamples, &continueI2S);
if(!continueI2S) { return bytesDecoded; } if(!continueI2S) { return bytesDecoded; }
} }
while(m_validSamples) { playChunk(); } m_curSample = 0;
playChunk();
return bytesDecoded; return bytesDecoded;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
...@@ -4500,7 +4444,7 @@ void Audio::printDecodeError(int r) { ...@@ -4500,7 +4444,7 @@ void Audio::printDecodeError(int r) {
case ERR_OPUS_INVALID_SAMPLERATE: e = "SAMPLERATE IS NOT 48000Hz"; break; case ERR_OPUS_INVALID_SAMPLERATE: e = "SAMPLERATE IS NOT 48000Hz"; break;
case ERR_OPUS_EXTRA_CHANNELS_UNSUPPORTED: e = "EXTRA CHANNELS UNSUPPORTED"; break; case ERR_OPUS_EXTRA_CHANNELS_UNSUPPORTED: e = "EXTRA CHANNELS UNSUPPORTED"; break;
case ERR_OPUS_SILK_MODE_UNSUPPORTED: e = "SILK MODE UNSUPPORTED"; break; case ERR_OPUS_SILK_MODE_UNSUPPORTED: e = "SILK MODE UNSUPPORTED"; break;
case ERR_OPUS_HYBRID_MODE_UNSUPPORTED: e = "HYBRID MODE UMSUPPORTED"; break; case ERR_OPUS_HYBRID_MODE_UNSUPPORTED: e = "HYBRID MODE UNSUPPORTED"; break;
case ERR_OPUS_CELT_BAD_ARG: e = "CELT_DECODER_BAD_ARG"; break; case ERR_OPUS_CELT_BAD_ARG: e = "CELT_DECODER_BAD_ARG"; break;
case ERR_OPUS_CELT_INTERNAL_ERROR: e = "CELT DECODER INTERNAL ERROR"; break; case ERR_OPUS_CELT_INTERNAL_ERROR: e = "CELT DECODER INTERNAL ERROR"; break;
case ERR_OPUS_CELT_UNIMPLEMENTED: e = "CELT DECODER UNIMPLEMENTED ARG"; break; case ERR_OPUS_CELT_UNIMPLEMENTED: e = "CELT DECODER UNIMPLEMENTED ARG"; break;
...@@ -4835,7 +4779,7 @@ bool Audio::playSample(int16_t sample[2]) { ...@@ -4835,7 +4779,7 @@ bool Audio::playSample(int16_t sample[2]) {
sample = IIR_filterChain2(sample); sample = IIR_filterChain2(sample);
//------------------------------------------- //-------------------------------------------
uint32_t s32 = Gain(sample); // vosample2lume; uint32_t s32 = Gain(sample); // sample2volume;
if(audio_process_i2s) { if(audio_process_i2s) {
// process audio sample just before writing to i2s // process audio sample just before writing to i2s
...@@ -4847,16 +4791,15 @@ bool Audio::playSample(int16_t sample[2]) { ...@@ -4847,16 +4791,15 @@ bool Audio::playSample(int16_t sample[2]) {
if(m_f_internalDAC) { s32 += 0x80008000; } if(m_f_internalDAC) { s32 += 0x80008000; }
m_i2s_bytesWritten = 0; m_i2s_bytesWritten = 0;
#if(ESP_IDF_VERSION_MAJOR == 5) #if(ESP_IDF_VERSION_MAJOR == 5)
esp_err_t err = i2s_channel_write(m_i2s_tx_handle, (const char*)&s32, sizeof(uint32_t), &m_i2s_bytesWritten, 100); esp_err_t err = i2s_channel_write(m_i2s_tx_handle, (const char*)&s32, sizeof(uint32_t), &m_i2s_bytesWritten, 0);
#else #else
esp_err_t err = i2s_write((i2s_port_t)m_i2s_num, (const char*)&s32, sizeof(uint32_t), &m_i2s_bytesWritten, 100); esp_err_t err = i2s_write((i2s_port_t)m_i2s_num, (const char*)&s32, sizeof(uint32_t), &m_i2s_bytesWritten, 0); // no wait
#endif #endif
if(err != ESP_OK) { if(err != ESP_OK) {
log_e("ESP32 Errorcode %i", err); log_e("ESP32 Errorcode %i", err);
return false; return false;
} }
if(m_i2s_bytesWritten < 4) { if(m_i2s_bytesWritten < 4) { // no more space in dma buffer --> break and try it later
log_e("Can't stuff any more in I2S..."); // increase waitingtime or outputbuffer
return false; return false;
} }
return true; return true;
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
* *
* Created on: Oct 28,2018 * Created on: Oct 28,2018
* *
* Version 3.0.7z * Version 3.0.8
* Updated on: Dec 16.2023 * Updated on: Dec 22.2023
* Author: Wolle (schreibfaul1) * Author: Wolle (schreibfaul1)
*/ */
...@@ -220,7 +220,7 @@ private: ...@@ -220,7 +220,7 @@ private:
bool setBitsPerSample(int bits); bool setBitsPerSample(int bits);
bool setChannels(int channels); bool setChannels(int channels);
bool setBitrate(int br); bool setBitrate(int br);
bool playChunk(); void playChunk();
bool playSample(int16_t sample[2]); bool playSample(int16_t sample[2]);
void computeVUlevel(int16_t sample[2]); void computeVUlevel(int16_t sample[2]);
void computeLimit(); void computeLimit();
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* based on Xiph.Org Foundation celt decoder * based on Xiph.Org Foundation celt decoder
* *
* Created on: 26.01.2023 * Created on: 26.01.2023
* Updated on: 07.04.2023 * Updated on: 23.12.2023
*/ */
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
// O G G / O P U S I M P L. // O G G / O P U S I M P L.
...@@ -16,7 +16,9 @@ bool s_f_opusSubsequentPage = false; ...@@ -16,7 +16,9 @@ bool s_f_opusSubsequentPage = false;
bool s_f_opusParseOgg = false; bool s_f_opusParseOgg = false;
bool s_f_newSteamTitle = false; // streamTitle bool s_f_newSteamTitle = false; // streamTitle
bool s_f_opusFramePacket = false; bool s_f_opusFramePacket = false;
bool s_f_opusStereoFlag = false;
uint8_t s_opusChannels = 0; uint8_t s_opusChannels = 0;
uint8_t s_opusCountCode = 0;
uint16_t s_opusSamplerate = 0; uint16_t s_opusSamplerate = 0;
uint32_t s_opusSegmentLength = 0; uint32_t s_opusSegmentLength = 0;
char *s_opusChbuf = NULL; char *s_opusChbuf = NULL;
...@@ -58,6 +60,7 @@ void OPUSsetDefaults(){ ...@@ -58,6 +60,7 @@ void OPUSsetDefaults(){
s_f_opusParseOgg = false; s_f_opusParseOgg = false;
s_f_newSteamTitle = false; // streamTitle s_f_newSteamTitle = false; // streamTitle
s_f_opusFramePacket = false; s_f_opusFramePacket = false;
s_f_opusStereoFlag = false;
s_opusChannels = 0; s_opusChannels = 0;
s_opusSamplerate = 0; s_opusSamplerate = 0;
s_opusSegmentLength = 0; s_opusSegmentLength = 0;
...@@ -65,6 +68,7 @@ void OPUSsetDefaults(){ ...@@ -65,6 +68,7 @@ void OPUSsetDefaults(){
s_opusSegmentTableSize = 0; s_opusSegmentTableSize = 0;
s_opusOldMode = 0xFF; s_opusOldMode = 0xFF;
s_opusSegmentTableRdPtr = -1; s_opusSegmentTableRdPtr = -1;
s_opusCountCode = 0;
s_opusError = 0; s_opusError = 0;
} }
...@@ -73,38 +77,100 @@ void OPUSsetDefaults(){ ...@@ -73,38 +77,100 @@ void OPUSsetDefaults(){
int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
static uint16_t fs = 0;
static uint8_t M = 0;
static uint16_t paddingBytes = 0;
static uint16_t samplesPerFrame = 0;
int ret = ERR_OPUS_NONE;
int len = 0;
if(s_f_opusParseOgg){ if(s_f_opusParseOgg){
int ret = OPUSparseOGG(inbuf, bytesLeft); fs = 0;
M = 0;
paddingBytes = 0;
s_opusCountCode = 0;
ret = OPUSparseOGG(inbuf, bytesLeft);
if(ret == ERR_OPUS_NONE) return OPUS_PARSE_OGG_DONE; // ok if(ret == ERR_OPUS_NONE) return OPUS_PARSE_OGG_DONE; // ok
else return ret; // error else return ret; // error
} }
if(s_opusCountCode == 3) goto FramePacking;
if(s_f_opusFramePacket){ if(s_f_opusFramePacket){
if(s_opusSegmentTableSize > 0){ if(s_opusSegmentTableSize > 0){
s_opusSegmentTableRdPtr++; s_opusSegmentTableRdPtr++;
s_opusSegmentTableSize--; s_opusSegmentTableSize--;
int len = s_opusSegmentTable[s_opusSegmentTableRdPtr]; len = s_opusSegmentTable[s_opusSegmentTableRdPtr];
}
ret = parseOpusTOC(inbuf[0]);
samplesPerFrame = opus_packet_get_samples_per_frame(inbuf, 48000);
if(ret < 0) goto exit; // error
FramePacking:
// https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
if(s_opusCountCode == 0){ // Code 0: One Frame in the Packet
*bytesLeft -= len; *bytesLeft -= len;
int32_t ret = parseOpusTOC(inbuf[0]); ret = parseOpusTOC(inbuf[0]);
if(ret < 0) return ret; if(ret < 0) goto exit; // error
int frame_size = opus_packet_get_samples_per_frame(inbuf, 48000);
len--; len--;
inbuf++; inbuf++;
ec_dec_init((uint8_t *)inbuf, len); ec_dec_init((uint8_t *)inbuf, len);
ret = celt_decode_with_ec(inbuf, len, (int16_t*)outbuf, frame_size); ret = celt_decode_with_ec(inbuf, len, (int16_t*)outbuf, samplesPerFrame);
if(ret < 0) return ret; // celt error if(ret < 0) goto exit; // celt error
s_opusValidSamples = ret; s_opusValidSamples = ret;
ret = ERR_OPUS_NONE;
if(s_opusSegmentTableSize== 0){ }
s_opusSegmentTableRdPtr = -1; // back to the parking position if(s_opusCountCode == 1){ // Code 1: Two Frames in the Packet, Each with Equal Compressed Size
s_f_opusFramePacket = false; log_e("OPUS countCode 1 not supported yet"); vTaskDelay(1000); // todo
s_f_opusParseOgg = true; }
if(s_opusCountCode == 2){ // Code 2: Two Frames in the Packet, with Different Compressed Sizes
log_e("OPUS countCode 2 not supported yet"); vTaskDelay(1000); // todo
}
if(s_opusCountCode == 3){ // Code 3: A Signaled Number of Frames in the Packet
if(M == 0){
bool v = ((inbuf[1] & 0x80) == 0x80); // VBR indicator
(void)v;
bool p = ((inbuf[1] & 0x40) == 0x40); // padding bit
M = inbuf[1] & 0x3F; // max framecount
// log_i("v %i, p %i, M %i", v, p, M);
paddingBytes = 0;
if(p){
int i = 0;
while(inbuf[2 + i] == 255){
paddingBytes += inbuf[2 + i];
i++;
}
paddingBytes += inbuf[2 + i];
fs = (len - 3 - i - paddingBytes) / M;
*bytesLeft -= 3 + i;
inbuf += 3 + i;
}
} }
*bytesLeft -= fs;
ec_dec_init((uint8_t *)inbuf, fs);
ret = celt_decode_with_ec(inbuf, fs, (int16_t*)outbuf, samplesPerFrame);
if(ret < 0) goto exit; // celt error
s_opusValidSamples = ret;
M--;
// log_i("M %i fs %i spf %i", M, fs, samplesPerFrame);
ret = ERR_OPUS_NONE;
if(M == 0) {s_opusCountCode = 0; *bytesLeft -= paddingBytes; goto exit;}
return ret;
} }
} }
return ERR_OPUS_NONE;
exit:
if(s_opusSegmentTableSize== 0){
s_opusSegmentTableRdPtr = -1; // back to the parking position
s_f_opusFramePacket = false;
s_f_opusParseOgg = true;
}
return ret;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int32_t opus_packet_get_samples_per_frame(const uint8_t *data, int32_t Fs) { int32_t opus_packet_get_samples_per_frame(const uint8_t *data, int32_t Fs) {
...@@ -155,8 +221,8 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716 ...@@ -155,8 +221,8 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
uint8_t mode = 0; uint8_t mode = 0;
uint8_t configNr = 0; uint8_t configNr = 0;
uint8_t s = 0; uint8_t s = 0; // stereo flag
uint8_t c = 0; (void)c; uint8_t c = 0; (void)c; // count code
configNr = (TOC_Byte & 0b11111000) >> 3; configNr = (TOC_Byte & 0b11111000) >> 3;
s = (TOC_Byte & 0b00000100) >> 2; s = (TOC_Byte & 0b00000100) >> 2;
...@@ -184,13 +250,13 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716 ...@@ -184,13 +250,13 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
c = 2: 2 frames in the packet, with different compressed sizes c = 2: 2 frames in the packet, with different compressed sizes
c = 3: an arbitrary number of frames in the packet c = 3: an arbitrary number of frames in the packet
*/ */
s_opusCountCode = c;
// log_i("configNr %i, s %i, c %i", configNr, s, c); s_f_opusStereoFlag = s;
if(configNr < 12) return ERR_OPUS_SILK_MODE_UNSUPPORTED; if(configNr < 12) return ERR_OPUS_SILK_MODE_UNSUPPORTED;
if(configNr < 16) return ERR_OPUS_HYBRID_MODE_UNSUPPORTED; if(configNr < 16) return ERR_OPUS_HYBRID_MODE_UNSUPPORTED;
return s; return configNr;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int parseOpusComment(uint8_t *inbuf, int nBytes){ // reference https://exiftool.org/TagNames/Vorbis.html#Comments int parseOpusComment(uint8_t *inbuf, int nBytes){ // reference https://exiftool.org/TagNames/Vorbis.html#Comments
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment