Beispiel #1
0
static void * winsnd_thread(void *p){
	MSSndCard *card=(MSSndCard*)p;
	WinSndData *d=(WinSndData*)card->data;
	int bsize=d->rate/8000 * 320;
	uint8_t *rtmpbuff=NULL;
	uint8_t *wtmpbuff=NULL;
	int err;

	MMRESULT mr = NOERROR;
    int pos_whdr=0;

	d->stat_input=0;
	d->stat_output=0;
	d->stat_notplayed=0;
	d->sound_err=winsnd_open(d, d->devid, d->bits,d->stereo,d->rate,&bsize);
	if (d->sound_err==0){
		rtmpbuff=(uint8_t*)alloca(bsize);
		wtmpbuff=(uint8_t*)alloca(bsize);
	}
	while(d->read_started || d->write_started){
		if (d->sound_err==0){
			if (d->write_started){
#if 0
                if (d->stat_output>0 && d->buffer_playing==0)
				{
                    ms_error("No data currently playing in sound card" );
				}
				if (d->stat_output>0 && (d->stat_input-d->stat_output>10 || d->stat_input-d->stat_output<-10))
                    ms_error("Not perfectly synchronized (input-output=%i)", d->stat_input-d->stat_output);
#endif

				while (d->buffer_playing<6 && d->buffer_playing<MAX_WAVEHDR)
				{
					ms_mutex_lock(&d->mutex);
				    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);
					ms_mutex_unlock(&d->mutex);
				    if (err!=bsize)
						break;

					ms_mutex_lock(&d->mutex);
                    /* write to sound devide! */
                    memcpy (d->waveouthdr[pos_whdr].lpData, wtmpbuff, bsize);

                    mr = waveOutWrite (d->waveoutdev,
                        &(d->waveouthdr[pos_whdr]),
                        sizeof (d->waveouthdr[pos_whdr]));

                    if (mr != MMSYSERR_NOERROR)
                    {
                        if (mr == WAVERR_STILLPLAYING)
                        {
                            /* retry later */
                            /* data should go back to queue */
                            /* TODO */
                            ms_warning("sound device write STILL_PLAYING (waveOutWrite:0x%i)", mr);
                        }
                        else
                        {
                            ms_warning("sound device write returned (waveOutWrite:0x%i)", mr);
                        }
                    }
                    else
                    {
                        d->buffer_playing++;
                        pos_whdr++;
                        if (pos_whdr == MAX_WAVEHDR)
                            pos_whdr = 0;   /* loop over the prepared blocks */
                    }
					ms_mutex_unlock(&d->mutex);


				    if (err<0){
#if !defined(_WIN32_WCE)
					    ms_warning("Fail to write %i bytes from soundcard: %s",
						    bsize,strerror(errno));
#else
					    ms_warning("Fail to write %i bytes from soundcard: %i",
						    bsize,WSAGetLastError());
#endif
				    }
				}

                if (d->buffer_playing==6 || d->buffer_playing==MAX_WAVEHDR)
                {
					int discarded=0;
					ms_mutex_lock(&d->mutex);
					while (d->bufferizer->size>=bsize){
						discarded++;
						d->stat_notplayed++;
					    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);
					}
					ms_mutex_unlock(&d->mutex);
					if (discarded>0)
						ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20*320)/320, d->buffer_playing, d->stat_input - d->stat_output);
				}
#if !defined(_WIN32_WCE)
				Sleep(5);
#endif
#if defined(_WIN32_WCE)
				Sleep(10);
#endif
			}else {
				int discarded=0;
				/* don't think this is usefull, anyway... */
				ms_mutex_lock(&d->mutex);
				while (d->bufferizer->size>=bsize){
					discarded++;
				    err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);
				}
				ms_mutex_unlock(&d->mutex);
				if (discarded>0)
					ms_error("Extra data for sound card removed (%ims), (playing: %i) (input-output: %i)", (discarded*20)/320, d->buffer_playing, d->stat_input - d->stat_output);
			    Sleep(10);
            }
		}else Sleep(10);
	}
	if (d->sound_err==0) {
        int i;
        int count=0;
        /* close sound card */
		ms_error("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->buffer_playing, d->stat_input - d->stat_output, d->stat_notplayed);

        /* unprepare buffer */
        for (i = 0; i < MAX_WAVEHDR; i++)
        {
            int counttry=0;
            for (counttry=0;counttry<10;counttry++)
            {
                mr = waveInUnprepareHeader (d->waveindev,
                                        &(d->waveinhdr[i]),
                                        sizeof (d->waveinhdr[i]));
                if (mr != MMSYSERR_NOERROR)
                {
                    ms_error("Failed to unprepared %i buffer from sound card (waveInUnprepareHeader:0x%i", count, mr);
                    Sleep (20);
                } else
                {
                    count++;
        		    ms_message("successfully unprepared %i buffer from sound card.", count);
                    break;
                }
            }
        }
		ms_warning("unprepared %i buffer from sound card.", count);

        mr = waveInStop (d->waveindev);
        if (mr != MMSYSERR_NOERROR)
        {
        	ms_error("failed to stop recording sound card (waveInStop:0x%i)", mr);
        } else
        {
        	ms_message("successfully stopped recording sound card");
        }

        mr = waveInReset (d->waveindev);
        if (mr != MMSYSERR_NOERROR)
        {
        	ms_warning("failed to reset recording sound card (waveInReset:0x%i)", mr);
        } else
        {
        	ms_message("successful reset of recording sound card");
        }

        mr = waveInClose (d->waveindev);
        if (mr != MMSYSERR_NOERROR)
        {
        	ms_warning("failed to close recording sound card (waveInClose:0x%i)", mr);
        } else
        {
        	ms_message("successfully closed recording sound card");
        }
		d->sound_err=-1;
	}
	d->stat_input=0;
	d->stat_output=0;
	d->stat_notplayed=0;
	return NULL;
}
Beispiel #2
0
long
audio_file_read(Chan *c, void *va, long count, vlong offset)
{
    MMRESULT status;
    long len = av.in.buf * Audio_Max_Buf / Audio_Max_Val;
    char *v = (char *) va;
    char *p;
    long ba, n, chunk, total;


    qlock(&flag_lock);
    WaitForSingleObject(inlock, INFINITE);

    if(waserror()) {
        audioerror(waveInStop(audio_file_in), AUDIOIN,
                   "audio_file_read Stop 1");
        audioerror(waveInReset(audio_file_in), AUDIOIN,
                   "audio_file_read Reset 1");
        audioerror(waveInUnprepareHeader(audio_file_in,
                                         &audio_ping.hdr, sizeof(WAVEHDR)), AUDIOIN,
                   "in unprepare ping");
        audioerror(waveInUnprepareHeader(audio_file_in,
                                         &audio_pong.hdr, sizeof(WAVEHDR)),
                   AUDIOIN, "in unprepare pong");

        audio_ping.sz = 0;
        audio_ping.ptr = &audio_ping.data[0];
        audio_pong.sz = 0;
        audio_pong.ptr = &audio_pong.data[0];

        ping_is_filling = pong_is_filling = 0;
        paddle = Ping;

        qunlock(&flag_lock);
        ReleaseMutex(inlock);

        nexterror();
    }

    if(!(audio_flags & INISOPEN))
        error(Eperm);

    /* check for block alignment */
    ba = av.in.bits * av.in.chan / Bits_Per_Byte;

    if(len < 1 || count % ba)
        error(Ebadarg);

    if(!(audio_flags & INPUTISGOING)) {
        if(audioerror(waveInStart(audio_file_in), AUDIOIN,
                      "in start") == -1)
            error(Eio);

        audio_ping.sz = 0;
        audio_ping.ptr = &audio_ping.data[0];
        audio_ping.hdr.lpData = audio_ping.ptr;
        audio_ping.hdr.dwBufferLength = len;
        audio_ping.hdr.dwUser = Ping;
        audio_ping.hdr.dwFlags = 0;

        status = waveInPrepareHeader(audio_file_in, &audio_ping.hdr,
                                     sizeof(WAVEHDR));

        if (audioerror(status, AUDIOIN, "in prepare header") == -1)
            error(Eio);

        audio_pong.sz = 0;
        audio_pong.ptr = &audio_pong.data[0];
        audio_pong.hdr.lpData = audio_pong.ptr;
        audio_pong.hdr.dwBufferLength = len;
        audio_pong.hdr.dwUser = Pong;
        audio_pong.hdr.dwFlags = 0;

        status = waveInPrepareHeader(audio_file_in, &audio_pong.hdr,
                                     sizeof(WAVEHDR));

        if (audioerror(status, AUDIOIN, "in prepare header") == -1)
            error(Eio);

        status = waveInAddBuffer(audio_file_in, &audio_ping.hdr,
                                 sizeof(WAVEHDR));
        if (audioerror(status, AUDIOIN, "file_read Add Buffer")== -1) {
            waveInUnprepareHeader(audio_file_in, &audio_ping.hdr,
                                  sizeof(WAVEHDR));
            audio_ping.sz = 0;
            audio_ping.ptr = &audio_ping.data[0];
            error(Eio);
        }

        ping_is_filling = 1;
        pong_is_filling = 0;
        paddle = Ping;
        audio_flags |= INPUTISGOING;
    }
    poperror();
    ReleaseMutex(inlock);

    total = 0;

Draining:

    WaitForSingleObject(inlock, INFINITE);
    if(waserror()) {
        audioerror(waveInStop(audio_file_in), AUDIOIN,
                   "audio_file_read Stop 2");
        audioerror(waveInReset(audio_file_in), AUDIOIN,
                   "audio_file_read Reset 2");
        audioerror(waveInUnprepareHeader(audio_file_in,
                                         &audio_ping.hdr, sizeof(WAVEHDR)), AUDIOIN,
                   "in unprepare ping");
        audioerror(waveInUnprepareHeader(audio_file_in,
                                         &audio_pong.hdr, sizeof(WAVEHDR)), AUDIOIN,
                   "in unprepare pong");

        audio_ping.sz = 0;
        audio_ping.ptr = &audio_ping.data[0];
        audio_pong.sz = 0;
        audio_pong.ptr = &audio_pong.data[0];

        audio_flags &= ~INPUTISGOING;

        ReleaseMutex(inlock);
        qunlock(&flag_lock);
        nexterror();
    }

    while((total < count) && ((audio_ping.sz > 0) || (audio_pong.sz > 0))) {
        n  = paddle == Ping ? audio_ping.sz : audio_pong.sz;
        p  = paddle == Ping ? audio_ping.ptr : audio_pong.ptr;

        chunk = min(n, count - total);

        memmove(v+total, p , chunk);

        total += chunk;

        if(paddle == Ping) {
            if(!pong_is_filling) {

                if(audioerror(waveInAddBuffer(audio_file_in,
                                              &audio_pong.hdr, sizeof(WAVEHDR)), AUDIOIN,
                              "draining ping calling add buffer pong") == -1)
                    error(Eio);

                pong_is_filling = 1;
            }

            audio_ping.sz -= chunk;
            if(audio_ping.sz > 0) {
                audio_ping.ptr += chunk;
            } else {
                audio_ping.ptr = &audio_ping.data[0];
                ping_is_filling = 0;
                paddle = Pong;
            }
        } else {
            if(!ping_is_filling) {

                if(audioerror(waveInAddBuffer(audio_file_in,
                                              &audio_ping.hdr, sizeof(WAVEHDR)), AUDIOIN,
                              "draining pong calling add buffer ping") == -1)
                    error(Eio);

                ping_is_filling = 1;
            }

            audio_pong.sz -= chunk;
            if(audio_pong.sz > 0) {
                audio_pong.ptr += chunk;
            } else {
                audio_pong.ptr = &audio_pong.data[0];
                pong_is_filling = 0;
                paddle = Ping;
            }
        }
    }

    poperror();

    ReleaseMutex(inlock);

    if(total == count) {
        qunlock(&flag_lock);
        return count;
    }

Filling:
    WaitForSingleObject(inlock, INFINITE);
    while((audio_ping.sz < 1) && (audio_pong.sz < 1)) {
        ReleaseMutex(inlock);
        sleep(0);
        goto Filling;
    }
    ReleaseMutex(inlock);

    goto Draining;
}
Beispiel #3
0
static void wave_in_test_deviceIn(int device, WAVEFORMATEX *pwfx, DWORD format, DWORD flags,
        WAVEINCAPSA *pcaps)
{
    HWAVEIN win;
    HANDLE hevent = CreateEventW(NULL, FALSE, FALSE, NULL);
    WAVEHDR frag;
    MMRESULT rc;
    DWORD res;
    MMTIME mmt;
    WORD nChannels = pwfx->nChannels;
    WORD wBitsPerSample = pwfx->wBitsPerSample;
    DWORD nSamplesPerSec = pwfx->nSamplesPerSec;

    win=NULL;
    rc=waveInOpen(&win,device,pwfx,(DWORD_PTR)hevent,0,CALLBACK_EVENT|flags);
    /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
    ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
       rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
       rc==MMSYSERR_ALLOCATED ||
       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
       (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
       ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
       (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
       !(pcaps->dwFormats & format)) ||
       (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
       "waveInOpen(%s): format=%dx%2dx%d flags=%x(%s) rc=%s\n",
       dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
       pwfx->nChannels,CALLBACK_EVENT|flags,
       wave_open_flags(CALLBACK_EVENT|flags),wave_in_error(rc));
    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
       (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
        trace(" Reason: The device lists this format as supported in its "
              "capabilities but opening it failed.\n");
    if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
       !(pcaps->dwFormats & format))
        trace("waveInOpen(%s): format=%dx%2dx%d %s rc=%s failed but format "
              "not supported so OK.\n",dev_name(device),pwfx->nSamplesPerSec,
              pwfx->wBitsPerSample,pwfx->nChannels,
              flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
              flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
    if (rc!=MMSYSERR_NOERROR) {
        CloseHandle(hevent);
        return;
    }
    res=WaitForSingleObject(hevent,1000);
    ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for open\n");

    ok(pwfx->nChannels==nChannels &&
       pwfx->wBitsPerSample==wBitsPerSample &&
       pwfx->nSamplesPerSec==nSamplesPerSec,
       "got the wrong format: %dx%2dx%d instead of %dx%2dx%d\n",
       pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
       pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);

    /* Check that the position is 0 at start */
    check_position(device, win, 0, pwfx);

    frag.lpData=HeapAlloc(GetProcessHeap(), 0, pwfx->nAvgBytesPerSec);
    frag.dwBufferLength=pwfx->nAvgBytesPerSec;
    frag.dwBytesRecorded=0;
    frag.dwUser=0;
    frag.dwFlags=0;
    frag.dwLoops=0;
    frag.lpNext=0;

    rc=waveInPrepareHeader(win, &frag, sizeof(frag));
    ok(rc==MMSYSERR_NOERROR, "waveInPrepareHeader(%s): rc=%s\n",
       dev_name(device),wave_in_error(rc));
    ok(frag.dwFlags&WHDR_PREPARED,"waveInPrepareHeader(%s): prepared flag "
       "not set\n",dev_name(device));

    if (winetest_interactive && rc==MMSYSERR_NOERROR) {
        trace("Recording for 1 second at %5dx%2dx%d %s %s\n",
              pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
              get_format_str(pwfx->wFormatTag),
              flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
              flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
        rc=waveInAddBuffer(win, &frag, sizeof(frag));
        ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer(%s): rc=%s\n",
           dev_name(device),wave_in_error(rc));

        /* Check that the position is 0 at start */
        check_position(device, win, 0, pwfx);

        rc=waveInStart(win);
        ok(rc==MMSYSERR_NOERROR,"waveInStart(%s): rc=%s\n",
           dev_name(device),wave_in_error(rc));

        res = WaitForSingleObject(hevent,1200);
        ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for header\n");
        ok(frag.dwFlags&WHDR_DONE,"WHDR_DONE not set in frag.dwFlags\n");
        ok(frag.dwBytesRecorded==pwfx->nAvgBytesPerSec,
           "frag.dwBytesRecorded=%d, should=%d\n",
           frag.dwBytesRecorded,pwfx->nAvgBytesPerSec);

        mmt.wType = TIME_BYTES;
        rc=waveInGetPosition(win, &mmt, sizeof(mmt));
        ok(rc==MMSYSERR_NOERROR,"waveInGetPosition(%s): rc=%s\n",
           dev_name(device),wave_in_error(rc));
        ok(mmt.wType == TIME_BYTES, "doesn't support TIME_BYTES: %u\n", mmt.wType);
        ok(mmt.u.cb == frag.dwBytesRecorded, "Got wrong position: %u\n", mmt.u.cb);

        /* stop playing on error */
        if (res!=WAIT_OBJECT_0) {
            rc=waveInStop(win);
            ok(rc==MMSYSERR_NOERROR,
               "waveInStop(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
        }
    }

    rc=waveInUnprepareHeader(win, &frag, sizeof(frag));
    ok(rc==MMSYSERR_NOERROR,"waveInUnprepareHeader(%s): rc=%s\n",
       dev_name(device),wave_in_error(rc));

    rc=waveInClose(win);
    ok(rc==MMSYSERR_NOERROR,
       "waveInClose(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
    res=WaitForSingleObject(hevent,1000);
    ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for close\n");

    if (winetest_interactive)
    {
        /*
         * Now play back what we recorded
         */
        HWAVEOUT wout;

        trace("Playing back recorded sound\n");
        rc=waveOutOpen(&wout,WAVE_MAPPER,pwfx,(DWORD_PTR)hevent,0,CALLBACK_EVENT);
        ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
           rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
           rc==MMSYSERR_ALLOCATED ||
           ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
            !(pcaps->dwFormats & format)),
           "waveOutOpen(%s) format=%dx%2dx%d flags=%x(%s) rc=%s\n",
           dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
           pwfx->nChannels,CALLBACK_EVENT|flags,
           wave_open_flags(CALLBACK_EVENT),wave_out_error(rc));
        if (rc==MMSYSERR_NOERROR)
        {
            rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
            ok(rc==MMSYSERR_NOERROR,"waveOutPrepareHeader(%s): rc=%s\n",
               dev_name(device),wave_out_error(rc));

            if (rc==MMSYSERR_NOERROR)
            {
                WaitForSingleObject(hevent,INFINITE);
                rc=waveOutWrite(wout, &frag, sizeof(frag));
                ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
                   dev_name(device),wave_out_error(rc));
                WaitForSingleObject(hevent,INFINITE);

                rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
                ok(rc==MMSYSERR_NOERROR,"waveOutUnprepareHeader(%s): rc=%s\n",
                   dev_name(device),wave_out_error(rc));
            }
            rc=waveOutClose(wout);
            ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",
               dev_name(device),wave_out_error(rc));
        }
        else
            trace("Unable to play back the recorded sound\n");
    }

    HeapFree(GetProcessHeap(), 0, frag.lpData);
    CloseHandle(hevent);
}
Beispiel #4
0
///////////////////////////////////////////////
//                                           //
//              メイン関数                   //
//                                           //
///////////////////////////////////////////////
int main(void){
    /////////////////////////////////
    //                             //
    //  リアルタイム入出力用変数   //
    //                             //
    /////////////////////////////////
    char   key;                                                     // スルーと処理音の切替用変数
    int in1;                                                        // 入力バッファ番号
    int out1;                                                       // 出力バッファ番号
    int flag;                                                       // 入出力状態のフラグ
    int n;                                                          // バッファ用の時刻
    short in_buf[NUM_BUF][BUF_SIZE]={0};                            // 入力バッファ
    WAVEHDR in_hdr[NUM_BUF];                                        // 入力バッファのヘッダ
	HWAVEIN in_hdl = 0;                                             // 入力(録音)デバイスのハンドル
    short out_buf[NUM_BUF][BUF_SIZE]={0};                           // 出力バッファ
    WAVEHDR out_hdr[NUM_BUF];                                       // 出力バッファのヘッダ
    HWAVEOUT out_hdl = 0;                                           // 出力(再生)デバイスのハンドル

    WAVEFORMATEX wave_format_ex = {WAVE_FORMAT_PCM,                 // PCM
                                 1,                                 // モノラル
                                 Fs,                                // サンプリング周波数
                                 2*Fs,                              // 1秒あたりの音データサイズ(byte)
                                 2,                                 // 音データの最小単位(2byte)
                                 16,                                // 量子化ビット(16bit)
                                 0                                  // オプション情報のサイズ(0byte)
                                };


//************************************************************************//

    ///////////////////////////////
    //                           //
    //      信号処理用変数       //
    //                           //
    ///////////////////////////////
    int t   = 0;                                                    // 入力の時刻
    int to  = 0;                                                    // 出力の時刻
    int hflg= 0;                                                    // 素通しと処理音の状態フラグ
    int i;                                                          // forループ用変数
    double s[MEM_SIZE+1]={0};                                       // 入力データ格納用変数
    double y[MEM_SIZE+1]={0};                                       // 出力データ格納用変数
    
    long int l;                                                     // FFT用変数
    double   w[FFT_SIZE+1] ={0};                                    // 窓関数
    double   x[FFT_SIZE+1] ={0};                                    // FFTの入力
    double   x1[FFT_SIZE+1]={0};                                    // 半フレームシフト時の入力保持用
    double   z1[FFT_SIZE+1]={0};                                    // ハーフオーバーラップの出力保持用
    double Xphs[FFT_SIZE+1]={0};
    double   Xpow;                                                  // 区間パワー

    ///////////////////////////////
    //                           //
    //       変数の初期設定      //
    //                           //
    ///////////////////////////////

    init();                                                         //ビット反転,乗み係数の計算
    l = 0;                                                          // FFT開始時刻管理
    for(i=0;i<FFT_SIZE;i++){                                        // 窓関数の設定
        w[i]=0.5*(1.0-cos(2.0*M_PI*i/(double)FFT_SIZE));
    }

//************************************************************************//


    ///////////////////////////////////////
    //                                   //
    //    入出力デバイスのオープン       // 
    //                                   //
    ///////////////////////////////////////
    waveInOpen(&in_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL);   // 入力(録音)デバイスオープン
    for (i = 0; i < NUM_BUF; i++){
        memset(&in_hdr[i], 0, sizeof(WAVEHDR));                     // 全入力バッファを初期化
    }
    waveOutOpen(&out_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL); // 出力(再生)デバイスオープン
    waveOutPause(out_hdl);                                          // サウンドデバイスの一時停止
    for (i = 0; i < NUM_BUF; i++){                                  // 全出力バッファを初期化
        memset(&out_hdr[i], 0, sizeof(WAVEHDR));
    }
    ///////////////////////////////////////
    //                                   //
    //    入出力バッファの初期設定       // 
    //                                   //
    ///////////////////////////////////////
    for (i=0;i<NUM_BUF;i++){                                        // バッファの数だけ繰り返し
        out_hdr[i].lpData = (char *)out_buf[i];                     // 出力バッファデータを更新
        out_hdr[i].dwBufferLength = BUF_SIZE * 2;                   // 出力バッファサイズを設定
        out_hdr[i].dwFlags = 0;                                     // 出力フラグのクリア
        waveOutPrepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));// 出力バッファをロック
        waveOutWrite(out_hdl, &out_hdr[i], sizeof(WAVEHDR));        // 出力バッファを出力待ちキューに送信
        in_hdr[i].lpData = (char *)in_buf[i];                       // 入力バッファデータの更新
        in_hdr[i].dwBufferLength = BUF_SIZE * 2;                    // 入力バッファサイズを設定
        in_hdr[i].dwFlags = 0;                                      // 入力フラグのクリア
        waveInPrepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR));   // 入力バッファをロック
        waveInAddBuffer(in_hdl, &in_hdr[i], sizeof(WAVEHDR));       // 入力バッファを入力待ちキューに送信
    }
    waveOutRestart(out_hdl);                                        // 音声出力開始
    waveInStart(in_hdl);                                            // 音声入力開始

    in1  = 0;                                                       // 入力バッファ番号の初期化
    out1 = 0;                                                       // 出力バッファ番号の初期化
    flag = 0;                                                       // 入出力判定フラグを0(入力)とする

    printf("[space]--> Through <=> Processing\n");                  // [space]で処理切り替え
    printf("[Enter]--> End\n");                                     // [Enter]で終了
    printf("Through\n");                                            // 素通しであることを表示


    ///////////////////////////////////
    //                               //
    //        メインループ           //
    //                               //
    ///////////////////////////////////
    while (1){
        //////////////////////////
        //                      //
        //    出力書出し処理    //
        //                      //
        //////////////////////////
        if (flag == 1){                                             // flag=1なら出力状態
            if ((out_hdr[out1].dwFlags & WHDR_DONE) != 0){          // 出力バッファのフラグ情報が0でないなら処理を実行
                for (n = 0; n < BUF_SIZE; n++){                     // 出力をBUF_SIZEサンプル分だけ書き出す
                    to=(to+1)%MEM_SIZE;                             // 出力時刻の更新
                    out_buf[out1][n] = y[to]*32768;                 // 出力データを記録
                }
                waveOutUnprepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR)); // 出力バッファをクリーンアップ
                out_hdr[out1].lpData = (char *)out_buf[out1];       // 出力データを更新
//                out_hdr[out1].dwBufferLength = BUF_SIZE * 2;        // 出力バッファサイズを設定
                out_hdr[out1].dwFlags = 0;                          // 出力バッファのフラグ情報を0にする
                waveOutPrepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));   // 情報を更新し出力バッファを準備
                waveOutWrite(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));// 出力待ちキューに出力バッファデータを送信
                out1=(out1+1)%NUM_BUF;                              // 出力バッファ番号を更新
                flag = 0;                                           // 入出力フラグを flag=0 (入力状態) にする
            }
        }
        //////////////////////////
        //                      //
        //    入力読込み処理    //
        //                      //
        //////////////////////////
        if ((in_hdr[in1].dwFlags & WHDR_DONE) != 0){                // 入力バッファのフラグ情報が0でないなら処理を実行
            waveInUnprepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 録音済みの入力バッファを選択
            for (n = 0; n < BUF_SIZE; n++){                         // BUF_SIZEサンプル分の入力を読込み,処理する
                t=(t+1)%MEM_SIZE;                                   // 入力時刻の更新
                s[t] = in_buf[in1][n]/32768.0;                      // 入力バッファからデータ読み込み (正規化)
                y[t] = s[t];                                        // 出力=入力の素通しをつくる
                if(hflg!=0){                                        // 処理状態フラグが0以外なら信号処理を実行


//************************************************************************//

            ////////////////////////////////////////////////////
            //                                                //
            //              Signal Processing                 //
            //                                                //
            //  現在時刻tの入力 s[t] から出力 y[t] をつくる   //
            //                                                //
            //  ※ tは0からMEM_SIZE-1までをループ             //
            //                                                //
            ////////////////////////////////////////////////////

                    x[l] = x1[l];                                   // FFT_SIZE/2までの入力をx[l]に格納
                    x1[l]= x[FFT_SIZE/2+l]=s[t];                    // FFT_SIZE/2以降の入力をx[l]に格納
                    y[t] = (z[l]+z1[l])/FFT_SIZE;                   // IFFTで得た出力
                    z1[l]= z[FFT_SIZE/2+l];                         // ハーフオーバーラップ用に出力記録

                    if( l>=FFT_SIZE/2){                             // 半フレームごとにFFTを実行
                        Xpow=0;
                        for(i=0;i<FFT_SIZE;i++){
                            xin[i]=x[i]*w[i];                       // 窓関数をかける
                            Xpow  = Xpow+xin[i]*xin[i];             // 区間パワー計算
                        }
                        fft();                                      // FFT
                        ///////////////////////////
                        //                       //
                        //        FFT処理        //
                        //                       //
                        ///////////////////////////
                        for(i=0;i<FFT_SIZE/2;i++){
                            Xphs[i] = 2*M_PI*(double)rand()/RAND_MAX;// 位相スペクトルを一様乱数で設定
                            Xphs[FFT_SIZE-i]=-Xphs[i];              // 奇対称にする
                        }
                        for(i=0;i<FFT_SIZE;i++){
                            Xr[i]=Xpow/4.0*cos(2*M_PI*i/FFT_SIZE+Xphs[i]); //実部の処理.複素分離とオーバーラップのため4で割る
                            Xi[i]=Xpow/4.0*sin(2*M_PI*i/FFT_SIZE+Xphs[i]); //虚部の処理.複素分離とオーバーラップのため4で割る
                        }

                        ifft();                                     // IFFT
                        l=0;
                    }
                    l++;                                            // FFT用の時刻管理

//************************************************************************//

                    y[t]=atan(y[t])/(M_PI/2.0);                     // クリップ防止
                }
            }
            in_hdr[in1].dwFlags = 0;                                // 入力バッファのフラグ情報を0にする
            waveInPrepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR));   // 情報を更新し入力バッファを準備
            waveInAddBuffer(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 入力待ちキューに入力バッファデータを送信
            in1=(in1+1)%NUM_BUF;                                    // 入力バッファの更新
            flag = 1;                                               // 入出力フラグを flag=1 (出力状態)にする
        }

        ////////////////////////////////////////////////////
        //                                                //
        //        キーボード入力に対する処理の設定        //
        //                                                //
        //                                                //
        //  [デフォルト設定]                              //
        //  ・スペースキーで素通しと信号処理を切り替え    //
        //  ・Enterキーでプログラム終了                   //
        //                                                //
        ////////////////////////////////////////////////////
        if (kbhit()){                                               // キーボード入力があったか
            key = getch();                                          // キーのチェック
            if (key == 32){                                         // スペースキーが押されとき
            	hflg=(hflg+1)%2;                                    // 処理フラグ変更
                if(hflg==1) printf("Processing\n");                 // 処理中であることを表示
                else        printf("Through\n");                    // 素通しであることを表示
            }
            if (key == 13){                                         // Enterキーが押されたとき
                waveInStop(in_hdl);                                 // 入力を停止
                for (i = 0; i < NUM_BUF; i++){                      // 全入力バッファのアンロック
                    if ((in_hdr[i].dwFlags & WHDR_PREPARED) != 0){
                        waveInUnprepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR ));
                    }
                }
                waveInClose(in_hdl);                                // 入力(録音)デバイスのクローズ
                waveOutPause(out_hdl);                              // 出力を停止
                for (i = 0; i < NUM_BUF; i++){
                    if ((out_hdr[i].dwFlags & WHDR_PREPARED) != 0){ // 全出力バッファのアンロック
                        waveOutUnprepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));
                    }
                }
                waveOutClose(out_hdl);                              // 出力(再生)デバイスのクローズ
                return 0;
            }
        }
    }                                                               //メインループ終わり
}
Beispiel #5
0
static void WinMMStopCapture(ALCdevice *pDevice)
{
    WinMMData *pData = (WinMMData*)pDevice->ExtraData;
    waveInStop(pData->hWaveHandle.In);
}
Beispiel #6
0
static	DWORD	widStop(WAVEMAPDATA* wim)
{
    TRACE("(%p)\n", wim);

    return waveInStop(wim->u.in.hInnerWave);
}
Beispiel #7
0
int main(void){
    /////////////////////////////////
    //                             //
    //  リアルタイム入出力用変数   //
    //                             //
    /////////////////////////////////
    char   key;                                                     // スルーと処理音の切替用変数
    int in1;                                                        // 入力バッファ番号
    int out1;                                                       // 出力バッファ番号
    int flag;                                                       // 入出力状態のフラグ
    int n;                                                          // バッファ用の時刻
    short in_buf[NUM_BUF][BUF_SIZE]={0};                            // 入力バッファ
    WAVEHDR in_hdr[NUM_BUF];                                        // 入力バッファのヘッダ
	HWAVEIN in_hdl = 0;                                             // 入力(録音)デバイスのハンドル
    short out_buf[NUM_BUF][BUF_SIZE]={0};                           // 出力バッファ
    WAVEHDR out_hdr[NUM_BUF];                                       // 出力バッファのヘッダ
    HWAVEOUT out_hdl = 0;                                           // 出力(再生)デバイスのハンドル

    WAVEFORMATEX wave_format_ex = {WAVE_FORMAT_PCM,                 // PCM
                                 1,                                 // モノラル
                                 Fs,                                // サンプリング周波数
                                 2*Fs,                              // 1秒あたりの音データサイズ(byte)
                                 2,                                 // 音データの最小単位(2byte)
                                 16,                                // 量子化ビット(16bit)
                                 0                                  // オプション情報のサイズ(0byte)
                                };


//************************************************************************//

    ///////////////////////////////
    //                           //
    //      信号処理用変数       //
    //                           //
    ///////////////////////////////
    int t   = 0;                                                    // 入力の時刻
    int to  = 0;                                                    // 出力の時刻
    int hflg= 0;                                                    // 素通しと処理音の状態フラグ
    int i;                                                          // forループ用変数
    double s[MEM_SIZE+1]={0};                                       // 入力データ格納用変数
    double y[MEM_SIZE+1]={0};                                       // 出力データ格納用変数
    
    long int l=0;                                                   // 変調用正弦波の時刻
    int      tau;                                                   // 遅延時間
    double   d,depth, r;                                            // 遅延の深さと周波数

    ///////////////////////////////
    //                           //
    //       変数の初期設定      //
    //                           //
    ///////////////////////////////

    d    = 0.002*Fs;                                                // ビブラートの基本深さ
    depth= 0.002*Fs;                                                // 変化の深さ
    r    = 0.5;                                                     // 周波数

//************************************************************************//


    ///////////////////////////////////////
    //                                   //
    //    入出力デバイスのオープン       // 
    //                                   //
    ///////////////////////////////////////
    waveInOpen(&in_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL);   // 入力(録音)デバイスオープン
    for (i = 0; i < NUM_BUF; i++){
        memset(&in_hdr[i], 0, sizeof(WAVEHDR));                     // 全入力バッファを初期化
    }
    waveOutOpen(&out_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL); // 出力(再生)デバイスオープン
    waveOutPause(out_hdl);                                          // サウンドデバイスの一時停止
    for (i = 0; i < NUM_BUF; i++){                                  // 全出力バッファを初期化
        memset(&out_hdr[i], 0, sizeof(WAVEHDR));
    }
    ///////////////////////////////////////
    //                                   //
    //    入出力バッファの初期設定       // 
    //                                   //
    ///////////////////////////////////////
    for (i=0;i<NUM_BUF;i++){                                        // バッファの数だけ繰り返し
        out_hdr[i].lpData = (char *)out_buf[i];                     // 出力バッファデータを更新
        out_hdr[i].dwBufferLength = BUF_SIZE * 2;                   // 出力バッファサイズを設定
        out_hdr[i].dwFlags = 0;                                     // 出力フラグのクリア
        waveOutPrepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));// 出力バッファをロック
        waveOutWrite(out_hdl, &out_hdr[i], sizeof(WAVEHDR));        // 出力バッファを出力待ちキューに送信
        in_hdr[i].lpData = (char *)in_buf[i];                       // 入力バッファデータの更新
        in_hdr[i].dwBufferLength = BUF_SIZE * 2;                    // 入力バッファサイズを設定
        in_hdr[i].dwFlags = 0;                                      // 入力フラグのクリア
        waveInPrepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR));   // 入力バッファをロック
        waveInAddBuffer(in_hdl, &in_hdr[i], sizeof(WAVEHDR));       // 入力バッファを入力待ちキューに送信
    }
    waveOutRestart(out_hdl);                                        // 音声出力開始
    waveInStart(in_hdl);                                            // 音声入力開始

    in1  = 0;                                                       // 入力バッファ番号の初期化
    out1 = 0;                                                       // 出力バッファ番号の初期化
    flag = 0;                                                       // 入出力判定フラグを0(入力)とする

    printf("[space]--> Through <=> Processing\n");                  // [space]で処理切り替え
    printf("[Enter]--> End\n");                                     // [Enter]で終了
    printf("Through\n");                                            // 素通しであることを表示


    ///////////////////////////////////
    //                               //
    //        メインループ           //
    //                               //
    ///////////////////////////////////
    while (1){
        //////////////////////////
        //                      //
        //    出力書出し処理    //
        //                      //
        //////////////////////////
        if (flag == 1){                                             // flag=1なら出力状態
            if ((out_hdr[out1].dwFlags & WHDR_DONE) != 0){          // 出力バッファのフラグ情報が0でないなら処理を実行
                for (n = 0; n < BUF_SIZE; n++){                     // 出力をBUF_SIZEサンプル分だけ書き出す
                    to=(to+1)%MEM_SIZE;                             // 出力時刻の更新
                    out_buf[out1][n] = y[to]*32768;                 // 出力データを記録
                }
                waveOutUnprepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR)); // 出力バッファをクリーンアップ
                out_hdr[out1].lpData = (char *)out_buf[out1];       // 出力データを更新
//                out_hdr[out1].dwBufferLength = BUF_SIZE * 2;        // 出力バッファサイズを設定
                out_hdr[out1].dwFlags = 0;                          // 出力バッファのフラグ情報を0にする
                waveOutPrepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));   // 情報を更新し出力バッファを準備
                waveOutWrite(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));// 出力待ちキューに出力バッファデータを送信
                out1=(out1+1)%NUM_BUF;                              // 出力バッファ番号を更新
                flag = 0;                                           // 入出力フラグを flag=0 (入力状態) にする
            }
        }
        //////////////////////////
        //                      //
        //    入力読込み処理    //
        //                      //
        //////////////////////////
        if ((in_hdr[in1].dwFlags & WHDR_DONE) != 0){                // 入力バッファのフラグ情報が0でないなら処理を実行
            waveInUnprepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 録音済みの入力バッファを選択
            for (n = 0; n < BUF_SIZE; n++){                         // BUF_SIZEサンプル分の入力を読込み,処理する
                t=(t+1)%MEM_SIZE;                                   // 入力時刻の更新
                s[t] = in_buf[in1][n]/32768.0;                      // 入力バッファからデータ読み込み (正規化)
                y[t] = s[t];                                        // 出力=入力の素通しをつくる
                if(hflg!=0){                                        // 処理状態フラグが0以外なら信号処理を実行


//************************************************************************//

            ////////////////////////////////////////////////////
            //                                                //
            //              Signal Processing                 //
            //                                                //
            //  現在時刻tの入力 s[t] から出力 y[t] をつくる   //
            //                                                //
            //  ※ tは0からMEM_SIZE-1までをループ             //
            //                                                //
            ////////////////////////////////////////////////////

                    tau  = d + depth*sin(2.0*M_PI*r*l/(double)Fs);  // 遅延時間の設定
                    y[t] = s[t]+s[(t-tau+MEM_SIZE)%MEM_SIZE];       // 遅延信号と現在の信号を加算
                    l    = (l+1)%(10*Fs);                           // 変調用正弦波の時刻管理

//************************************************************************//

                    y[t]=atan(y[t])/(M_PI/2.0);                     // クリップ防止
                }
            }
            in_hdr[in1].dwFlags = 0;                                // 入力バッファのフラグ情報を0にする
            waveInPrepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR));   // 情報を更新し入力バッファを準備
            waveInAddBuffer(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 入力待ちキューに入力バッファデータを送信
            in1=(in1+1)%NUM_BUF;                                    // 入力バッファの更新
            flag = 1;                                               // 入出力フラグを flag=1 (出力状態)にする
        }

        ////////////////////////////////////////////////////
        //                                                //
        //        キーボード入力に対する処理の設定        //
        //                                                //
        //                                                //
        //  [デフォルト設定]                              //
        //  ・スペースキーで素通しと信号処理を切り替え    //
        //  ・Enterキーでプログラム終了                   //
        //                                                //
        ////////////////////////////////////////////////////
        if (kbhit()){                                               // キーボード入力があったか
            key = getch();                                          // キーのチェック
            if (key == 32){                                         // スペースキーが押されとき
            	hflg=(hflg+1)%2;                                    // 処理フラグ変更
                if(hflg==1) printf("Processing\n");                 // 処理中であることを表示
                else        printf("Through\n");                    // 素通しであることを表示
            }
            if (key == 13){                                         // Enterキーが押されたとき
                waveInStop(in_hdl);                                 // 入力を停止
                for (i = 0; i < NUM_BUF; i++){                      // 全入力バッファのアンロック
                    if ((in_hdr[i].dwFlags & WHDR_PREPARED) != 0){
                        waveInUnprepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR ));
                    }
                }
                waveInClose(in_hdl);                                // 入力(録音)デバイスのクローズ
                waveOutPause(out_hdl);                              // 出力を停止
                for (i = 0; i < NUM_BUF; i++){
                    if ((out_hdr[i].dwFlags & WHDR_PREPARED) != 0){ // 全出力バッファのアンロック
                        waveOutUnprepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));
                    }
                }
                waveOutClose(out_hdl);                              // 出力(再生)デバイスのクローズ
                return 0;
            }
        }
    }                                                               //メインループ終わり
}
Beispiel #8
0
int main(void){
    /////////////////////////////////
    //                             //
    //  リアルタイム入出力用変数   //
    //                             //
    /////////////////////////////////
    char   key;                                                     // スルーと処理音の切替用変数
    int in1;                                                        // 入力バッファ番号
    int out1;                                                       // 出力バッファ番号
    int flag;                                                       // 入出力状態のフラグ
    int n;                                                          // バッファ用の時刻
    short in_buf[NUM_BUF][BUF_SIZE]={0};                            // 入力バッファ
    WAVEHDR in_hdr[NUM_BUF];                                        // 入力バッファのヘッダ
	HWAVEIN in_hdl = 0;                                             // 入力(録音)デバイスのハンドル
    short out_buf[NUM_BUF][BUF_SIZE]={0};                           // 出力バッファ
    WAVEHDR out_hdr[NUM_BUF];                                       // 出力バッファのヘッダ
    HWAVEOUT out_hdl = 0;                                           // 出力(再生)デバイスのハンドル

    WAVEFORMATEX wave_format_ex = {WAVE_FORMAT_PCM,                 // PCM
                                 1,                                 // モノラル
                                 Fs,                                // サンプリング周波数
                                 2*Fs,                              // 1秒あたりの音データサイズ(byte)
                                 2,                                 // 音データの最小単位(2byte)
                                 16,                                // 量子化ビット(16bit)
                                 0                                  // オプション情報のサイズ(0byte)
                                };


//************************************************************************//

    ///////////////////////////////
    //                           //
    //      信号処理用変数       //
    //                           //
    ///////////////////////////////
    int t   = 0;                                                    // 入力の時刻
    int to  = 0;                                                    // 出力の時刻
    int hflg= 0;                                                    // 素通しと処理音の状態フラグ
    int i;                                                          // forループ用変数
    double s[MEM_SIZE+1]={0};                                       // 入力データ格納用変数
    double y[MEM_SIZE+1]={0};                                       // 出力データ格納用変数

    double   rho[P+1]={0}, delta[P+1]={0}, sigma[P+1]={0};          // AR係数推定
    double   h[P+1]={0}, r[N+1]={0}, a[P+1][P+1]={0};               // 自己相関関数
    int      l, m, tau;                                             // 繰り返し計算管理用
    double   rs[MEM_SIZE+1]={0};                                    // 合成信号
    double   rmax;                                                  // ピッチ抽出用
    int      pitch;                                                 // ピッチ
    double   e[N+1]={0};                                            // 予測誤差
    double   k, alpha;                                              // ピッチ変更用の変数

    ///////////////////////////////
    //                           //
    //      変数の初期設定       //
    //                           //
    ///////////////////////////////

    h[0]  = 1.0;                                                    // 線形予測係数h[0]=1
    alpha = 2.0;                                                    // 高さを何倍にするか
    k     = 0;                                                      // 出力時刻管理

//************************************************************************//

    ///////////////////////////////////////
    //                                   //
    //    入出力デバイスのオープン       // 
    //                                   //
    ///////////////////////////////////////
    waveInOpen(&in_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL);   // 入力(録音)デバイスオープン
    for (i = 0; i < NUM_BUF; i++){
        memset(&in_hdr[i], 0, sizeof(WAVEHDR));                     // 全入力バッファを初期化
    }
    waveOutOpen(&out_hdl, 0, &wave_format_ex, 0, 0, CALLBACK_NULL); // 出力(再生)デバイスオープン
    waveOutPause(out_hdl);                                          // サウンドデバイスの一時停止
    for (i = 0; i < NUM_BUF; i++){                                  // 全出力バッファを初期化
        memset(&out_hdr[i], 0, sizeof(WAVEHDR));
    }
    ///////////////////////////////////////
    //                                   //
    //    入出力バッファの初期設定       // 
    //                                   //
    ///////////////////////////////////////
    for (i=0;i<NUM_BUF;i++){                                        // バッファの数だけ繰り返し
        out_hdr[i].lpData = (char *)out_buf[i];                     // 出力バッファデータを更新
        out_hdr[i].dwBufferLength = BUF_SIZE * 2;                   // 出力バッファサイズを設定
        out_hdr[i].dwFlags = 0;                                     // 出力フラグのクリア
        waveOutPrepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));// 出力バッファをロック
        waveOutWrite(out_hdl, &out_hdr[i], sizeof(WAVEHDR));        // 出力バッファを出力待ちキューに送信
        in_hdr[i].lpData = (char *)in_buf[i];                       // 入力バッファデータの更新
        in_hdr[i].dwBufferLength = BUF_SIZE * 2;                    // 入力バッファサイズを設定
        in_hdr[i].dwFlags = 0;                                      // 入力フラグのクリア
        waveInPrepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR));   // 入力バッファをロック
        waveInAddBuffer(in_hdl, &in_hdr[i], sizeof(WAVEHDR));       // 入力バッファを入力待ちキューに送信
    }
    waveOutRestart(out_hdl);                                        // 音声出力開始
    waveInStart(in_hdl);                                            // 音声入力開始

    in1  = 0;                                                       // 入力バッファ番号の初期化
    out1 = 0;                                                       // 出力バッファ番号の初期化
    flag = 0;                                                       // 入出力判定フラグを0(入力)とする

    printf("[space]--> Through <=> Processing\n");                  // [space]で処理切り替え
    printf("[Enter]--> End\n");                                     // [Enter]で終了
    printf("Through\n");                                            // 素通しであることを表示

    ///////////////////////////////////
    //                               //
    //        メインループ           //
    //                               //
    ///////////////////////////////////
    while (1){
        //////////////////////////
        //                      //
        //    出力書出し処理    //
        //                      //
        //////////////////////////
        if (flag == 1){                                             // flag=1なら出力状態
            if ((out_hdr[out1].dwFlags & WHDR_DONE) != 0){          // 出力バッファのフラグ情報が0でないなら処理を実行
                for (n = 0; n < BUF_SIZE; n++){                     // 出力をBUF_SIZEサンプル分だけ書き出す
                    to=(to+1)%MEM_SIZE;                             // 出力時刻の更新
                    out_buf[out1][n] = y[to]*32768;                 // 出力データを記録
                }
                waveOutUnprepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR)); // 出力バッファをクリーンアップ
                out_hdr[out1].lpData = (char *)out_buf[out1];       // 出力データを更新
//                out_hdr[out1].dwBufferLength = BUF_SIZE * 2;        // 出力バッファサイズを設定
                out_hdr[out1].dwFlags = 0;                          // 出力バッファのフラグ情報を0にする
                waveOutPrepareHeader(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));   // 情報を更新し出力バッファを準備
                waveOutWrite(out_hdl, &out_hdr[out1], sizeof(WAVEHDR));// 出力待ちキューに出力バッファデータを送信
                out1=(out1+1)%NUM_BUF;                              // 出力バッファ番号を更新
                flag = 0;                                           // 入出力フラグを flag=0 (入力状態) にする
            }
        }
        //////////////////////////
        //                      //
        //    入力読込み処理    //
        //                      //
        //////////////////////////
        if ((in_hdr[in1].dwFlags & WHDR_DONE) != 0){                // 入力バッファのフラグ情報が0でないなら処理を実行
            waveInUnprepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 録音済みの入力バッファを選択
            for (n = 0; n < BUF_SIZE; n++){                         // BUF_SIZEサンプル分の入力を読込み,処理する
                t=(t+1)%MEM_SIZE;                                   // 入力時刻の更新
                s[t] = in_buf[in1][n]/32768.0;                      // 入力バッファからデータ読み込み (正規化)
                y[t] = s[t];                                        // 出力=入力の素通しをつくる
                if(hflg!=0){                                        // 処理状態フラグが1なら信号処理を実行


//************************************************************************//

            ////////////////////////////////////////////////////
            //                                                //
            //              Signal Processing                 //
            //                                                //
            //  現在時刻tの入力 s[t] から出力 y[t] をつくる   //
            //                                                //
            //  ※ tは0からMEM_SIZE-1までをループ             //
            //                                                //
            ////////////////////////////////////////////////////

                    if(l>=N){                                       // Nサンプルごとに線形予測分析を実行
                    /////////////////////////////
                    //                         //
                    //      線形予測分析       //
                    //                         //
                    /////////////////////////////

                        pitch=1, rmax=0;                            // ピッチの初期化
                        for(tau=0;tau<N;tau++){                     // 時間差tauの設定
                            r[tau]=0;                               // 自己相関の初期化
                            i=0;
                            while(tau+i<=N){                        // 自己相関の計算
                                r[tau]=r[tau]+s[(t-i+MEM_SIZE)%MEM_SIZE]*s[(t-tau-i+MEM_SIZE)%MEM_SIZE];
                                i++;
                            }
                            r[tau]=r[tau]/N;                        // 自己相関の初期化

                            //ピッチ抽出
                            if(tau>=20 && rmax<r[tau]){             // 音声ピッチの範囲内で最大相関検出
                                rmax=r[tau];
                                pitch=tau;                          // ピッチ推定値
                            }
                        }

                        // レビンソン・ダービンアルゴリズム
                        sigma[0]=r[0];                              // sigma[0] = 時間差0の自己相関関数
                        for(m=0;m<P;m++){
                            delta[m+1]=r[m+1];                      // deltaの初期値 = 自己相関関数
                            for(i=1;i<=m;i++){
                                delta[m+1]=delta[m+1]+a[m][i]*r[m+1-i]; // AR係数aを使ってdeltaを更新
                            }
                            if(fabs(sigma[m])==0.0 || fabs(delta[m+1])>2*fabs(sigma[m])){
                                rho[m+1]   =0.0;                    // deltaが0かsigmaの2倍より大きい場合はrho=0
                                a[m+1][m+1]=rho[m+1];               // AR係数をrhoにする
                            }
                            else{                             
                                rho[m+1]=-delta[m+1]/sigma[m];      // 反射係数rhoの更新
                                a[m+1][m+1]=rho[m+1];               // AR係数a[m+1]の更新
                            }
                            sigma[m+1]=sigma[m]*(1.0-(rho[m+1]*rho[m+1]));// sigma[m+1]の更新
                            for(i=1;i<=m;i++){
                                a[m+1][i]=a[m][i]+rho[m+1]*a[m][m+1-i];// AR係数a[1]からa[m]の更新
                            }
                        }

                        h[0]=1.0;                                   // 線形予測係数h[0]
                        for(i=1;i<=P;i++){
                            h[i]=a[P][i];                           // 線形予測係数h[1]からh[P]の計算
                        }
                        l=0;
                    }

                    e[l]=0;
                    for(i=0;i<=P;i++){
                        e[l] = e[l] + h[i]*s[(t-i+MEM_SIZE)%MEM_SIZE];// 予測誤差(音源)
                    }
                
                    l++;

                    /////////////////////////////
                    //                         //
                    //        音声合成         //
                    //                         //
                    /////////////////////////////

                    rs[t]=e[(int)k];                                // 音源の設定
                    for(i=1;i<=P;i++){
                        rs[t] = rs[t] - h[i]*rs[(t-i+MEM_SIZE)%MEM_SIZE];// 音声合成
                    }

                    y[t]=rs[t];                                     // 合成音声を出力
                
                    k = k+alpha;                                    // 出力の時刻インデックス
                    if(k>=N)k=k-N;                                  // kを0からNの範囲内にする

            ////////////////////////////////////////////////////
            //                                                //
            //              Signal Processing                 //
            //                                                //
            //                  ここまで                      //
            //                                                //
            ////////////////////////////////////////////////////

//************************************************************************//

                    y[t]=atan(y[t])/(M_PI/2.0);                     // クリップ防止
                }
            }
            in_hdr[in1].dwFlags = 0;                                // 入力バッファのフラグ情報を0にする
            waveInPrepareHeader(in_hdl, &in_hdr[in1], sizeof(WAVEHDR));   // 情報を更新し入力バッファを準備
            waveInAddBuffer(in_hdl, &in_hdr[in1], sizeof(WAVEHDR)); // 入力待ちキューに入力バッファデータを送信
            in1=(in1+1)%NUM_BUF;                                    // 入力バッファの更新
            flag = 1;                                               // 入出力フラグを flag=1 (出力状態)にする
        }

        ////////////////////////////////////////////////////
        //                                                //
        //        キーボード入力に対する処理の設定        //
        //                                                //
        //                                                //
        //  [デフォルト設定]                              //
        //  ・スペースキーで素通しと信号処理を切り替え    //
        //  ・Enterキーでプログラム終了                   //
        //                                                //
        ////////////////////////////////////////////////////
        if (kbhit()){                                               // キーボード入力があったか
            key = getch();                                          // キーのチェック
            if (key == 32){                                         // スペースキーが押されとき
            	hflg=(hflg+1)%2;                                    // 処理フラグ変更
                if(hflg==1) printf("Processing\n");                 // 処理中であることを表示
                else        printf("Through\n");                    // 素通しであることを表示
            }
            if (key == 13){                                         // Enterキーが押されたとき
                waveInStop(in_hdl);                                 // 入力を停止
                for (i = 0; i < NUM_BUF; i++){                      // 全入力バッファのアンロック
                    if ((in_hdr[i].dwFlags & WHDR_PREPARED) != 0){
                        waveInUnprepareHeader(in_hdl, &in_hdr[i], sizeof(WAVEHDR ));
                    }
                }
                waveInClose(in_hdl);                                // 入力(録音)デバイスのクローズ
                waveOutPause(out_hdl);                              // 出力を停止
                for (i = 0; i < NUM_BUF; i++){
                    if ((out_hdr[i].dwFlags & WHDR_PREPARED) != 0){ // 全出力バッファのアンロック
                        waveOutUnprepareHeader(out_hdl, &out_hdr[i], sizeof(WAVEHDR));
                    }
                }
                waveOutClose(out_hdl);                              // 出力(再生)デバイスのクローズ
                return 0;
            }
        }
    }                                                               //メインループ終わり
}
Beispiel #9
0
LRESULT CALLBACK MainWndProc(HWND hWnd,
			     UINT uMsg,
			     WPARAM wParam,
			     LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:

	// Get the window and client dimensions

	GetClientRect(hWnd, &window.rect);

	int width = window.rect.right - window.rect.left;
	int height = window.rect.bottom - window.rect.top;

	// Create status bar

	status.hwnd =
	    CreateWindow(STATUSCLASSNAME,
			 " Turn knob to adjust measurement frequency",
			 WS_VISIBLE | WS_CHILD,
			 0, 0, 0, 0,
			 hWnd, (HMENU)STATUS_ID, hInst, NULL);

	// Create tooltip

	tooltip.hwnd =
	    CreateWindow(TOOLTIPS_CLASS, NULL,
			 WS_POPUP | TTS_ALWAYSTIP,
			 CW_USEDEFAULT, CW_USEDEFAULT,
			 CW_USEDEFAULT, CW_USEDEFAULT,
			 hWnd, NULL, hInst, NULL);

	SetWindowPos(tooltip.hwnd, HWND_TOPMOST, 0, 0, 0, 0,
		     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

	tooltip.info.cbSize = sizeof(tooltip.info);
	tooltip.info.hwnd = hWnd;
	tooltip.info.uFlags = TTF_IDISHWND | TTF_SUBCLASS;

	// Create scale

	scale.hwnd =
	    CreateWindow(WC_STATIC, NULL,
			 WS_VISIBLE | WS_CHILD |
			 SS_NOTIFY | SS_OWNERDRAW,
			 8, 8, 160, 40, hWnd,
			 (HMENU)SCALE_ID, hInst, NULL);

	// Add scale to tooltip

	tooltip.info.uId = (UINT_PTR)scale.hwnd;
	tooltip.info.lpszText = "Frequency scale";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create knob

	knob.hwnd =
	    CreateWindow(KNOBCLASS, NULL,
			 WS_VISIBLE | WS_CHILD,
			 4, 52, 168, 168, hWnd,
			 (HMENU)KNOB_ID, hInst, NULL);

	// Add knob to tooltip

	tooltip.info.uId = (UINT_PTR)knob.hwnd;
	tooltip.info.lpszText = "Frequency adjustment knob";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create display

	display.hwnd =
	    CreateWindow(WC_STATIC, NULL,
			 WS_VISIBLE | WS_CHILD |
			 SS_NOTIFY | SS_OWNERDRAW,
			 176, 8, width - 184, 50, hWnd,
			 (HMENU)DISPLAY_ID, hInst, NULL);

	// Add display to tooltip

	tooltip.info.uId = (UINT_PTR)display.hwnd;
	tooltip.info.lpszText = "Frequency and level display";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create meter

	meter.hwnd =
	    CreateWindow(WC_STATIC, NULL,
			 WS_VISIBLE | WS_CHILD |
			 SS_NOTIFY | SS_OWNERDRAW,
			 176, 66, width - 184, 50, hWnd,
			 (HMENU)METER_ID, hInst, NULL);

	// Add meter to tooltip

	tooltip.info.uId = (UINT_PTR)meter.hwnd;
	tooltip.info.lpszText = "Level meter";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create meter slider

	meter.slider.hwnd =
	    CreateWindow(TRACKBAR_CLASS, NULL,
			 WS_VISIBLE | WS_CHILD |
			 TBS_HORZ | TBS_NOTICKS | TBS_TOP,
			 178, 92, width - 188, 20, hWnd,
			 (HMENU)SLIDER_ID, hInst, NULL);

	SendMessage(meter.slider.hwnd, TBM_SETRANGE, TRUE,
		    MAKELONG(MIN_METER, MAX_METER));
	SendMessage(meter.slider.hwnd, TBM_SETPOS, TRUE, MIN_METER);

	// Add slider to tooltip

	tooltip.info.uId = (UINT_PTR)meter.slider.hwnd;
	tooltip.info.lpszText = "Level meter";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create spectrum

	spectrum.hwnd =
	    CreateWindow(WC_STATIC, NULL,
			 WS_VISIBLE | WS_CHILD |
			 SS_NOTIFY | SS_OWNERDRAW,
			 176, 122, width - 184, 50, hWnd,
			 (HMENU)SPECTRUM_ID, hInst, NULL);

	// Add spectrum to tooltip

	tooltip.info.uId = (UINT_PTR)spectrum.hwnd;
	tooltip.info.lpszText = "Frequency spectrum";

	SendMessage(tooltip.hwnd, TTM_ADDTOOL, 0,
		    (LPARAM) &tooltip.info);

	// Create quit button

	quit.hwnd =
	    CreateWindow(WC_BUTTON, "Quit",
			 WS_VISIBLE | WS_CHILD,
			 width - 80, 194, 72, 24, hWnd,
			 (HMENU)QUIT_ID, hInst, NULL);

	// Start audio thread

	audio.thread = CreateThread(NULL, 0, AudioThread, hWnd, 0, &audio.id);

	// Start meter timer

	CreateTimerQueueTimer(&meter.timer, NULL,
			      (WAITORTIMERCALLBACK)MeterCallback,
			      &meter, METER_DELAY, METER_DELAY,
			      WT_EXECUTEDEFAULT);

	// Update frequency

	UpdateFrequency();
	break;

	// Colour static text

    case WM_CTLCOLORSTATIC:
    	return (LRESULT)GetSysColorBrush(COLOR_WINDOW);
    	break;

	// Draw item

    case WM_DRAWITEM:
	return DrawItem(wParam, lParam);
	break;

	// Disable menus by capturing this message

    case WM_INITMENU:
	break;

	// Capture system character key to stop pop up menus and other
	// nonsense

    case WM_SYSCHAR:
	break;

	// Char pressed

    case WM_CHAR:
	CharPressed(wParam, lParam);
	break;

	// Key pressed

    case WM_KEYDOWN:
	KeyDown(wParam, lParam);
	break;

	// Buttons

    case WM_COMMAND:
	switch (LOWORD(wParam))
	{
	    // Quit

	case QUIT_ID:
	    waveInStop(audio.hwi);
	    waveInClose(audio.hwi);
	    PostQuitMessage(0);
	    break;
	}
	break;

	// Notify

    case WM_NOTIFY:
	switch (((LPNMHDR)lParam)->code)
	{
	    // Tooltip

	case TTN_SHOW:
	    TooltipShow(wParam, lParam);
	    break;

	case TTN_POP:
	    TooltipPop(wParam, lParam);
	    break;
	}
	break;

        // Process other messages.

    case WM_DESTROY:
	waveInStop(audio.hwi);
	waveInClose(audio.hwi);
	PostQuitMessage(0);
	break;

	// Everything else

    default:
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    return 0;
}