none
Question to Rafes Castor or someone else RRS feed

  • Question

  • Hello rafael castor...i saw your code about recording and playing wav files. i am doing the same and want to learn about this. i tried to just copy your code into visual studio 2008, just want to see if it worked (you said it workd correct) this is the code you wrote:

    #include <stdio.h>
    #include <conio.h>
    #include <windows.h>
    #include <aviriff.h>

    //WAV format def 
    #define WAV_CHN 1    //mono
    #define WAV_SMP    8000    //sample per sec
    #define    WAV_BIT    16    //bit rate
    #define    WAV_LENG_SEC    30    //record length(sec)

    //wave buf len(channel*sample*bitrate/8*length)
    #define WAVBUFFERLENGTH (WAV_CHN * WAV_SMP * (WAV_BIT / 8) * WAV_LENG_SEC)


    WAVEFORMATEX g_WavFmt = {0};


    //Wave header length
    #define HEADERLENGTH (sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + sizeof(WAVEFORMATEX) + sizeof(RIFFCHUNK))


    void InitWavFmt(void)
    {
        g_WavFmt.wFormatTag = WAVE_FORMAT_PCM;
        g_WavFmt.nChannels = WAV_CHN;
        g_WavFmt.nSamplesPerSec = WAV_SMP;
        g_WavFmt.wBitsPerSample = WAV_BIT;
        g_WavFmt.nBlockAlign = g_WavFmt.nChannels * g_WavFmt.wBitsPerSample / 8;
        g_WavFmt.nAvgBytesPerSec = g_WavFmt.nChannels * g_WavFmt.wBitsPerSample / 8 * g_WavFmt.nSamplesPerSec;
        g_WavFmt.cbSize = 0;
    }

     

    char* AddWavHdr(char *pinBuffer, int inWavLength)
    {
        BYTE *pWavHdr = NULL;
        RIFFLIST  *pRiffWave = NULL;
        RIFFCHUNK *pRiffFmt = NULL;
        RIFFCHUNK *pRiffData = NULL;
        char* outWavBuffer = NULL;

        if (NULL == pinBuffer)
        {
            return NULL;
        }
        
        pWavHdr = malloc(sizeof(BYTE) * HEADERLENGTH);
        if ( NULL == pWavHdr)
        {
            return NULL;
        }
        else
        {
            memset(pWavHdr, 0, sizeof(BYTE) * HEADERLENGTH);
        }

        pRiffWave = (RIFFLIST*)pWavHdr;
        pRiffFmt  = (RIFFCHUNK*)(pRiffWave + 1);
        pRiffData = (RIFFCHUNK*)(((BYTE*)(pRiffFmt + 1)) + sizeof(WAVEFORMATEX));

        pRiffWave->fcc = FCC('RIFF');
        pRiffWave->cb = inWavLength + HEADERLENGTH - sizeof(RIFFCHUNK);
        pRiffWave->fccListType = FCC('WAVE');

        pRiffFmt->fcc = FCC('fmt ');
        pRiffFmt->cb = sizeof(WAVEFORMATEX);

        pRiffData->fcc = FCC('data');
        pRiffData->cb = inWavLength;

        memcpy(pRiffFmt + 1, &g_WavFmt, pRiffFmt->cb);

    outWavBuffer = malloc(sizeof(BYTE) * (inWavLength + HEADERLENGTH));
        if (NULL == outWavBuffer)
        {
            return NULL;
        }
        else
        {
            memset(outWavBuffer, 0, sizeof(BYTE) * (inWavLength + HEADERLENGTH));
        }
        
        memcpy(outWavBuffer, pWavHdr, sizeof(BYTE) * HEADERLENGTH);
        memcpy(outWavBuffer + HEADERLENGTH, pinBuffer, (sizeof(BYTE) * inWavLength));
        return outWavBuffer;
    }

    void main ()
    {
        HWAVEIN hWavIn;
        WAVEHDR WavHdr;
        char *pBuffer = NULL;
        char *pWavBuffer = NULL;    MMRESULT ret;
        FILE *fpPCMFile;
        FILE *fpWavFile;
        MMTIME MMTime = {0};   
        unsigned int numwritten = 0;
        MMTime.wType = TIME_BYTES;

        InitWavFmt();

        if (0 == waveInGetNumDevs())
        {
            printf("Audio device not found!\n");
            exit(0);
        }

     

     ret = waveInOpen(&hWavIn, WAVE_MAPPER, &g_WavFmt, 0, 0, WAVE_FORMAT_QUERY);
        if (MMSYSERR_NOERROR != ret)
        {
            printf("Unsupported WAV format.\n");
            exit(0);
        }


        ret = waveInOpen(&hWavIn, WAVE_MAPPER, &g_WavFmt, 0, 0, CALLBACK_NULL);
        

        if (MMSYSERR_NOERROR != ret)
        {
            exit(0);
        }
        
        pBuffer = malloc(WAVBUFFERLENGTH);
        if ( NULL != pBuffer)
        {
            memset(pBuffer, 0, WAVBUFFERLENGTH);
        }
        else
        {
            exit(0);
        }

        WavHdr.lpData = pBuffer;
        WavHdr.dwBufferLength = WAVBUFFERLENGTH;
        WavHdr.dwBytesRecorded = 0;
        WavHdr.dwUser = 0;
        WavHdr.dwFlags = 0;
        WavHdr.dwLoops = 1;
        WavHdr.lpNext = 0;
        WavHdr.reserved = 0;

     

     ret = waveInPrepareHeader(hWavIn,&WavHdr,sizeof(WAVEHDR));
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }

        ret = waveInAddBuffer(hWavIn, &WavHdr, sizeof(WAVEHDR));
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }


        printf ("Press any key to start recording...\n");
        getch();
        printf ("Recording now\n");

        ret = waveInStart(hWavIn);
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }

        printf ("Press any key to stop Recording\n");
        getch();
        waveInGetPosition(hWavIn, &MMTime, sizeof(MMTime));
        waveInReset(hWavIn);

        waveInUnprepareHeader(hWavIn,&WavHdr,sizeof(WAVEHDR));
        waveInClose(hWavIn);
        
        fpPCMFile = fopen("pcm","w");
        if (NULL == fpPCMFile)
        {
            printf("Creating PCM file failed\n");
            free(pBuffer);
            exit(0);
        }

     

    numwritten = fwrite(pBuffer, sizeof(char), MMTime.u.cb, fpPCMFile);

        printf ("Recording done, %d bytes recorded, %d bytes written\n", MMTime.u.cb, numwritten);

        fclose(fpPCMFile);

        pWavBuffer = AddWavHdr(pBuffer, MMTime.u.cb);
        if ( NULL == pWavBuffer)
        {
            printf("Add header failed\n");
        }
        else
        {
            fpWavFile = fopen("wave.wav", "w");
            if (NULL == fpWavFile)
            {
                printf("Creating WAV file failed\n");
            }
            else
            {
                numwritten = fwrite(pWavBuffer, sizeof(char), sizeof(BYTE) * (HEADERLENGTH + MMTime.u.cb), fpWavFile);
                printf("%d bytes of WAV file written\n", numwritten);
                fclose(fpWavFile);
                free(pWavBuffer);
            }
        }

        free(pBuffer);
        getch();
        return;    
    }





    but when i compile this i get this errors:

    Error 1 error C2440: '=' : cannot convert from 'void *' to 'BYTE *' 
    Error 2 error C2440: '=' : cannot convert from 'void *' to 'char *' 
    Error 3 error C2143: syntax error : missing ')' before ';' 
    Error 4 error C2143: syntax error : missing ')' before ';' 
    Error 5 error C2440: '=' : cannot convert from 'void *' to 'char *'
    Error 6 error C2100: illegal indirection 
    Error 7 error C2143: syntax error : missing ')' before ';' 
    Error 8 error C2100: illegal indirection 
    Error 9 error C2143: syntax error : missing ';' before '/' 
    Error 10 error C2059: syntax error : ')'
    Error 11 error C2059: syntax error : ')' 
    Error 12 error C2059: syntax error : ')' 
    Error 13 error C2143: syntax error : missing ')' before ';' 
    Error 14 error C2143: syntax error : missing ')' before ';' 
    Error 15 error C2100: illegal indirection 
    Error 16 error C2143: syntax error : missing ')' before ';' 
    Error 17 error C2100: illegal indirection 
    Error 18 error C2143: syntax error : missing ';' before '/' 
    Error 19 error C2059: syntax error : ')' 
    Error 20 error C2059: syntax error : ')' 
    Error 21 error C2059: syntax error : ')' 
    Error 22 error C2143: syntax error : missing ')' before ';' 
    Error 23 error C2100: illegal indirection c
    Error 24 error C2143: syntax error : missing ')' before ';' 
    Error 25 error C2100: illegal indirection 
    Error 26 error C2143: syntax error : missing ';' before '/' 
    Error 27 error C2059: syntax error : ')' 
    Error 28 error C2059: syntax error : ')' 


    it seems all the errors can be removed just by adding some library or something. what library did you add? maybe you don´t use Visual Studio? Is there something i have missed?

    thanks in advance 
    Monday, May 11, 2009 8:02 PM

Answers

  • I reposted your code with these fixes in an earlier message. 
    Example of explicit cast:

    pWavHdr = (BYTE*)
    malloc(sizeof(BYTE) * HEADERLENGTH);

    The code you posted is C code.  A C++ compiler will compile it if you at least cast the void pointer that malloc() returns to the target variable type.  Since you have CPP file, you might as well remove the malloc() calls and use new:

    pWavHdr = new BYTE[HEADERLENGTH] ;


    Don't worry about it if you're not getting the warnings about getch().  If you do see them, just use _getch() instead.
    Joseph w Donahue joseph@odonahue.com www.odonahue.com
    • Marked as answer by Wesley Yao Monday, May 18, 2009 3:36 AM
    Tuesday, May 12, 2009 9:04 AM
  • Hi vilse,

    There are many difference between C and C++, you could find so many discussion on the web, like here: What are the major difference between C and C++, I suggest getting a book to learn about their details, and MSDN is a good helper, i.e. the documentations of new and delete operator at here: new Operator, delete Operator, you could also look up the documentation for cout etc.

    To change
    pBuffer = (char*)malloc(WAVBUFFERLENGTH);

    using new, the code is like:

    pBuffer = new char[WAVBUFFERLENGTH];
    please remember using delete to deallocate the memory, i.e.: "delete[] pBuffer;" instead of "free(pBuffer);"

    Any other questions please feel free to open other threads on the forum, here I will mark Joseph w Donahue's post as answer since he has resolved your problem and provided good explanation.

    Sincerely,
    Wesley
    Please mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Wesley Yao Monday, May 18, 2009 11:41 AM
    Monday, May 18, 2009 3:36 AM

All replies

  • Vilse,

    What version of VS did you use?
    Was the above code in a .C or .CPP file?

    VC++ 2008 Express only hit the three C2440 errors due to the assignment to BYTE* and char* from malloc().  When I explicitly cast those assignments appropriately it compiles without error but does warn about the POSIX name for getch() being deprecated and that _getch() has replaced it.  Whether you would get those warnings obviously depends on whether you compile for C or C++ and on which version of the compiler.

    Here's the patched sources:

    // app.cpp : Defines the entry point for the console application.
    //
    #include <stdio.h>
    #include <conio.h>
    #include <windows.h>
    #include <aviriff.h>
    
    //WAV format def 
    #define WAV_CHN 1    //mono
    #define WAV_SMP    8000    //sample per sec
    #define    WAV_BIT    16    //bit rate
    #define    WAV_LENG_SEC    30    //record length(sec)
    
    //wave buf len(channel*sample*bitrate/8*length)
    #define WAVBUFFERLENGTH (WAV_CHN * WAV_SMP * (WAV_BIT / 8) * WAV_LENG_SEC)
    
    
    WAVEFORMATEX g_WavFmt = {0};
    
    
    //Wave header length
    #define HEADERLENGTH (sizeof(RIFFLIST) + sizeof(RIFFCHUNK) + sizeof(WAVEFORMATEX) + sizeof(RIFFCHUNK))
    
    
    void InitWavFmt(void)
    {
        g_WavFmt.wFormatTag = WAVE_FORMAT_PCM;
        g_WavFmt.nChannels = WAV_CHN;
        g_WavFmt.nSamplesPerSec = WAV_SMP;
        g_WavFmt.wBitsPerSample = WAV_BIT;
        g_WavFmt.nBlockAlign = g_WavFmt.nChannels * g_WavFmt.wBitsPerSample / 8;
        g_WavFmt.nAvgBytesPerSec = g_WavFmt.nChannels * g_WavFmt.wBitsPerSample / 8 * g_WavFmt.nSamplesPerSec;
        g_WavFmt.cbSize = 0;
    }
    
     
    
    char* AddWavHdr(char *pinBuffer, int inWavLength)
    {
        BYTE *pWavHdr = NULL;
        RIFFLIST  *pRiffWave = NULL;
        RIFFCHUNK *pRiffFmt = NULL;
        RIFFCHUNK *pRiffData = NULL;
        char* outWavBuffer = NULL;
    
        if (NULL == pinBuffer)
        {
            return NULL;
        }
        
        pWavHdr = (BYTE*)malloc(sizeof(BYTE) * HEADERLENGTH);
        if ( NULL == pWavHdr)
        {
            return NULL;
        }
        else
        {
            memset(pWavHdr, 0, sizeof(BYTE) * HEADERLENGTH);
        }
    
        pRiffWave = (RIFFLIST*)pWavHdr;
        pRiffFmt  = (RIFFCHUNK*)(pRiffWave + 1);
        pRiffData = (RIFFCHUNK*)(((BYTE*)(pRiffFmt + 1)) + sizeof(WAVEFORMATEX));
    
        pRiffWave->fcc = FCC('RIFF');
        pRiffWave->cb = inWavLength + HEADERLENGTH - sizeof(RIFFCHUNK);
        pRiffWave->fccListType = FCC('WAVE');
    
        pRiffFmt->fcc = FCC('fmt ');
        pRiffFmt->cb = sizeof(WAVEFORMATEX);
    
        pRiffData->fcc = FCC('data');
        pRiffData->cb = inWavLength;
    
        memcpy(pRiffFmt + 1, &g_WavFmt, pRiffFmt->cb);
    
    outWavBuffer = (char*)malloc(sizeof(BYTE) * (inWavLength + HEADERLENGTH));
        if (NULL == outWavBuffer)
        {
            return NULL;
        }
        else
        {
            memset(outWavBuffer, 0, sizeof(BYTE) * (inWavLength + HEADERLENGTH));
        }
        
        memcpy(outWavBuffer, pWavHdr, sizeof(BYTE) * HEADERLENGTH);
        memcpy(outWavBuffer + HEADERLENGTH, pinBuffer, (sizeof(BYTE) * inWavLength));
        return outWavBuffer;
    }
    
    void main ()
    {
        HWAVEIN hWavIn;
        WAVEHDR WavHdr;
        char *pBuffer = NULL;
        char *pWavBuffer = NULL;    MMRESULT ret;
        FILE *fpPCMFile;
        FILE *fpWavFile;
        MMTIME MMTime = {0};   
        unsigned int numwritten = 0;
        MMTime.wType = TIME_BYTES;
    
        InitWavFmt();
    
        if (0 == waveInGetNumDevs())
        {
            printf("Audio device not found!\n");
            exit(0);
        }
    
     
    
     ret = waveInOpen(&hWavIn, WAVE_MAPPER, &g_WavFmt, 0, 0, WAVE_FORMAT_QUERY);
        if (MMSYSERR_NOERROR != ret)
        {
            printf("Unsupported WAV format.\n");
            exit(0);
        }
    
    
        ret = waveInOpen(&hWavIn, WAVE_MAPPER, &g_WavFmt, 0, 0, CALLBACK_NULL);
        
    
        if (MMSYSERR_NOERROR != ret)
        {
            exit(0);
        }
        
        pBuffer = (char*)malloc(WAVBUFFERLENGTH);
        if ( NULL != pBuffer)
        {
            memset(pBuffer, 0, WAVBUFFERLENGTH);
        }
        else
        {
            exit(0);
        }
    
        WavHdr.lpData = pBuffer;
        WavHdr.dwBufferLength = WAVBUFFERLENGTH;
        WavHdr.dwBytesRecorded = 0;
        WavHdr.dwUser = 0;
        WavHdr.dwFlags = 0;
        WavHdr.dwLoops = 1;
        WavHdr.lpNext = 0;
        WavHdr.reserved = 0;
    
     
    
     ret = waveInPrepareHeader(hWavIn,&WavHdr,sizeof(WAVEHDR));
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }
    
        ret = waveInAddBuffer(hWavIn, &WavHdr, sizeof(WAVEHDR));
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }
    
    
        printf ("Press any key to start recording...\n");
        getch();
        printf ("Recording now\n");
    
        ret = waveInStart(hWavIn);
        if (MMSYSERR_NOERROR != ret)
        {
            free(pBuffer);
            exit(0);
        }
    
        printf ("Press any key to stop Recording\n");
        getch();
        waveInGetPosition(hWavIn, &MMTime, sizeof(MMTime));
        waveInReset(hWavIn);
    
        waveInUnprepareHeader(hWavIn,&WavHdr,sizeof(WAVEHDR));
        waveInClose(hWavIn);
        
        fpPCMFile = fopen("pcm","w");
        if (NULL == fpPCMFile)
        {
            printf("Creating PCM file failed\n");
            free(pBuffer);
            exit(0);
        }
    
     
    
    numwritten = fwrite(pBuffer, sizeof(char), MMTime.u.cb, fpPCMFile);
    
        printf ("Recording done, %d bytes recorded, %d bytes written\n", MMTime.u.cb, numwritten);
    
        fclose(fpPCMFile);
    
        pWavBuffer = AddWavHdr(pBuffer, MMTime.u.cb);
        if ( NULL == pWavBuffer)
        {
            printf("Add header failed\n");
        }
        else
        {
            fpWavFile = fopen("wave.wav", "w");
            if (NULL == fpWavFile)
            {
                printf("Creating WAV file failed\n");
            }
            else
            {
                numwritten = fwrite(pWavBuffer, sizeof(char), sizeof(BYTE) * (HEADERLENGTH + MMTime.u.cb), fpWavFile);
                printf("%d bytes of WAV file written\n", numwritten);
                fclose(fpWavFile);
                free(pWavBuffer);
            }
        }
    
        free(pBuffer);
        getch();
        return;    
    }
    
    Good luck!

    Joseph w Donahue joseph@odonahue.com www.odonahue.com
    Monday, May 11, 2009 9:11 PM
  • When I added the original code to a .C file in VS 2003 it compiled without errors and got two warnings:

    ...\test.c(193): warning C4267: '=' : conversion from 'size_t' to 'unsigned int', possible loss of data
    ...\test.c(213): warning C4267: '=' : conversion from 'size_t' to 'unsigned int', possible loss of data


    The variable numwritten should be declared as a size_t and the format specifiers where it is used in output should be modified as well (size_t is usually unsigned and definitely varies in size from one platform to another).
    Joseph w Donahue joseph@odonahue.com www.odonahue.com
    Monday, May 11, 2009 9:35 PM
  • Hello Joseph w Donahue

    Tanks for repling..i am working under Microsoft Visual Studio 2008 v 9.0....
    when i created a project i chosed New Project -> Console Aplication -> Emty Project after that i chosed .cpp file.
    When i compile same code again i only got 3 errors and 0 warings lol just under a night 27 errors seems to dispear´=). 
    And it seems like the same error as yours.

    Error 1 error C2440: '=' : cannot convert from 'void *' to 'BYTE *' 
    Error 2 error C2440: '=' : cannot convert from 'void *' to 'char *' 
    Error 3 error C2440: '=' : cannot convert from 'void *' to 'char *'

    i don´t really understand what you mean with this..

    "...When I explicitly cast those assignments appropriately it compiles without error but does warn about the POSIX name for getch() being deprecated and that _getch() has replaced it." and what is app.cpp? do i have to add this somewhere? in the patch you send you did a comment of it.

    iam not so good at this but i really want to be. Can you show me how you did to solve these errors. how did you change the code? my english is not so good since it not my mother language. if i can get the code to work my next step is to understand it a little more.

    Thanks in advance for every kind of answers that can solve this

    Tuesday, May 12, 2009 8:05 AM
  • I reposted your code with these fixes in an earlier message. 
    Example of explicit cast:

    pWavHdr = (BYTE*)
    malloc(sizeof(BYTE) * HEADERLENGTH);

    The code you posted is C code.  A C++ compiler will compile it if you at least cast the void pointer that malloc() returns to the target variable type.  Since you have CPP file, you might as well remove the malloc() calls and use new:

    pWavHdr = new BYTE[HEADERLENGTH] ;


    Don't worry about it if you're not getting the warnings about getch().  If you do see them, just use _getch() instead.
    Joseph w Donahue joseph@odonahue.com www.odonahue.com
    • Marked as answer by Wesley Yao Monday, May 18, 2009 3:36 AM
    Tuesday, May 12, 2009 9:04 AM
  • Hi Joseph

    Thank you very mutch for your help....I copied the code ju reposted and after that added winmm.lib to link list. Now  i can compile it after all.  Now i just have to understand the code and that wont be easy i know :P, and try to understand why i got noise when i play a recorded file. 
     I am sure i will come up with more question later. Tank you one more time.

    Tuesday, May 12, 2009 11:26 AM
  • Hi i have alrady a question about the code. you said that it was coded in C. Is it huge difference between C and C++? just because i have only coded in C++ earlier. for exampel i use to write cout instead of printf(...) by including iostream.  what are the differnces, can i just change the code a little to make it more like c++ code? and..

    you said something about remove the malloc() calls and replace it with new BYTE[HEADERLENGTH];
    does that mean that

    pWavHdr = (BYTE*)
    malloc(sizeof(BYTE)*HEADERLENGTH); = new BYTE[HEADERLENGTH];?

    if that how do i change

    pBuffer = (

    char*)malloc(WAVBUFFERLENGTH); to new?

    Thanks in advance

    Tuesday, May 12, 2009 12:36 PM
  • Hi vilse,

    There are many difference between C and C++, you could find so many discussion on the web, like here: What are the major difference between C and C++, I suggest getting a book to learn about their details, and MSDN is a good helper, i.e. the documentations of new and delete operator at here: new Operator, delete Operator, you could also look up the documentation for cout etc.

    To change
    pBuffer = (char*)malloc(WAVBUFFERLENGTH);

    using new, the code is like:

    pBuffer = new char[WAVBUFFERLENGTH];
    please remember using delete to deallocate the memory, i.e.: "delete[] pBuffer;" instead of "free(pBuffer);"

    Any other questions please feel free to open other threads on the forum, here I will mark Joseph w Donahue's post as answer since he has resolved your problem and provided good explanation.

    Sincerely,
    Wesley
    Please mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Wesley Yao Monday, May 18, 2009 11:41 AM
    Monday, May 18, 2009 3:36 AM
  • Hi Wesley Yao

    Tank you for help. yes i know Joseph w Donahue's helped me i forgot to mark is as "aswered". i will be better on that for next time. thanks for helping.
    =).
    Tuesday, May 19, 2009 11:37 AM