mmioOpen question in C++

I'm sure that I'm making a dumb mistake somewhere. I found a tutorial of sorts on how to read into a .wav. Here is a snippet from the code.

1
2
3
4
HMMIO handle = mmioOpen("test.wav", 0, MMIO_READ);
if (!handle) {
MessageBox(Handle,"Error opening file.","Error Message", 0);
return;}


Before I even get the chance to try running the code, MSVC++ points out this error:

Error: argument of type "const char*" is incompatible with parameter of type "LPWSTR"

What's going on?

Thanks,
Chris
I think LPWSTR is wide characters, so you could try to prefix the string literal with an L.
Last edited on
I'm such a noob. OK another issue. Here goes.

1
2
3
4
5
6
7
8
9
10
11
#include <windows.h> // Use windows
#include <mmsystem.h> // Use multimedia system
#include <iostream> // Use console IO
using namespace std;


HMMIO handle = mmioOpen(L"test.wav", 0, MMIO_READ);

if (!handle) {
MessageBox(Handle,"Error opening file.","Error Message", 0);
return;}


At the beginning of the if statement MSVC++ is underlining the "if" and giving this error:
Error: expected a declaration
To my rookie eyes everything looks fine... any thoughts?
Last edited on
This is something I wrote a long time ago based on some sample code I found somewhere.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#include <iostream>
#include <cstdlib>
#include <string>
#include <conio.h>
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <msacm.h>
#include <cmath>

#pragma comment(lib, "winmm.lib")
#pragma comment(lib,"msacm32.lib")

using namespace std;

class CWaveFile : public WAVEFORMATEX 
{                                      
public:
    HMMIO m_hmmio;
    MMCKINFO m_wave,m_fmt,m_data;

    CWaveFile();
    // creates a WAVE file ready to write audio-data to
    BOOL Create(LPCSTR name);
    // write audio-data to created file
    BOOL Write(BYTE* sd, LONG len);
    // open a WAV file ready to read data from
    DWORD Open(LPCSTR name);
    // read audio-data from opened file
    LONG Read(BYTE* sd, LONG len);
    // seek from current position
    LONG SeekCur(LONG diff);
    // seek from beginning
    LONG SeekSet(LONG pos);
    // close the file
    BOOL Close();
    virtual ~CWaveFile();
};

typedef struct 
{
    WAVEFORMATEX WAVEFORMAT;  
    HMMIO        WAVEHANDLE;     
    DWORD        DATAC; 
} *WAVEIN;

typedef struct
{
    SHORT LEFT;
    SHORT RIGHT;} SAMPLE;

    MMCKINFO    mmckinfoParent;    
    MMCKINFO    mmckinfoSubchunk;  
    WAVEIN      w; 



    WAVEIN openwave(LPTSTR szFilename)
    {

        w = (WAVEIN) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*w));

        w-> WAVEHANDLE = mmioOpen((LPTSTR) szFilename, NULL, MMIO_READ | MMIO_ALLOCBUF | MMIO_DENYWRITE);

        mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); 

        mmioDescend(w-> WAVEHANDLE , (LPMMCKINFO) &mmckinfoParent, 0, MMIO_FINDRIFF);

        mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); 

        mmioDescend(w-> WAVEHANDLE , &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK); 

        mmioRead(w-> WAVEHANDLE , (HPSTR) &w->WAVEFORMAT, min(mmckinfoSubchunk.cksize, sizeof(w->WAVEFORMAT)));

        mmioAscend(w-> WAVEHANDLE , &mmckinfoSubchunk, 0); 

        mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); 

        mmioDescend(w->WAVEHANDLE, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK);

        w->DATAC = mmckinfoSubchunk.cksize;

        return w;

        mmioClose(w-> WAVEHANDLE , 0);
        HeapFree(GetProcessHeap(), 0, w);
        return NULL;
    }

    VOID getwaveformat(WAVEIN wav, WAVEFORMATEX* pFormat)
    {
        CopyMemory(pFormat, &wav->WAVEFORMAT, sizeof(*pFormat));
    }

    LONG getnextsample(WAVEIN wav, SAMPLE* pSample)
    {
        LONG ret = mmioRead( wav -> WAVEHANDLE , (HPSTR) &pSample->LEFT, wav ->WAVEFORMAT.wBitsPerSample / 8);

        ret = mmioRead(wav-> WAVEHANDLE , (HPSTR) &pSample->RIGHT, wav ->WAVEFORMAT.wBitsPerSample / 8);
        return ret;
    }

    VOID release(WAVEIN wav)
    {
    	mmioClose(wav-> WAVEHANDLE , 0);
    	HeapFree(GetProcessHeap(), 0, wav);
    }

    int x=0;
    int c=0;
    bool quit=false;
    char q;

    int main(void)
    {

        LONGLONG addedleft=NULL;
        LONGLONG addedright=NULL;
        LONG counted=NULL;
        LONGLONG average=NULL;
        LONGLONG averageleft=NULL;
        LONGLONG averageright=NULL;
        LONGLONG total=NULL;
        LONGLONG avtotal=NULL;
        LONGLONG peakright=NULL;
        LONGLONG peakleft=NULL;
        char b=NULL;
        LONGLONG peak=NULL;

        WAVEIN  wav  = NULL;
        SAMPLE sample = { 0 };


        while (quit==false) {
            system("cls");

            addedleft=0;
            addedright=0;
            counted=0;
            average=0;
            averageleft=0;
            averageright=0;
            total=0;
            avtotal=0;
            peakright=0;
            peakleft=0;
            b=0;
            peak=0;
            x=0;
            q=NULL;

            cout << endl;
            cout << "  specify a wav file to read: " ;

            string filen="test.wav";   
            //cin >> filen;

            system("cls");

            if (filen=="1") {
                LPTSTR filename=(TEXT("test.wav"));   //unicode mode version
                wav=openwave(filename);}

            else { wav=openwave(const_cast<char*>(filen.c_str()));}

            //char *wvf="test.wav";                      //multibyet alternative
            //wav=openwave(wtf);

            cout << endl << "  How many samplse do you want to display values for? ";
            cin >>c;

            system("cls"); 
            cout << endl;
            cout << "  " << filen ;

            if (c>0) {
                cout << endl << endl <<  "  first "; 
                cout <<  c; 
                cout <<  " sample values: " << endl << endl;}

            while (getnextsample(wav, &sample) > 0)
            {
                if (abs(sample.LEFT)>peakleft) {peakleft=0; peakleft=abs(sample.LEFT);}
                if (abs(sample.RIGHT)>peakright) {peakright=0; peakright=abs(sample.RIGHT);}

                addedleft=abs(addedleft)+abs(sample.LEFT);
                addedright=abs(addedright)+abs(sample.RIGHT);
                counted++;

                if (x<c){ x++;

                cout << "  sample # "; 
                cout << x; 
                cout << "        " << "left: "; 
                cout  << sample.LEFT;
                cout  << "            " << "right: "; 
                cout  << sample.RIGHT << endl;
                }
            }
            peak=(peakleft+peakright)/2;
            total=addedleft+addedright;
            avtotal=total/2;
            average=avtotal/counted;
            averageleft=addedleft/counted;
            averageright=addedright/counted;

            cout << endl << endl;
            cout << "  number of samples:       ";
            cout  << counted;
            cout << endl << endl << "  average amplitude :      "; 
            cout  << average; 
            cout  << endl << endl << "  peak amplitude:          "; 
            cout << peak << endl << endl; 
            cout << "  average amplitude left:  "; 
            cout  << averageleft; 
            cout  << endl << endl << "  average amplitude right: "; 
            cout  << averageright; 
            cout  << endl << endl << "  peack amplitude left:    "; 
            cout  << peakleft; 
            cout  << endl << endl << "  peak amplitude right:    "; 
            cout  << peakright; 
            cout << "         quit "; 
            cout << "[q]";
            cout << "  continue "; 
            cout << "[any other key]";
            cout << endl; 

            q=_getch();

            if (q=='q') quit=true;

            mmioClose(wav-> WAVEHANDLE , 0);
            HeapFree(GetProcessHeap(), 0, wav);

        }
        return 0;
    }


The best programming advice I think I ever got was to use libsndfile to read audio files. It's much much easier to use. You can read and write many different types of audio files, and it's portable.

http://en.wikipedia.org/wiki/Libsndfile
http://www.mega-nerd.com/libsndfile/

Last edited on
@iseeplusplus:
Thanks.
Here is the basic process of reading and writing with libsndfile, after you've gone through the process of installing/linking and all that. Might be syntax errors and whatnot.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <sndfile.h>   
//lbsnfile header

//declare variables used to read audio file
short *in;     
short *inleft, *inright;   
SNDFILE *WavIn;                                     
SF_INFO WavInfo;       
/*
this is what  SF_INFO looks like under the hood

      typedef struct
      {    sf_count_t  frames ;     Used to be called samples. 
           int         samplerate ;
           int         channels ;
           int         format ;
           int         sections ;
           int         seekable ;
       } SF_INFO ;
*/

//open new sound file for reading
string InPath = "test.wav";
Wav = sf_open(InPath.c_str(), SFM_READ, &WavInfo);		
//fills up the your WavInfo struct with info about the file

//allocate memory to hold samples
in = new short[WavInfo.channels * WavInfo.frames];                          

sf_readf_short(Wav, in, WavInfo.frames);  
/*
returns audio samples in interleaved format 
ie.  (in[0] = first sample left, i[1] = first sample right) = first frame
reading as short will give you PCM samples with possible ranges from -32768 to 32768
you can also read as float or double, in which case they will be between -1, 1
*/

//allocate memory for each channel 
inleft  = new short[WavInfo.frames];
inright = new short[WavInfo.frames];

//my method for deinterleaving 2 channels, assumes WavInfo.channels == 2
for (int st=0, ml=0, mr=0; i < (WavInfo.frames * WavInfo.channels); ++i) {
    if (st & 1))  {
        inright[mr] = in[i];
        ++mr;
    }
    else {
        inleft[ml] = in[i];
        ++ml;
    }
}


//variables used to write audio file
short *outleft  = new short[WavInfo.frames];
short *outright = new short[WavInfo.frames];
short *out      = new short[WavInfo.channels * WavInfo.frames]; 
SNDFILE *WavOut;                                     
SF_INFO WavOutfo;  //my favorite word is outfo, should be in the dictionaty

//here you could process, watch out for going out of bounds with your index
for ( int i = 0; i < WavInfo.frames; ++i){
    outleft[i]  =  inleft[i] / 2;     //cut apmlitude in half
    outright[i] = inright[i] / 2;   
}

//my method of reinterleaving 2 channels
for (int st=0, ml=0, mr=0; i < (WavInfo.frames * WavInfo.channels); ++i) {
    if (st & 1))  {
        out[i] = outright[mr];
        ++mr;
    }
    else {
        out[i] = outleft[ml];
        ++ml;
    }
}

//fill in SFINFO Outfo; based on the info of the input, to prepare for writing WavOut
WavOutfo.channels   = WavInfo.channels;
WavOutfo.format     = WavInfo.format;
WavOutfo.frames     = WavInfo.frames;
WavOutfo.samplerate = WavInfo.samplerate;
WavOutfo.sections   = WavInfo.sections;    
WavOutfo.seekable   = WavInfo.seekable; 

//open new wav file for writing
WavOut = sf_open("TestOut.txt", SFM_WRITE, &WavOutfo);
//write WavOut to new file
sf_writef_short(WavOut, out, WavOutfo.frames); 


//clean up
sf_close(WavOut);
sf_close(WavIn);
delete [] out;
delete [] outleft;
delete [] outright;
delete [] in;
delete [] inleft;
delete [] inright;

Last edited on
@iseepluspluse:
I appreciate the info, but my question still remains:

1
2
3
4
5
6
7
8
9
10
11
#include <windows.h> // Use windows
#include <mmsystem.h> // Use multimedia system
#include <iostream> // Use console IO
using namespace std;


HMMIO handle = mmioOpen(L"test.wav", 0, MMIO_READ);

if (!handle) {
MessageBox(Handle,"Error opening file.","Error Message", 0);
return;}


At the beginning of the if statement MSVC++ is underlining the "if" and giving this error:
Error: expected a declaration
To my rookie eyes everything looks fine... any thoughts?
Last edited on
You have to put the code inside a function.
Like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <windows.h>
#include <tchar.h>
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
HMMIO handle = mmioOpen(TEXT("test.wav"), 0, MMIO_READ);

if (!handle) {
MessageBox(NULL, TEXT("Error opening file."), TEXT("Error Message"), MB_ICONERROR);
return 1;
} else {
MessageBox(NULL, TEXT("success opening file."), TEXT("Error Message"), MB_ICONINFORMATION);
}
return 0;
}


There is no need to include mmsystem.h and please note that function mmioOpen() is deprecated, use CreateFile() instead.
CreateFile()? Just when I was starting to understand the mmioOpen and mmioRead functions. Is the mmsystem.h outdated. I want to open a wav and pass its data chunk to an array.
Just did a little reading at Microsoft, I guess mmioOpen() has been depricated like modoran stated. I looked up mmioRead() and it didn't say anything about that function being depricated. I guess I need to look up mmioDescend() and mmioAscend().

I also need to learn how to use CreateFile(). If anyone has any tips for using this function, it would be greatly appreciated.

Thanks to everyone for helping
Chris
Topic archived. No new replies allowed.