handmade.network » Wiki » Audio API Examples

PulseAudio

 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
// Build with: gcc sound.c -o sound -lm -lpulse -lpulse-simple

#include <stdlib.h>
#include <pulse/simple.h>

#define SAMPLE_RATE  (44100)
#define CHANNELS     (2)

int main(int argc, char **argv) {
    static const pa_sample_spec streamFormat = {
        .format = PA_SAMPLE_S16LE,
        .rate = SAMPLE_RATE,
        .channels = CHANNELS,
    };

    pa_simple *device = pa_simple_new(NULL, NULL, PA_STREAM_PLAYBACK, NULL, 
            "playback", &streamFormat, NULL, NULL, NULL);

    while (1) {
        uint16_t buffer[1024];

        for (int i = 0; i < 512; i++) {
            buffer[i * 2 + 0] = rand();
            buffer[i * 2 + 1] = rand();
        }

        pa_simple_write(device, buffer, 1024, NULL);
    }

    pa_simple_drain(device, NULL);

    return 0;
}

ALSA

 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
#if 0
gcc $0 -o ${0%%.*} -lasound -lm
exit
#endif
#include <math.h>
#include <stdint.h>
#include <alsa/asoundlib.h>

#define SAMPLE_RATE  (48000)
#define CHANNELS     (2)
#define BUFFER_SIZE  (1000)

int main(void) {
    snd_pcm_t* pcm;
    snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, 0);
    snd_pcm_set_params(pcm,
                       SND_PCM_FORMAT_S16_LE,
                       SND_PCM_ACCESS_RW_INTERLEAVED,
                       CHANNELS,
                       SAMPLE_RATE,
                       1,
                       16667);

    int16_t buffer[BUFFER_SIZE];

    const float nfreq = (M_PI * 2.0) / (float) SAMPLE_RATE;
    const float vol   = (1 << 15) * 0.5;
    const float note  = 440.0;
    float ctr = 0.0;

    for(;;) {
        for(int i = 0; i < BUFFER_SIZE; i += 2) {
            buffer[i+0] = buffer[i+1] = vol * sinf(note * nfreq * ctr++);
        }
        snd_pcm_writei(pcm, buffer, BUFFER_SIZE / CHANNELS);
    }
}

SDL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SDL_Init(... | SDL_INIT_AUDIO | ...);

int audioDevicesLength = SDL_GetNumAudioDevices(0);

SDL_AudioSpec desiredAudioFormat = {}, obtainedAudioFormat;
desiredAudioFormat.freq = 44100;
desiredAudioFormat.format = AUDIO_F32;
desiredAudioFormat.channels = 2;
desiredAudioFormat.samples = 4096;
desiredAudioFormat.callback = [] (void *userData, uint8_t *stream, int length) {
    for (int i = 0; i < length; i++) {
        stream[i] = rand();
    }
};

bool foundAudioDevice = false;

for (int i = 0; i < audioDevicesLength; i++) {
    SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(i, 0), 0, 
            &desiredAudioFormat, &obtainedAudioFormat, 0);
    if (!audioDevice) continue;
    SDL_PauseAudioDevice(audioDevice, 0);
    break;
}