Hi, Sorry! Marc Gimpel. I wrote it in a false thread before. It was my first time. :-) I have to write a small programm which should be able to record speeches and in addition synchronize the recorded speeches with measuring data. My idea is to record the speech in the normal way with speex and without ogg. If a sync message was received, i write a custom in-band messages using mode 13 into the stream. Furthermore, i fill a structure with the sync data and write the structure into an array. To determine the position of the sync structure in the array, i have to write the array index of the sync structure into the stream. Inside the user callback i have to read the array index of the reached sync point from the stream and send it within a notification message to the application. The Problem is, after the decoder reached the custom in-band messages and executed the user callback, the stream is corrupted and speex_decode() returns -2. I don't know where the problem is. I can't find any sample code for custom in-band messages. Is there anyone who can help? Here some sample code: /********************************** encoder *********************************************/ // read raw data from serving buffer void CSpeexEncoderThread::Decode(char * pcData, DWORD dwLength){ ... speex_encode(st, s, &bits); // encode ... if (syncmsg == TRUE && synccount < 256){ // is there a sync message? syncstruct[synccount].sync_value = syncvalue; //fill the sync structure ... speex_bits_pack(&bits, 13, 5); //custom in-band messages // write the array index of the sync structure into the stream (max. 256 sync points) speex_bits_pack(&bits, synccount, 8); synccount++ } nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES); ... // write the encoded data into the end buffer ... speex_bits_reset(&bits); ... } /********************************** encoder end ********************************************/ /************************************* decoder *********************************************/ int CSpeexDecoderThread::SpeexUserCallback(SpeexBits *bits, void *state, void *data){ ... // read the array index of the corresponding sync structure int index = speex_bits_unpack_unsigned(bits, 8); SendNotifyMessage(l_sdthread->m_hWnd, USER_PLAYBACK_MESSAGE, SYNC_DATA, LPARAM(index)); return 0; } inline int speex_bits_init_buffer_ex(SpeexBits *bits, void *buff, int buf_size){ if (buff == NULL || buf_size == 0) return -1; memset(bits, 0, sizeof(SpeexBits)); bits->bytes = (char*)buff; bits->buf_size = buf_size; bits->nbBits=buf_size << 3; return 0; } int CSpeexDecoderThread::DecodePlay(void* state, SpeexStereoState stereo, char* pcData, DWORD dwLength, int nchannels, int frame_size, int ynccount){ ... if (synccount > 0){ callback.callback_id = 0; callback.func = SpeexUserCallback; callback.data = this; speex_decoder_ctl(state, SPEEX_SET_USER_HANDLER, &callback); } ... speex_bits_init_buffer_ex(&bits, pcData, dwLength); while (1 == 1){ ... retval = speex_decode(state, &bits, output); if (retval == -1){ return -1; //return DECODE_ENDOFSTREAM; } else if (retval == -2){ return -2; } ... // play the sample } } The second question, is there something wrong with the speex_uwb_mode since version 1.1? It don't work. Only speex_nb_mode and speex_wb_mode works. Norman ps: sorry for my pure english. <p>--- >8 ---- List archives: http://www.xiph.org/archives/ Ogg project homepage: http://www.xiph.org/ogg/ To unsubscribe from this list, send a message to 'speex-dev-request@xiph.org' containing only the word 'unsubscribe' in the body. No subject is needed. Unsubscribe messages sent to the list will be ignored/filtered.
Hi, I think what happened is that you did not write the "message" length. With user-callbacks, you also need to say how large the message. The size is in bytes and encoded in 4 bits. Besides, you're probably the first one to use user-callbacks. BTW, why didn't you want to use Ogg. It's much simpler to use and overhead can be made minimal anyway. Jean-Marc Le ven 07/11/2003 à 11:17, Norman Biehl a écrit :> Hi, > > Sorry! Marc Gimpel. I wrote it in a false thread before. It was my > first time. J > > > > I have to write a small programm which should be able to record > speeches > and in addition synchronize the recorded speeches with measuring data. > > My idea is to record the speech in the normal way with speex and > without > ogg. If a sync message was received, i write a custom in-band messages > using mode 13 into the stream. Furthermore, i fill a structure with > the > sync data and write the structure into an array. To determine the > position > of the sync structure in the array, i have to write the array index of > the > sync structure into the stream. Inside the user callback i have to > read > the array index of the reached sync point from the stream and send it > within a notification message to the application. > > The Problem is, after the decoder reached the custom in-band messages > and > executed the user callback, the stream is corrupted and speex_decode() > returns -2. > > I don't know where the problem is. > > I can't find any sample code for custom in-band messages. > > Is there anyone who can help? > > Here some sample code: > > /********************************** encoder > *********************************************/ > > // read raw data from serving buffer > void CSpeexEncoderThread::Decode(char * pcData, DWORD dwLength){ > > ... > > speex_encode(st, s, &bits); // encode > > ... > > if (syncmsg == TRUE && synccount < 256){ // is there a sync > message? > > syncstruct[synccount].sync_value = syncvalue; //fill > the sync structure > > ... > > speex_bits_pack(&bits, 13, 5); //custom in-band > messages > > // write the array index of the sync structure into > the stream (max. 256 > sync points) > speex_bits_pack(&bits, synccount, 8); > > synccount++ > } > > nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES); > > ... > > // write the encoded data into the end buffer > > ... > > speex_bits_reset(&bits); > > ... > } > /********************************** encoder end > ********************************************/ > > /************************************* decoder > *********************************************/ > > int CSpeexDecoderThread::SpeexUserCallback(SpeexBits *bits, void > *state, > void *data){ > ... > > // read the array index of the corresponding sync structure > int index = speex_bits_unpack_unsigned(bits, 8); > > SendNotifyMessage(l_sdthread->m_hWnd, USER_PLAYBACK_MESSAGE, > SYNC_DATA, > LPARAM(index)); > > return 0; > } > > inline int speex_bits_init_buffer_ex(SpeexBits *bits, void *buff, int > buf_size){ > > if (buff == NULL || buf_size == 0) > return -1; > > memset(bits, 0, sizeof(SpeexBits)); > > bits->bytes = (char*)buff; > bits->buf_size = buf_size; > bits->nbBits=buf_size << 3; > > return 0; > } > > int CSpeexDecoderThread::DecodePlay(void* state, SpeexStereoState > stereo, > char* pcData, DWORD dwLength, int nchannels, int frame_size, > int > synccount){ > > ... > > if (synccount > 0){ > callback.callback_id = 0; > callback.func = SpeexUserCallback; > callback.data = this; > speex_decoder_ctl(state, SPEEX_SET_USER_HANDLER, > &callback); > } > ... > > speex_bits_init_buffer_ex(&bits, pcData, dwLength); > > while (1 == 1){ > > ... > > retval = speex_decode(state, &bits, output); > > if (retval == -1){ > return -1; //return DECODE_ENDOFSTREAM; > } else if (retval == -2){ > return -2; > } > ... > > // play the sample > } > } > > The second question, is there something wrong with the speex_uwb_mode > since version 1.1? > It don't work. Only speex_nb_mode and speex_wb_mode works. > > Norman > > ps: sorry for my pure english. > >-- Jean-Marc Valin, M.Sc.A., ing. jr. LABORIUS (http://www.gel.usherb.ca/laborius) Université de Sherbrooke, Québec, Canada -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 190 bytes Desc: Ceci est une partie de message numériquement signée Url : http://lists.xiph.org/pipermail/speex-dev/attachments/20031107/afe7b87f/signature-0001.pgp
Jean-Marc wrote:>I think what happened is that you did not write the "message" length. >With user-callbacks, you also need to say how large the message. The >size is in bytes and encoded in 4 bits.I wonder what is correct. Inside speex the documentation was written that the size in byte is encoded within 5 bit. I changed the code in both ways, but it doesn't work anytime. It's the same problem. See below.>Besides, you're probably the first one to use user-callbacks.Oh, I feel honoured. :-) Why does it contain this feature if nobody uses it? I think it's a good and very flexible feature (if it works :-)).>BTW, why >didn't you want to use Ogg. It's much simpler to use and overhead canbe>made minimal anyway.At first there is no need for ogg, the programm is only for encoding voice in a test environment. And if the user in-band callback mechanism works it is more then enough. <p><p>void CSpeexEncoderThread::Decode(char * pcData, DWORD dwLength){ ... speex_encode(st, s, &bits); // encode if (syncmsg == TRUE && synccount < 256){ // is there a sync message? syncstruct[synccount].sync_value = syncvalue; //fill the sync structure ... //custom in-band messages speex_bits_pack(&bits, 13, 5); // write the length of the message speex_bits_pack(&bits, 1, 4); // write the array index of the sync structure into the stream (max. 256 sync points) speex_bits_pack(&bits, synccount, 8); synccount++ } nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES); ... // write the encoded data into the end buffer ... speex_bits_reset(&bits); ... } int CSpeexDecoderThread::SpeexUserCallback(SpeexBits *bits, void *state, void *data){ int length = speex_bits_unpack_unsigned(bits, 4); int inedx = speex_bits_unpack_unsigned(bits, length * 8); <p> SendNotifyMessage(l_sdthread->m_hWnd, USER_PLAYBACK_MESSAGE, SYNC_DATA, LPARAM(index)); return 0; } <p><p><p><p><p><p><p><p>--- >8 ---- List archives: http://www.xiph.org/archives/ Ogg project homepage: http://www.xiph.org/ogg/ To unsubscribe from this list, send a message to 'speex-dev-request@xiph.org' containing only the word 'unsubscribe' in the body. No subject is needed. Unsubscribe messages sent to the list will be ignored/filtered.