I am developing an acoustic simulation program. I can calculate the pressure wave (in Pa), but I cannot play it on my MacBook Pro. I'm using a helper lib miniaudio
.
My questions are:
What is the input format of PC sound card? I mean, Is it correct to write a discretized sound pressure wave, which represented in physical unit $Pa$, into the buffer of sound card, and expect a proper behavior? (for general developement, or my current helper library selection
miniaudio
)After search for quite a while, I still cannot find any useful resource for audio development. How can I find a development manual?
At this moment, my project works in cpp
. Thanks!
CodePudding user response:
1. Units of computer audio samples
Computer audio devices usually accept as input some form of linear pulse-code modulation. In such a format, to a first approximation, each sample represents a number in the range -1 to 1 that indicates the physical position of the cone of a loudspeaker within its travel range, generating audible noise as it moves back and forth.
The physical cone position correlates with the variations in air pressure known as "sound", since it is the source of the pressure variations, but computer audio formats do not directly deal with pressure in Pascals or whatever. You'll need to convert air pressure values to cone travel positions somehow, but doing so with high accuracy is a topic beyond the scope of Stack Overflow. (You could ask on Physics.SE.) A quick and dirty method is to just map whatever range of values you have to [-1,1] in the obvious way.
2. Generating audio with miniaudio
The miniaudio library has good documentation to get you started. The simple_playback_sine.c
example demonstrates using the low-level API, in which individual audio samples are computed and passed to the audio device for playback. However, that sample also uses the wa_waveform
API, making it just a bit more complicated than necessary.
So, I created a simplified example I called simple_playback_woowoo.c
that computes the sample values directly. The key parts are:
Use
ma_device_start
and its prerequisites to arrange for a callback,data_callback
, to be invoked every time the audio device is ready for another short clip of audio to play.In
data_callback
, populate thepOutput
array with sample values. I configured it to use thema_format_f32
format, with two channels (stereo), sopOutput
is an array of pairs offloat
sample values in [-1,1]. TheframeCount
parameter says how many frames (pairs of samples) are required.I wrote a very simple sine wave generator that is the source of the samples. For fun, I also made the frequency vary over time using the same wave generator logic, so it makes a "woowoo" sound.