OSDN Git Service

implemente speex master
authorBreak <t_windbreak@yahoo.co.jp>
Mon, 5 Jul 2010 08:40:50 +0000 (17:40 +0900)
committerBreak <t_windbreak@yahoo.co.jp>
Mon, 5 Jul 2010 08:40:50 +0000 (17:40 +0900)
add wave buffer, because input buffer and output buffer
when input callback, encode and decode a voice

source/CInputWave.cpp
source/COutputWave.cpp
source/main.cpp
win7/internetcity_test/internetcity_test.vcxproj

index b252ce6..21e93f1 100644 (file)
@@ -65,7 +65,7 @@ void CInputWave::callbackWave(HWAVEIN in_hWaveIn, UINT in_Message, DWORD in_Inst
 
        // \83f\83o\83C\83X\82ª\81AwaveInAddBuffer \8aÖ\90\94\82Å\91\97\90M\82³\82ê\82½\83f\81[\83^\83u\83\8d\83b\83N\82Ì\8f\88\97\9d\82ð\8fI\97¹\82µ\82½\82Æ\82«\82É\91\97\90M\82³\82ê\82Ü\82·\81B
        case WIM_DATA:
-               //std::cout << "WIM_DATA" << std::endl;
+               std::cout << "WIM_DATA" << std::endl;
                // \98^\89¹\83t\83\89\83O\82ª\97§\82Á\82Ä\82¢\82é\8fê\8d\87\82Í\83o\83b\83t\83@\82ð\89Á\82¦\82é
                m_NumberOfBufferInQueue--;
                // \83w\83b\83_\81[\8cã\8f\88\97\9d
index de7ac00..f0fe3d6 100644 (file)
@@ -66,7 +66,7 @@ void COutputWave::callbackWave(HWAVEOUT in_hWaveOut, UINT in_Message, DWORD in_I
 
        // \83f\83o\83C\83X\83h\83\89\83C\83o\82ª\81AwaveOutWrite \8aÖ\90\94\82Å\91\97\90M\82³\82ê\82½\83f\81[\83^\83u\83\8d\83b\83N\82Ì\8f\88\97\9d\82ð\8fI\97¹\82µ\82½\82Æ\82«\82É\91\97\90M\82³\82ê\82Ü\82·\81B
        case WOM_DONE:
-               //std::cout << "WOM_DATA" << std::endl;
+               std::cout << "WOM_DATA" << std::endl;
                // \8dÄ\90\83t\83\89\83O\82ª\97§\82Á\82Ä\82¢\82é\8fê\8d\87\82Í\83o\83b\83t\83@\82ð\89Á\82¦\82é
                m_NumberOfBufferInQueue--;
                // \83w\83b\83_\81[\8cã\8f\88\97\9d
index c6151dc..075de60 100644 (file)
 //#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
 {
@@ -70,7 +88,8 @@ const int KEY_LEFT_BIT  = 1 << 3;
 int isBeep = 0;
 
 
-CWaveData g_WaveData;
+CWaveData g_WaveData1; // \93ü\97Í\97p
+CWaveData g_WaveData2; // \8fo\97Í\97p
 CInputWave g_InputWave;
 COutputWave g_OutputWave;
 
@@ -336,23 +355,148 @@ static void DataFullCallBackFunction(WAVEHDR* io_WaveHeader)
                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;
        }
@@ -370,5 +514,8 @@ int main(int argc, char* argv[])
        glutReshapeFunc(reshape);
        init();
        glutMainLoop();
+
+       uninitSpeex();
+
        return 0;
 }
index ecad108..ffd6be8 100644 (file)
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>..\..\..\speex-1.2beta3-win32\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>..\..\..\speex-1.2beta3-win32\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">