//#include <GL/glut.h>
#include "glut.h"
+
+#include <speex/speex.h>
+#pragma comment(lib, "libspeex.lib")
+#pragma comment(lib, "libspeexdsp.lib")
+/* BEGIN: You probably don't need the following in a real application */
+#include <speex/speex_callbacks.h>
+SpeexCallback callback;
+/* END of unnecessary stuff */
+
+void *st;
+void *dec;
+spx_int32_t skip_group_delay;
+SpeexBits bits;
+#define FRAME_SIZE 160
+
+
+
#ifndef M_PI
#define M_PI 3.14159265357989
#endif // M_PI
+
// \83A\83o\83^\81[\82Ì\8fî\95ñ
struct AvatarInformation
{
int isBeep = 0;
-CWaveData g_WaveData;
+CWaveData g_WaveData1; // \93ü\97Í\97p
+CWaveData g_WaveData2; // \8fo\97Í\97p
CInputWave g_InputWave;
COutputWave g_OutputWave;
char* p = &io_WaveHeader->lpData[i];
*p = static_cast<unsigned char>((static_cast<unsigned char>(*p) - 128) * a_AttenuationOfTheta * a_AttenuationOfLength) + 128;
}
+
+ // \88ê\8e\9e\83o\83b\83t\83@
+ short in_short[FRAME_SIZE];
+ short out_short[FRAME_SIZE];
+
+ // \83R\83s\81[\8f\80\94õ
+ char* p1 = g_WaveData1.getReadBuffer();
+ char* p2 = g_WaveData2.getWriteBuffer();
+ char* p1_end = p1 + g_WaveData1.getReadBufferSize();
+ char* p2_end = p2 + g_WaveData2.getWriteBufferSize();
+
+ int bitCount = 0;
+ while(true){
+ if(p1 + FRAME_SIZE > p1_end || p2 + FRAME_SIZE > p2_end){
+ break;
+ }
+
+ speex_bits_reset(&bits);
+
+ // char\8c^\82Íint\8c^\82É\8c^\95Ï\8a·\82µ\82Ä\82¨\82
+ // 16kHz\82ð\8eg\97p\82µ\82½\82Ù\82¤\82ª\8cø\97¦\82ª\82¢\82¢\82©\82à
+
+ // Convert 8 -> 16 bits
+ for(int i = 0; i < FRAME_SIZE; i++){
+ // \97Ê\8eq\89»\83r\83b\83g\90\94\82ª8\83r\83b\83g\82Ì\8fê\8d\87\82Í\81A0\81`255 \82Ì\94Í\88Í\82Å\90U\95\9d\92l\82ð\95\\8c»\82µ\82Ü\82·\81B128 \82ª\92\86\90S(\90U\95\9d\82È\82µ)\82Å\82·\81B
+ // 16\83r\83b\83g\82Ì\8fê\8d\87\82Í\81A-32768\81`32767 \82Ì\94Í\88Í\82Å\90U\95\9d\92l\82ð\95\\8c»\82µ\82Ü\82·\81B0 \82ª\92\86\90S(\90U\95\9d\82È\82µ)\82Å\82·\81B
+ in_short[i] = (*(p1 + i) << 8) ^ 0x8000;
+ }
+ // \88³\8fk
+ speex_encode_int(st, in_short, &bits);
+
+ char cbits[200];
+ int nbBits = speex_bits_write(&bits, cbits, 200);
+ bitCount += bits.nbBits;
+
+ speex_bits_rewind(&bits);
+
+ // \89ð\93\80
+ speex_decode_int(dec, &bits, out_short);
+
+ speex_bits_reset(&bits);
+
+ for(int i = 0; i < FRAME_SIZE; i++){
+ *(p2 + i) = (out_short[i] ^ 0x8000) >> 8;
+ }
+
+ p1 += FRAME_SIZE;
+ p2 += FRAME_SIZE;
+ }
+ g_WaveData1.nextReadBuffer();
+ g_WaveData2.nextWriteBuffer();
+}
+
+int initSpeex()
+{
+ st = speex_encoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
+ dec = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_NB));
+
+ /* BEGIN: You probably don't need the following in a real application */
+ callback.callback_id = SPEEX_INBAND_CHAR;
+ callback.func = speex_std_char_handler;
+ callback.data = stderr;
+ speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+ callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+ callback.func = speex_std_mode_request_handler;
+ callback.data = st;
+ speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+ /* END of unnecessary stuff */
+
+ spx_int32_t tmp;
+ tmp=1;
+ speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
+ tmp=0;
+ speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
+ tmp=8;
+ speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+ /*
+ tmp=1;
+ speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
+ */
+ tmp = 8000;
+ //speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &tmp);
+ //speex_decoder_ctl(dec, SPEEX_SET_SAMPLING_RATE, &tmp);
+ //tmp = 8000;
+ //speex_encoder_ctl(st, SPEEX_SET_BITRATE, &tmp);
+
+ spx_int32_t frame_size;
+ speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
+
+ /* Turn this off if you want to measure SNR (on by default) */
+ /*
+ tmp=1;
+ speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &tmp);
+ speex_decoder_ctl(dec, SPEEX_SET_HIGHPASS, &tmp);
+ */
+
+ speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &skip_group_delay);
+ speex_decoder_ctl(dec, SPEEX_GET_LOOKAHEAD, &tmp);
+ skip_group_delay += tmp;
+
+ speex_bits_init(&bits);
+
+
+ return true;
+}
+
+void uninitSpeex()
+{
+ speex_encoder_destroy(st);
+ speex_decoder_destroy(dec);
+ speex_bits_destroy(&bits);
}
int main(int argc, char* argv[])
{
- g_WaveData.initialize();
+
+ initSpeex();
+
+ g_WaveData1.initialize();
+ g_WaveData2.initialize();
// \83o\83b\83t\83@\83T\83C\83Y1000\81A\98^\89¹\8e\9e\8aÔ100ms
- g_WaveData.allocBuffer(1000, 100);
+ g_WaveData1.allocBuffer(1000, 1600);
+ g_WaveData2.allocBuffer(1000, 1600);
+
+ // \8c»\8fóbuffer_size\82ª160\82Ì\94{\90\94\82Å\82È\82¯\82ê\82Î\81A\88³\8fk\82Ì\8aÖ\8cW\8fã\82»\82Ì\8aÔ\82É\83m\83C\83Y\82ª\93ü\82é
+ // buffer_size = 22050 * bitrate / 8 * channel * time / 1000;
+ // buffer_size \82ª160\82Ì\94{\90\94
+
+ // \88ê\94Ê\93I\82É\82Í\83o\83b\83t\83@\82Í\98A\91±\82µ\82Ä\82¢\82é\82½\82ß\81A\8dD\82«\82È\88Ê\92u\82Å\90Ø\82é\82±\82Æ\82ª\89Â\94\\82¾\82ª\81A\8c»\8fó\82Ì
+ // \8dì\82è\82Å\82Í\83o\83b\83t\83@\82ð\83\8a\83\93\83O\83o\83b\83t\83@\82Æ\82µ\82Ä\95ª\8a\84\82µ\82Ä\82¢\82é\82½\82ß\81A\8dD\82«\82È\88Ê\92u\82Å\90Ø\82é\82±\82Æ\82ª\82Å\82«\82È\82¢\81B
+ // \82æ\82Á\82Ä\81A\8d¡\8cã\82Í\83o\83b\83t\83@\82ð\8dD\82«\82È\8aÔ\8au\82Å\90Ø\82é\82±\82Æ\82ª\89Â\94\\82È\8dì\82è\82É\82·\82é\95K\97v\82ª\82 \82é\81B
g_InputWave.initialize();
- g_InputWave.setWaveData(&g_WaveData);
+ g_InputWave.setWaveData(&g_WaveData1);
g_InputWave.setDataFullCallBack(&DataFullCallBackFunction);
if(!g_InputWave.open()){
return 0;
}
g_OutputWave.initialize();
- g_OutputWave.setWaveData(&g_WaveData);
+ g_OutputWave.setWaveData(&g_WaveData2);
if(!g_OutputWave.open()){
return 0;
}
glutReshapeFunc(reshape);
init();
glutMainLoop();
+
+ uninitSpeex();
+
return 0;
}