Development:Tutorials:SetupAudio
From DingooWiki
[edit] Using SDL
- Sample format is restricted to AUDIO_S16.
- Frequencies that works: 44100, 22050, 16000, 8000.
As normal no need it any special setting, a simple example:
SDL_AudioSpec *desired, *obtained;
desired = (SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
obtained = (SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
desired->freq = 44100;
desired->format = AUDIO_S16;
desired->channels = 2;
desired->samples = audio_align_samples(desired->freq / 50);
desired->callback = SoundUpdate;
desired->userdata = NULL;
if (SDL_OpenAudio(desired, obtained) < 0) {
fprintf(stderr, "Could not open audio: %s\n", SDL_GetError());
return 0;
}
free(desired);
audio_spec = obtained;
printf("SDL AUDIO - INIT AT: %i\n",audio_spec->size);
[edit] Using direct access to DSP
Global variables and includes:
[...] #include <sys/ioctl.h> #include <pthread.h> #include <stdbool.h> #include <sys/poll.h> #include <sys/soundcard.h> #include <sys/mman.h> static pthread_t sound_thrd_loop_fill = (pthread_t)0; static bool sound_running = false; static bool sfx_thread_paused = true; int sound_dev = -1; int mixer_dev = -1; int vol_left = 0, vol_right = 0; audio_buf_info sound_buf_info; int sound_fmt, sound_chans; long sound_rate; unsigned char *sound_buffer; [...]
Need it fuctions:
int sound_set_volume() {
if (vol_left < 0) vol_left = 0;
if (vol_left > 100) vol_left = 100;
if (vol_right < 0) vol_right = 0;
if (vol_right > 100) vol_right = 100;
int vol = ((vol_left << 8) | vol_right);
return (ioctl(mixer_dev, MIXER_WRITE(SOUND_MIXER_VOLUME), &vol) == -1
|| ioctl(mixer_dev, MIXER_WRITE(SOUND_MIXER_PCM), &vol) == -1) ? -1 : 0;
}
int sound_reset() {
return ioctl(sound_dev, SNDCTL_DSP_RESET, 0);
}
int sound_set_format(int fmt) {
if (fmt != AFMT_S16_LE) return -1; /* sorry, but this library depends on it */
sound_reset();
if (ioctl(sound_dev, SNDCTL_DSP_SETFMT, &fmt) == -1) return -1;
if (ioctl(sound_dev, SNDCTL_DSP_GETOSPACE, &sound_buf_info) == -1) return -1;
sound_fmt = fmt;
return 0;
}
int sound_set_channels(int chans) {
if (sound_chans == chans) return 0;
sound_reset();
if (ioctl(sound_dev, SNDCTL_DSP_CHANNELS, &chans) == -1) return -1;
if (ioctl(sound_dev, SNDCTL_DSP_GETOSPACE, &sound_buf_info) == -1) return -1;
sound_chans = chans;
return 0;
}
int sound_set_rate(long rate) {
if (sound_rate == rate) return 0;
sound_reset();
if (ioctl(sound_dev, SNDCTL_DSP_SPEED, &rate) == -1) return -1; if (ioctl(sound_dev, SNDCTL_DSP_GETOSPACE, &sound_buf_info) == -1) return -1; sound_rate = rate; return 0; }
int sound_set_buffer_size(int max_frags, int size) {
sound_reset();
int frag = (max_frags << 16) | size;
if (ioctl(sound_dev, SNDCTL_DSP_SETFRAGMENT, &frag) == -1) return -1;
if (ioctl(sound_dev, SNDCTL_DSP_GETOSPACE, &sound_buf_info) == -1) return -1;
return 0;
}
int sound_get_buffer_remaining() {
audio_buf_info info;
if (ioctl(sound_dev, SNDCTL_DSP_GETOSPACE, &info) == -1) return 0;
return sound_buf_info.bytes - info.bytes;
}
int sound_set_nonblock() {
return ioctl(sound_dev, SNDCTL_DSP_NONBLOCK, 0);
}
Setup DSP Audio:
if ((sound_dev = open("/dev/dsp", O_WRONLY)) == -1) goto error;
if (sound_set_buffer_size(3, 15)) goto error; /* these values are based on several tests; not accurate */
if (sound_set_format(AFMT_S16_LE) || sound_set_channels(2) || sound_set_rate(44100)) goto error; /* FIXME */
sound_running = true;
sfx_thread_paused = false;
if (!sound_thrd_loop_fill && pthread_create(&sound_thrd_loop_fill, NULL, sound_loop_fill, NULL)) goto error;
if ((mixer_dev = open("/dev/mixer", O_RDONLY)) == -1) goto error;
An audio thread example:
static void *sound_loop_fill(void *user_data) {
while (sound_running) {
struct pollfd fds[1];
fds[0].fd = sound_dev;
fds[0].events = POLLOUT;
while (!poll(fds, sizeof(fds)/sizeof(fds[0]), 0)) usleep(1000);
if (sfx_thread_paused) continue;
write(sound_dev, mySoundBuffer, 1024); } return NULL; }
Close Sound DSP and Mixer:
sound_running = false; if (sound_thrd_loop_fill && pthread_join(sound_thrd_loop_fill, NULL)) return; sound_thrd_loop_fill = (pthread_t)0; if (sound_dev != -1 && (close(sound_dev) || ((sound_dev = -1) & 0))) return; if (mixer_dev != -1 && (close(mixer_dev) || ((mixer_dev = -1) & 0))) return;

