Communicating with Sound Card

Started by
22 comments, last by Kylotan 16 years, 7 months ago
Hi, I'm attempting to create a type of sound library in C++. I think I've got a pretty good idea on how to do this, but I need to learn how to communicate with and send bytes to the sound card (Sound Blaster, I suppose) to be played. Can anyone direct me to a tutorial on how to do this or give any tips? Thanks.
Advertisement
Why do you need to communicate directly with a specific sound card? Are you using DOS? If not, what OS are you using? Either way there is a ton of information for you out there, but you need to be more specific.

Cheers
Perhaps that was a little vague. Sorry, I'll explain:

I would like to manipulate sound data in real time. In order to do this, I need to be able to directly control the bytes of sound data and send them to the speaker.

In other words, if I have data:

A5 ED 4A ED B2 EE 2D EE (in hexadecimal)

I want to be able to run algorithms on that data and then directly play it by sending that data to the speakers.

I'm personally running Vista, but of course I'd expect this to be compatible with more than Vista.
Well, you could use DirectSound.

By creating a DirectSound buffer, locking it and dumping your raw data in, you can get your sound-card to play just about anything you like. I hope you're aware, though, that at 44kHz, eight bytes will last only around a millisecond.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Thanks for the help!

About 1/44 of a millisecond, I think! [smile] However, of course, sound data is much longer than 8 bytes usually, which leads to my concern:

I want to be able to control the timing of when certain bytes are played to within milliseconds - relative to other channels. (So, for instance, I don't care when channels one and two are playing, as long as it's within +- 50 milliseconds, but I do want channel 2 to be, say, 5 milliseconds delayed from channel 1 when both are playing the same sound data) This is in order to try to create a binaural sound library.

But, with, say a data rate of 60 kb/s (too low, but fine for now), we're talking about 60 bytes per millisecond! Is that too fast to consider fine-tuning the timing on the fly by creating a buffer? I mean, that's 60 bytes a millisecond flowing into the buffer! [wow]
Quote:Original post by Phyrrus52
But, with, say a data rate of 60 kb/s (too low, but fine for now), we're talking about 60 bytes per millisecond! Is that too fast to consider fine-tuning the timing on the fly by creating a buffer? I mean, that's 60 bytes a millisecond flowing into the buffer! [wow]

Well, I can't imagine you'd be doing yourself any favours by attempting to lock and unlock the buffer every millisecond, for the sake of 60 bytes, but if you implement a write-cache, there should be no trouble. In system memory, store up as much audio data from the stream as is feasible and write these batches to the sound buffer (in a single contiguous copy operation) periodically - one lock/unlock per second would be fine. The data throughput of memory-writes and the motherboard buses is far in excess of 60kB/s (we're talking several GB/s) so I really wouldn't worry about that.

Today's computers are capable of dithering and pumping a real-time audio stream at 44.8kHz without breaking an idle sweat. Testament to this is the fact that the data can further be FFTed, processed in a dozen different ways and IFFTed prior to dithering without pushing the CPU out of its comfort zone.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
(I'm also working on this with Phyrrus52.)

We plan to store sound data in an array of bytes. The way we will achieve the binaural effect (as well as the doppler effect) is to constantly stream the bytes to the sound card except rather than just sending something like
SoundData[time]
we would send
SoundData[time-(distance/SpeedOfSound)]
Of course, we would send this two times: one for each channel and the distance is measured from the source of the sound to each "ear". Also, the distance/SpeedOfSound will be interpolated from previous position to current position.

Anyways, assuming that the time of each game cycle is 20ms, at 60kbps that would mean sending 3,000 bytes to the sound card every 20ms, per channel, per sound playing. So if 10 sound were playing using both channels, that would be sending nearly 3MB to the sound card each second (if I understand correctly and am not missing some other way to do this).

Anyways, I'll edit this when I get home to actually ask something...
Quote:Original post by Gumgo
Anyways, assuming that the time of each game cycle is 20ms, at 60kbps that would mean sending 3,000 bytes to the sound card every 20ms, per channel, per sound playing. So if 10 sound were playing using both channels, that would be sending nearly 3MB to the sound card each second (if I understand correctly and am not missing some other way to do this).

Sound cards use DMA, whereby you tell the sound card where to find the data and it handles the copying itself without taking up valuable CPU time. Moreover, 3 MB/sec is not a significant strain on the bus; a modern PCIe bus can carry 250 MB/sec on each lane, and the memory itself can transfer several gigabytes per second.
Quote:Sound cards use DMA, whereby you tell the sound card where to find the data and it handles the copying itself without taking up valuable CPU time. Moreover, 3 MB/sec is not a significant strain on the bus; a modern PCIe bus can carry 250 MB/sec on each lane, and the memory itself can transfer several gigabytes per second.

Oh good, then no problems there.

Only one more thing:
Quote:Well, I can't imagine you'd be doing yourself any favours by attempting to lock and unlock the buffer every millisecond, for the sake of 60 bytes, but if you implement a write-cache, there should be no trouble. In system memory, store up as much audio data from the stream as is feasible and write these batches to the sound buffer (in a single contiguous copy operation) periodically - one lock/unlock per second would be fine.

Hmm, maybe I'm not understanding this but doesn't that mean that the sound would be delayed by one second? We were planning on sending data to the sound card every 20ms (the length of the game loop).
Check this out: (Google rocks!)

http://www.ddj.com/184410687

it's an old article, but worth a look.

This topic is closed to new replies.

Advertisement