waveInStart audio is very choppy
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: waveInStart audio is very choppy

Hybrid View

  1. #1
    Join Date
    Jan 2008
    Location
    Earth
    Posts
    60

    Angry waveInStart audio is very choppy

    I am writing an application to send audio over a socket, problem is, its very very choppy! my buffer size is 1000 bytes, I tried 500, 4096, 8000, all of which exhibit very choppy sound! can someone help? what do I need to do to stream PCM audio without choppy sound? my settings are...
    WAVEFORMATEX wfx;
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nChannels = 1; //1: mono, 2, stereo
    wfx.nSamplesPerSec = 11025; //11025,22050,44100
    wfx.wBitsPerSample = 8; //8,16


    this is what Im doing...

    ---to send audio from the microphone---
    waveInPrepareHeader
    waveInAddBuffer
    waveInStart
    //wait for MM_WIM_DATA
    //I make a heap copy of WAVEHDR's lpData , and post to another thread
    //(done just for testing purpose, will send over socket eventually)
    waveInStop
    waveInUnprepareHeader
    -repeats

    --to receive the audio---
    thread receives the message
    waveOutPause
    waveOutUnprepareHeader
    waveOutPrepareHeader
    waveOutWrite
    waveOutRestart
    //wait for next message

  2. #2
    Join Date
    Aug 2007
    Location
    Birmingham, UK
    Posts
    360

    Re: waveInStart audio is very choppy

    Have you tried recording the audio and playing it back on the same machine without sockets? As in, the recording side places audio in a buffer, which is then used by the playback side.

    When you try that, does that sound choppy as well?

    Streaming live audio over a network is not trivial. You need to match the audio clock rates at both ends of the connection, and you need to counteract any networking jitter. The easy fix for the last option is a larger receive buffer, which will then of course increase latency.

  3. #3
    Join Date
    Jan 2008
    Location
    Earth
    Posts
    60

    Re: waveInStart audio is very choppy

    Thanks for you response! I did end up figuring it out last night!
    The problem was, I did not have enough buffers flowing to the sound devices.
    I increased my buffers to 10 x 1000, and this is the method am using now, and its really smooth!....

    ---to send audio from the microphone---
    {create WAVEHDR on heap, waveInPrepareHeader, waveInAddBuffer}
    //loop previous line 10 times to make a nice buffer for mic
    waveInStart
    //on MM_WIM_DATA we used a buffer, so add another one, then cleanup
    //the one we just rcv'ed (after sending it of course)...
    {create WAVEHDR on heap, waveInPrepareHeader, waveInAddBuffer}
    {waveInUnprepareHeader passed by MM_WIM_DATA, send lpData,
    delete WAVEHDR, and then lpData}

    ---to play audio---
    rcv lpData, waveOutPrepareHeader, waveOutWrite
    on MM_WOM_DONE message, I cleanup the WAVEHDR


    this method works perfect, and is not choppy at all!

  4. #4
    Join Date
    Aug 2007
    Location
    Birmingham, UK
    Posts
    360

    Re: waveInStart audio is very choppy

    Glad to hear you got it sorted, and also thank you for posting your solution here!

  5. #5
    Join Date
    Dec 2009
    Posts
    161

    Re: waveInStart audio is very choppy

    Hi,

    I'm sorry to bring this up after along while... I would like to save the first one second of audio data from the internal Microphone. I am doing this in order to get to know better the waveForm API. this is the code I've written so far:

    Code:
    #include <windows.h>
    #pragma comment (lib, "winmm.lib")
    #include <mmsystem.h>
    #include <iostream>
    #define system_buf_len 4096
    
    BOOL CALLBACK myCallback();
    
    int main()
    {
     // Definisco la struttura WAVEFORMATEX
     WAVEFORMATEX waveFormat;
     waveFormat.wFormatTag      = WAVE_FORMAT_PCM;
     waveFormat.wBitsPerSample  = 16;
     waveFormat.nChannels       = 1;
     waveFormat.nSamplesPerSec  = 44100;
     waveFormat.nBlockAlign     = waveFormat.nChannels *
    waveFormat.wBitsPerSample / 8;
     waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec *
    waveFormat.nBlockAlign;
     waveFormat.cbSize          = 0;
    
     MMRESULT mmres;   // ...
     HWAVEIN phvi;     // Handle for the input device
     UINT uDevice = 0; // Device id "Gruppo Microfoni"
    
     // waveInOpen
     mmres = waveInOpen(&phvi,
         uDevice,
         (LPWAVEFORMATEX)&waveFormat,
         0,
         0,
         CALLBACK_EVENT
         );
    
     // Prepare Buffer
    
     char *buf = (char *)malloc(system_buf_len);
    
     WAVEHDR buffer;
     buffer.lpData          = buf;
     buffer.dwBufferLength  = system_buf_len;
     buffer.dwBytesRecorded = 0;
     buffer.dwUser          = 0;
     buffer.dwFlags         = 0;
     buffer.dwLoops         = 0;
    
     // waveInPrepareHeader
     waveInPrepareHeader(phvi, &buffer, sizeof(WAVEHDR));
    
     // waveInAddBuffer
     waveInAddBuffer(phvi, &buffer, sizeof(WAVEHDR));
    
     //waveInStart;
     waveInStart(phvi);
    
     return 0;
    }
    I'd like to point out that I am not using any callback function for the
    moment...I'd like to know more about that by the way!

    Anyway, is the code right so far? after I call waveInStart(); how can I
    actually grab the rwa audio data??

    thanks!

  6. #6
    Join Date
    Feb 2005
    Posts
    2,160

    Re: waveInStart audio is very choppy

    I've never used the callback method with the waveXXX functions so I don't know too much about it. I found this article:

    http://www.codeproject.com/KB/audio-...recording.aspx

    that discusses issues involved with callback processing. I was looking for a project that I'd used in the past when I ran across the article above. Here's the class I've used before (after hacking it all to hell):

    http://www.codeproject.com/KB/audio-video/fister.aspx

  7. #7
    Join Date
    Dec 2009
    Posts
    161

    Re: waveInStart audio is very choppy

    ok thanks...I am going to check out those links. Anyway...this is something more I have coded so far:

    Code:
    #include <windows.h>
    #pragma comment (lib, "winmm.lib")
    #include <mmsystem.h>
    #include <iostream>
    #include <stdlib.h> // Define "system" function
    #define system_buf_len 4096
    
    void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD 
    dwParam1,DWORD dwParam2);
    
    int main()
    {
     // Definisco la struttura WAVEFORMATEX
     WAVEFORMATEX waveFormat;
     waveFormat.wFormatTag      = WAVE_FORMAT_PCM;
     waveFormat.wBitsPerSample  = 16;
     waveFormat.nChannels       = 1;
     waveFormat.nSamplesPerSec  = 44100;
     waveFormat.nBlockAlign     = waveFormat.nChannels * 
    waveFormat.wBitsPerSample / 8;
     waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * 
    waveFormat.nBlockAlign;
     waveFormat.cbSize          = 0;
    
     MMRESULT mmres;   // ...
     HWAVEIN phvi;     // Handle for the input device
     UINT uDevice = 0; // Device id "Gruppo Microfoni"
    
     // waveInOpen
     mmres = waveInOpen(&phvi,
         uDevice,
         (LPWAVEFORMATEX)&waveFormat,
         (DWORD)waveInProc,
         0,
         CALLBACK_FUNCTION
         );
    
     // Prepare Buffer
    
     char *buf = (char *)malloc(system_buf_len);
    
     WAVEHDR buffer;
     buffer.lpData          = buf;
     buffer.dwBufferLength  = system_buf_len;
     buffer.dwBytesRecorded = 0;
     buffer.dwUser          = 0;
     buffer.dwFlags         = 0;
     buffer.dwLoops         = 0;
    
     // waveInPrepareHeader
     waveInPrepareHeader(phvi, &buffer, sizeof(WAVEHDR));
    
     // waveInAddBuffer
     waveInAddBuffer(phvi, &buffer, sizeof(WAVEHDR));
    
     //waveInStart;
     waveInStart(phvi);
    
     //
     system("pause");
    
     //waveInClose;
     waveInClose(phvi);
    
     return 0;
    }
    
    void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD 
    dwParam1,DWORD dwParam2)
    {
     switch(uMsg)
     {
     case WIM_DATA:
      MessageBox(0,"WIN_DATA","waveInProc",MB_OK);
      break;
     case WIM_OPEN:
      MessageBox(0,"WIN_OPEN","waveInProc",MB_OK);
      break;
     case WIM_CLOSE:
      MessageBox(0,"WIN_CLOSE","waveInProc",MB_OK);
      break;
     }
    }
    it basically uses the CALLBACK_FUNCTION

  8. #8
    Join Date
    Dec 2009
    Posts
    161

    Re: waveInStart audio is very choppy

    I coded the callback function like the following:

    Code:
    void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
    {
    	WAVEHDR* pWaveHdr;
    	switch(uMsg)
    	{
    	case MM_WIM_DATA:
    		pWaveHdr = ((WAVEHDR*)dwParam1 );
    		std::cout << "MM_WIN_DATA" << std::endl;
    		std::cout << "dwFlags: " << pWaveHdr->dwFlags << std::endl;
    		std::cout << "dwBytesRecorded: " << pWaveHdr->dwBytesRecorded << std::endl;
    		std::cout << "lpData: " << &pWaveHdr->lpData << std::endl;
    		break;
    	case MM_WIM_OPEN:
    		std::cout << "MM_WIN_OPEN" << std::endl;
    		break;
    	case MM_WIM_CLOSE:
    		std::cout << "MM_WIN_CLOSE" << std::endl;
    		break;
    	}
    }
    I am getting it working great. yet, I wonder how I can access the actual buffer data! I'd like to save it on a binary file (yep, just 4096 bytes)

    thanks

  9. #9
    Join Date
    Dec 2009
    Posts
    161

    Re: waveInStart audio is very choppy

    this is some new code...how can I put the recording into a infinite loop? do I have to use threads?

    Code:
    #include <windows.h>
    #pragma comment (lib, "winmm.lib")
    #include <mmsystem.h>
    #include <iostream>
    #include <stdlib.h> // Define "system" function
    #include <string>
    #define system_buf_len 32768
    
    void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
    bool addbuffer(WAVEHDR *pWaveHdr);
    
    
    int main()
    {
    	// Definisco la struttura WAVEFORMATEX
    	WAVEFORMATEX waveFormat;
    	waveFormat.wFormatTag      = WAVE_FORMAT_PCM;
    	waveFormat.wBitsPerSample  = 16;
    	waveFormat.nChannels       = 1;
    	waveFormat.nSamplesPerSec  = 44100;
    	waveFormat.nBlockAlign     = (waveFormat.nChannels * waveFormat.wBitsPerSample) / 8;
    	waveFormat.nAvgBytesPerSec = (waveFormat.nSamplesPerSec * waveFormat.nBlockAlign);
    	waveFormat.cbSize          = 0;
    
    	MMRESULT mmres;   // ...
    	HWAVEIN phvi;     // Handle for the input device
    	UINT uDevice = 0; // Device id "Gruppo Microfoni"
    
    	// waveInOpen
    	mmres = waveInOpen(&phvi,
    					uDevice,
    					(LPWAVEFORMATEX)&waveFormat,
    					(DWORD)waveInProc,
    					0,
    					CALLBACK_FUNCTION
    					);
    
    	// Prepare Buffer
    
    	int i=0;
    	int num_buff = 20;
    	WAVEHDR *buffer = (WAVEHDR *) malloc(sizeof(WAVEHDR)*num_buff);
    	for (i=0; i<num_buff; i++)
    	{
    		buffer[i].lpData          = (LPSTR) malloc(system_buf_len);
    		buffer[i].dwBufferLength  = system_buf_len;
    		buffer[i].dwBytesRecorded = 0;
    		buffer[i].dwUser          = 0;
    		buffer[i].dwFlags         = 0;
    		buffer[i].dwLoops         = 0;
    
    		waveInPrepareHeader(phvi, &buffer[i], sizeof(WAVEHDR));
    		waveInAddBuffer(phvi, &buffer[i], sizeof(WAVEHDR));
    	}
    	//waveInStart;
    	waveInStart(phvi);
    
    	//waveInClose;
    	waveInClose(phvi);
    	system("pause");
    	return 0;
    }
    
    void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
    {
    	WAVEHDR* pWaveHdr;
    	switch(uMsg)
    	{
    	case MM_WIM_DATA:
    		pWaveHdr = ((WAVEHDR*)dwParam1);
    		if (pWaveHdr && hwi)
    		{
    			if (pWaveHdr->dwFlags && WHDR_DONE == WHDR_DONE)
    			{
    				pWaveHdr->dwFlags = 0;
    				waveInUnprepareHeader(hwi, pWaveHdr, sizeof(WAVEHDR));
    				if (pWaveHdr->dwBytesRecorded > 0)
    				{
    					addbuffer(pWaveHdr);
    				}
    				delete[] pWaveHdr->lpData;
    				pWaveHdr->lpData = NULL;
    			}
    		}
    		break;
    
    	case MM_WIM_OPEN:
    		std::cout << "MM_WIN_OPEN" << std::endl;
    		break;
    	case MM_WIM_CLOSE:
    		std::cout << "MM_WIN_CLOSE" << std::endl;
    		break;
    	}
    }
    
    bool addbuffer(WAVEHDR *pWaveHdr)
    {
    	std::cout << pWaveHdr->dwBytesRecorded << std::endl;
    	std::cout << pWaveHdr->lpData << std::endl;
    	return true;
    }
    thanks

  10. #10
    Join Date
    Dec 2012
    Posts
    1

    Re: waveInStart audio is very choppy

    Hi Guys,

    you guys are good! i having a question about waveform audio functions as well. and i am wondering how could i code the input signal and play it the output sound at the same time? is there any idea guys?

    here the code is the usually code founded anywhere and works find.

    #include <iostream>
    #include <Windows.h>
    #include <MMSystem.h>
    using namespace std;
    #pragma comment(lib,”libwinmm.a”)//this will make the linker links
    //with this library

    int main()
    {
    const int NUMPTS = 44100 * 10;
    int sampleRate = 44100;
    short int waveIn[NUMPTS];

    HWAVEIN hWaveIn;
    WAVEHDR WaveInHdr;
    MMRESULT result;
    HWAVEOUT hWaveOut;

    WAVEFORMATEX pFormat;
    pFormat.wFormatTag = WAVE_FORMAT_PCM;
    pFormat.nChannels = 1;
    pFormat.nSamplesPerSec = sampleRate;
    pFormat.nAvgBytesPerSec = 2 * sampleRate;
    pFormat.nBlockAlign = 2;
    pFormat.wBitsPerSample = 16;
    pFormat.cbSize = 0;

    result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);

    if(result)
    {
    char fault[256];
    waveInGetErrorTextA(result, fault, 256);
    MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

    WaveInHdr.lpData = (LPSTR)waveIn;
    WaveInHdr.dwBufferLength = 2 * NUMPTS;
    WaveInHdr.dwBytesRecorded = 0;
    WaveInHdr.dwUser = 0;
    WaveInHdr.dwFlags = 0;
    WaveInHdr.dwLoops = 0;
    waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

    result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
    if(result)
    {
    MessageBoxA(NULL, "Failed to read block from device", NULL, MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

    result = waveInStart(hWaveIn);
    if(result)
    {
    MessageBoxA(NULL, "Failed to start recording", NULL, MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

    cout << "Recording..." << endl;
    Sleep((NUMPTS/sampleRate) * 1000); //Sleep while recording

    cout << "Playing..." << endl;

    if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
    {
    MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
    }

    waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); //<-- The line I forgot before
    Sleep((NUMPTS/sampleRate) * 1000); //Sleep for as long as there was recorded

    waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
    waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
    waveInClose(hWaveIn);
    waveOutClose(hWaveOut);

    return 0;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center