Unverified Commit b57941b0 authored by Wolle's avatar Wolle Committed by GitHub

Add files via upload

parent dda1071b
...@@ -3,21 +3,19 @@ ...@@ -3,21 +3,19 @@
* 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: 27.01.2023 * Updated on: 28.01.2023
************************************************************************************/ ************************************************************************************/
#include "opus_decoder.h" #include "opus_decoder.h"
// global vars // global vars
bool f_m_parseOgg = false;
bool f_m_subsequentPage = false; bool f_m_subsequentPage = false;
// bool f_m_commentHeader = false; bool f_m_parseOgg = false;
// bool f_m_opusHeadWasRead = false;
// bool f_m_nextPage = false;
bool f_m_newSt = false; // streamTitle bool f_m_newSt = false; // streamTitle
bool f_m_opusFramePacket = false; bool f_m_opusFramePacket = false;
uint8_t m_channels = 0; uint8_t m_channels = 0;
uint16_t m_samplerate = 0; uint16_t m_samplerate = 0;
uint32_t m_segmentLength = 0;
char* m_chbuf = NULL; char* m_chbuf = NULL;
std::vector<uint16_t> m_segmentTable; // contains segment frame lengths std::vector<uint16_t> m_segmentTable; // contains segment frame lengths
...@@ -35,20 +33,29 @@ void OPUSDecoder_FreeBuffers(){ ...@@ -35,20 +33,29 @@ void OPUSDecoder_FreeBuffers(){
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
log_w("f_m_parseOgg %i", f_m_parseOgg);
if(f_m_parseOgg == true){ if(f_m_parseOgg){
log_i("parseogg"); log_i("parseogg");
int ret = OPUSparseOGG(inbuf, bytesLeft); int ret = OPUSparseOGG(inbuf, bytesLeft);
f_m_parseOgg = false;
return ret; return ret;
} }
if(f_m_opusFramePacket){ if(f_m_opusFramePacket){
int ret = parseOpusFramePacket(inbuf, bytesLeft); //int ret = parseOpusFramePacket(inbuf, bytesLeft);
if(m_segmentTable.size() > 0){
int len = m_segmentTable[m_segmentTable.size()-1];
*bytesLeft -= len;
m_segmentTable.pop_back();
// log_i("decode %i", len);
if(m_segmentTable.size() == 0){
f_m_opusFramePacket = false;
f_m_parseOgg = true;
}
}
}
*bytesLeft = 0;
}
return 0; return 0;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
...@@ -66,7 +73,7 @@ uint32_t OPUSGetBitRate(){ ...@@ -66,7 +73,7 @@ uint32_t OPUSGetBitRate(){
return 1; return 1;
} }
uint16_t OPUSGetOutputSamps(){ uint16_t OPUSGetOutputSamps(){
return 1024; return 10; // 1024
} }
char* OPUSgetStreamTitle(){ char* OPUSgetStreamTitle(){
if(f_m_newSt){ if(f_m_newSt){
...@@ -76,23 +83,27 @@ char* OPUSgetStreamTitle(){ ...@@ -76,23 +83,27 @@ char* OPUSgetStreamTitle(){
return NULL; return NULL;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft){ // https://www.rfc-editor.org/rfc/rfc6716 page 16 ff int parseOpusFramePacket(){ // https://www.rfc-editor.org/rfc/rfc6716 page 16 ff
uint8_t configNr = 0; uint8_t configNr = 0;
uint8_t s = 0; uint8_t s = 0;
uint8_t c = 0; uint8_t c = 0;
// //
uint8_t TOC_Byte = *(inbuf); uint8_t TOC_Byte = m_segmentTable[0];
configNr = (TOC_Byte & 0b11111000) >> 3; configNr = (TOC_Byte & 0b11111000) >> 3;
s = (TOC_Byte & 0b00000100) >> 2; s = (TOC_Byte & 0b00000100) >> 2;
c = (TOC_Byte & 0b00000011); c = (TOC_Byte & 0b00000011);
/* Configuration Mode Bandwidth FrameSizes /* Configuration Mode Bandwidth FrameSizes Audio Bandwidth Sample Rate (Effective)
configNr 16 ... 19 CELT NB 2.5, 5, 10, 20ms configNr 16 ... 19 CELT NB (narrowband) 2.5, 5, 10, 20ms 4 kHz 8 kHz
configNr 20 ... 23 CELT WB 2.5, 5, 10, 20ms configNr 20 ... 23 CELT WB (wideband) 2.5, 5, 10, 20ms 8 kHz 16 kHz
configNr 24 ... 27 CELT SWB 2.5, 5, 10, 20ms configNr 24 ... 27 CELT SWB(super wideband) 2.5, 5, 10, 20ms 12 kHz 24 kHz
configNr 28 ... 31 CELT FB 2.5, 5, 10, 20ms configNr 28 ... 31 CELT FB (fullband) 2.5, 5, 10, 20ms 20 kHz (*) 48 kHz <-------
(*) Although the sampling theorem allows a bandwidth as large as half the sampling rate, Opus never codes
audio above 20 kHz, as that is the generally accepted upper limit of human hearing.
s = 0: mono 1: stereo s = 0: mono 1: stereo
...@@ -102,8 +113,6 @@ int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft){ // https://www.rfc-ed ...@@ -102,8 +113,6 @@ int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft){ // https://www.rfc-ed
c = 3: an arbitrary number of frames in the packet c = 3: an arbitrary number of frames in the packet
*/ */
log_i("configNr %i", configNr); log_i("configNr %i", configNr);
log_i("s %i", s); log_i("s %i", s);
log_i("c %i", c); log_i("c %i", c);
...@@ -115,7 +124,7 @@ int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft){ // https://www.rfc-ed ...@@ -115,7 +124,7 @@ int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft){ // https://www.rfc-ed
return 0; return 0;
} }
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
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
// reference https://www.rfc-editor.org/rfc/rfc7845#section-5 // reference https://www.rfc-editor.org/rfc/rfc7845#section-5
int idx = OPUS_specialIndexOf(inbuf, "OpusTags", 10); int idx = OPUS_specialIndexOf(inbuf, "OpusTags", 10);
if(idx != 0) return 0; // is not OpusTags if(idx != 0) return 0; // is not OpusTags
...@@ -186,6 +195,7 @@ int parseOpusHead(uint8_t *inbuf, int nBytes){ // reference https://wiki.xiph.o ...@@ -186,6 +195,7 @@ int parseOpusHead(uint8_t *inbuf, int nBytes){ // reference https://wiki.xiph.o
if(channelCount == 0 or channelCount >2) return ERR_OPUS_NR_OF_CHANNELS_UNSUPPORTED; if(channelCount == 0 or channelCount >2) return ERR_OPUS_NR_OF_CHANNELS_UNSUPPORTED;
m_channels = channelCount; m_channels = channelCount;
if(sampleRate != 48000) return ERR_OPUS_INVALID_SAMPLERATE; if(sampleRate != 48000) return ERR_OPUS_INVALID_SAMPLERATE;
m_samplerate = sampleRate;
if(channelMap > 1) return ERR_OPUS_EXTRA_CHANNELS_UNSUPPORTED; if(channelMap > 1) return ERR_OPUS_EXTRA_CHANNELS_UNSUPPORTED;
(void)outputGain; (void)outputGain;
...@@ -196,6 +206,7 @@ int parseOpusHead(uint8_t *inbuf, int nBytes){ // reference https://wiki.xiph.o ...@@ -196,6 +206,7 @@ int parseOpusHead(uint8_t *inbuf, int nBytes){ // reference https://wiki.xiph.o
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph.org/ogg/doc/rfc3533.txt int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph.org/ogg/doc/rfc3533.txt
f_m_parseOgg = false;
int ret = 0; int ret = 0;
int idx = OPUS_specialIndexOf(inbuf, "OggS", 6); int idx = OPUS_specialIndexOf(inbuf, "OggS", 6);
log_i("idx %i", idx); log_i("idx %i", idx);
...@@ -227,13 +238,16 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph ...@@ -227,13 +238,16 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph
// read the segment table (contains pageSegments bytes), 1...251: Length of the frame in bytes, // read the segment table (contains pageSegments bytes), 1...251: Length of the frame in bytes,
// 255: A second byte is needed. The total length is first_byte + second byte // 255: A second byte is needed. The total length is first_byte + second byte
m_segmentLength = 0;
m_segmentTable.clear(); m_segmentTable.clear();
for(int i = 0; i < pageSegments; i++){ for(int i = 0; i < pageSegments; i++){
if(*(inbuf + 27 + i) < 255) m_segmentTable.push_back(*(inbuf + 27 + i)); int n = *(inbuf + 27 + i);
else{ while(*(inbuf + 27 + i) == 255){
m_segmentTable.push_back(*(inbuf + 27 + i) + (*(inbuf + 27 + i + 1)));
i++; i++;
n+= *(inbuf + 27 + i);
} }
m_segmentTable.insert(m_segmentTable.begin(), n); // use vector as a queue
m_segmentLength += n;
} }
bool continuedPage = headerType & 0x01; // set: page contains data of a packet continued from the previous page bool continuedPage = headerType & 0x01; // set: page contains data of a packet continued from the previous page
...@@ -251,29 +265,39 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph ...@@ -251,29 +265,39 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph
ret = parseOpusComment(inbuf + headerSize, m_segmentTable[0]); ret = parseOpusComment(inbuf + headerSize, m_segmentTable[0]);
if(ret == 1) *bytesLeft -= m_segmentTable[0]; if(ret == 1) *bytesLeft -= m_segmentTable[0];
if(ret < 0){ *bytesLeft -= m_segmentTable[0]; return ret;} if(ret < 0){ *bytesLeft -= m_segmentTable[0]; return ret;}
f_m_parseOgg = true; // goto next page f_m_parseOgg = true;// goto next page
log_i("hier2"); }
else if(m_segmentTable.size() > 0){
if(m_segmentLength /m_segmentTable.size() == 3){
//parseOpusFramePacket();
log_i("special");
*bytesLeft -= m_segmentLength;
f_m_parseOgg = true;
}
else{
f_m_opusFramePacket = true;
}
} }
if(firstPage) f_m_subsequentPage = true; else f_m_subsequentPage = false; if(firstPage) f_m_subsequentPage = true; else f_m_subsequentPage = false;
log_i("headerType %i", headerType);
log_i("firstPage %i", firstPage);
log_i("continuedPage %i", continuedPage);
log_i("lastPage %i", lastPage);
log_i("headerSize %i", headerSize);
log_i("granulePosition %u", granulePosition);
log_i("bitstreamSerialNr %u", bitstreamSerialNr);
log_i("pageSequenceNr %u", pageSequenceNr);
log_i("pageSegments %i", pageSegments);
int sum = 0; // log_i("headerType %i", headerType);
for(int i = 0; i < m_segmentTable.size(); i++){ // log_i("firstPage %i", firstPage);
log_w("segTable %i, sum %i", m_segmentTable[i], sum); // log_i("continuedPage %i", continuedPage);
sum += m_segmentTable[i]; // log_i("lastPage %i", lastPage);
} // log_i("headerSize %i", headerSize);
log_w("sum = %i", sum); // log_i("granulePosition %u", granulePosition);
log_w("f_m_parseOgg %i", f_m_parseOgg); // log_i("bitstreamSerialNr %u", bitstreamSerialNr);
log_i("pageSequenceNr %u", pageSequenceNr);
// log_i("pageSegments %i", pageSegments);
// log_i("m_segmentLength %i", m_segmentLength);
//int sum = 0;
// for(int i = 0; i < m_segmentTable.size(); i++){
// log_w("segTable %i, sum %i", m_segmentTable[i], sum);
// sum += m_segmentTable[i];
// }
// log_w("sum = %i", sum);
return 0; // no error return 0; // no error
} }
...@@ -286,6 +310,7 @@ int OPUSFindSyncWord(unsigned char *buf, int nBytes){ ...@@ -286,6 +310,7 @@ int OPUSFindSyncWord(unsigned char *buf, int nBytes){
f_m_parseOgg = true; f_m_parseOgg = true;
return idx; return idx;
} }
log_i("find sync");
f_m_parseOgg = false; f_m_parseOgg = false;
return -1; return -1;
} }
......
...@@ -31,7 +31,7 @@ int OPUSFindSyncWord(unsigned char *buf, int nBytes); ...@@ -31,7 +31,7 @@ int OPUSFindSyncWord(unsigned char *buf, int nBytes);
int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft); int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft);
int parseOpusHead(uint8_t *inbuf, int nBytes); int parseOpusHead(uint8_t *inbuf, int nBytes);
int parseOpusComment(uint8_t *inbuf, int nBytes); int parseOpusComment(uint8_t *inbuf, int nBytes);
int parseOpusFramePacket(uint8_t *inbuf, int *bytesLeft); int parseOpusFramePacket();
// some helper functions // some helper functions
int OPUS_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false); int OPUS_specialIndexOf(uint8_t* base, const char* str, int baselen, bool exact = false);
\ No newline at end of file
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