Click to See Complete Forum and Search --> : Soundcard Access denied?
Gyannea
February 28th, 2003, 04:18 PM
Can anyone tell me why I get an "access denied" error when I try to open the sound card? I use:
waveformatex.wFormatTag = WAVE_FORMAT_PCM;
waveformatex.nChannels = 1;
waveformatex.nSamplesPerSec = wave.samplerate; // 24000
waveformatex.nAvgBytesPerSec =
wave.samplerate * wave.bytes_per_sample; //48000
waveformatex.nBlockAlign =
wave.bytes_per_sample; //2
waveformatex.wBitsPerSample =
(wave.bytes_per_sample << 3); // 16
waveformatex.cbSize = 0;
status = waveOutOpen(&hsoundcardout, 0, &waveformatex, (DWORD)SendWave, 0, CALLBACK_FUNCTION);
"SendWave" is my callback function given below:
void CALLBACK SendWave(HWAVEOUT hwindow, UINT msg,
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
switch(msg)
{
case MM_WOM_OPEN:
....
}
}
The "access denied" error occurs when the "waveOutOpen()" function is executed. Changing the device ID to "WAVE_MAPPER" changes nothing.
Any help or ideas would be greatly appreciated!
I'M STUCK!!!
Horst
March 10th, 2003, 06:18 AM
Does your card support these settings? Check waveOutGetDevCaps first! You won't get a working device with WAVE_FORMAT_PCM if there is no standard setting available for your device.
By the way I have had a terrible experience with CALLBACK and multimedia wave functions. If it works for you then please send me an answer how you did it. (I would still have a use for callbacks in my programm). I solved it with a polling thread.
Hope this helped.
Horst
Gyannea
March 12th, 2003, 08:10 AM
Horst,
I have gotten them to work. However, I don't know what you need. My application loads a double sound buffer with generated audio data and sends it out to the sound card. While one buffer is sending, the other is loading. The callback function handles the MM_WOM_DONE message in the classic manner.
I have encapsulated the whole mess in a class by placing a pointer to the instance in the WAVEHDR structure, so I can branch out to instance-dependent functions from the single static callback.
Horst
March 13th, 2003, 02:28 AM
Hello Gyannea,
my problem has been the fact that when I recorded data and I got the MM_WIM_DATA, I could not add another buffer to get new data when using a callback.
(It looked some how as if the api calls got stuck in because of critical sections or something like that.)
But I'm not shure whether this problem aplies to output as well.
Do you record in your application as well?
(Mine are a bit tricky in because of being real time communication applications with multiple threads to store, load or transmit voice data.)
Gyannea
March 13th, 2003, 06:08 AM
No I do not record data...YET. I am starting to do that now as I am also writing a radio communications program and I need to receive data as well as send it. It's just a lot easier to write the sending part first, then you have something to test your receiving code.
I have not done anything yet, but in theory I am hoping it works the same way as the transmitting but in reverse. Doesn't one setup a double buffer and when buffer 1 is filled the sound card sends a message that it is filled, buffer 2 starts getting filled and you unload buffer 1 in response to the message and do whatever you are going to do with it and the process continues.
Sounds good in theory in any case! In practice...?
Horst
March 14th, 2003, 02:13 AM
Yes it works like this. But,...
...as I said I had big troubles when I tried to add the second buffer after having it used once (when using callback) but maybe it works with you, I'm not perfect after all.
It helps to have more than one buffer too. (my experience)
It's simply that your second buffer may still be in work by another part of your programme (I had some problem like that).
My solution as been a polling thread with an event to trigger reading data and using a little array of buffers (circular stack).
RockNix
March 14th, 2003, 07:01 AM
@horst:
i dont know if i understand your problem right but ...
to use callback for MM_WIM_DATA you should add at least 2 (!) empty buffers before start recording. if one buffer returns via callback you have time to store the data come within while the other buffer is still used by the device. make sure you return the first buffer back to the device before the other one returned to your application.
hope it helps ...
Gyannea
March 15th, 2003, 06:47 AM
That's the classic sending process .... in reverse, and that's exactly what I intend to do. The only concern I have is the latency time during buffer transition...when one buffer finishes and another starts; and that we can't do anything about, its' all in Windows.
If I am sampling at 44 KHz and generate a continuous sine wave and buffer one is sending, finishes and buffer 2 starts, does my sine wave miss a pulse during the transition just because of the Windows overhead in handling the waveOutX and waveInX API functions?
Horst
March 18th, 2003, 02:24 AM
Not as long as at least one buffer is active for taking data. That means if you can be sure that you add an empty buffer before the asctive one got filled you can be sure that you will not miss a single pulse.
So to say it's coming down to three factors: buffer size, number of buffers and CPU power.
Buffer size determines how long you can sample with one buffer.
The number of buffers gives you increased security if you need relatively small buffers. (As I do)
CPU power tells how quick buffers can be processed and reactivated.
But in the end it's all a matter of trying which combination is best for your application.
Gyannea
March 18th, 2003, 05:52 AM
Horst,
From my DOS days I recall that once the buffer was filled the sound card triggered an interrupt and the next buffer (waiting) was ready on the DMA channel. The Sound card also had to know that the buffer was ready so there must be some overhead here; that is the sound card can transfer received digitized data to the buffer with less overhead than when the switching takes place.
Now Windows buries all that stuff with its waveInX() functions and Windows is not known to be particularily efficient. I don't know what that API function does and how much overhead it contains when it actually gets down to do the work. What worries me most is the introduction of Direct Sound to get around the performance problems of Windows.
I hope NOT to have to use Direct Sound since it involves setting up Direct X on host computers that may or may not have it. On the other hand, I wonder what Direct Sound has that waveInX() and waveOutX() don't have? Do you have any idea? Game writers (who really need maximum performance) seem to religously stick to Direct X and its subsidiaries.
I do know on the write side if the buffers are too short (and switches therefore many) that I get clicks. But until I get an oscilloscope on the output end and/or my receive section working, I won't know Window's API limitations!
BTW, your knowledge and insight have been very helpful and I appreciate it! Thanks!
RockNix
March 18th, 2003, 06:11 AM
>>>On the other hand, I wonder what Direct Sound has that
>>>waveInX() and waveOutX() don't have?
the most important difference between wave-API and direct- sound is ds uses stream-io while API uses buffered-io for playback ... stream-io allows smaller latency between sending and hearing the sound due to smaller size of data to be written to the driver which is placed in a kind of ring-io. while performance breaks by using buffers about 1k-samples within api-functions ds allows data sizes smaller than 256 samples. actually it is the same procedure as done by steinbergs ASIO drivers.
of course there are more differences between ds and api like HAL and things like that but for simple playback IMO it is the most important thing ...
Gyannea
March 18th, 2003, 08:23 AM
RockNix,
My application is for sending and receiving data-coded signals over radio; bit values are coded as pure sinusoidal tones which last a specific time. On HF radio these tones switch at 100 baud and on VHF at 1200 baud. Gaps in the generated sine waves cause not only timing errors but spikes (any discontinuities) which generate a wide bandwidth signal.
That is why I am concerned about having the best continuity in sent and received signals. If I am using 44KHz sampling with a buffer size that allows 1000 samples, I need sample 1001 sent to the DAC 1/44KHz of a second later, such that the time interval between sample 999 and 1000 is the same as between sample 1000 and 1001. I am hoping that the waveInX and waveOutX functions can handle that!
I will have to do some (a lot?) DSP work on the incoming data so when a buffer is returned, I will empty it and 'waveIn' it again and work on it somewhere else...but I guess that's kind of obvious.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.