Mercurial > hg > audiostuff
diff intercom/oss.cpp @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/oss.cpp Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,90 @@ +/* oss.cpp + * + * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). + * All Rights Reserved. + * + * Open Sound System functions + * + * Version 0.3 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +/* Error handling */ +#include <assert.h> +#include <errno.h> +extern int errno; + +/* low level io */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +/* OSS, see www.4front-tech.com/pguide/index.html */ +#include <sys/soundcard.h> + +#include "oss.h" +#include "intercomd.h" + +int audio_init(char *pathname, int channels_, int mode) +{ +/* Using OSS is simple in theory. The application just: + * Opens the device. + * Optional turns on full duplex + * Sets fragment size if necessary + * Sets number of channels, sample format and sampling rate + * Starts reading and/or writing the device + * + * Linux ALSA dmix note: To allow dmix simultaneous playback of + * different PCM-out, do not open OSS in full duplex mode. Open two file + * descriptors instead. + */ + // fprintf(stderr, "OSS Header SOUND_VERSION = %x\n", SOUND_VERSION); + + int audio_fd = open(pathname, mode); + return_if(audio_fd < 0, -1); + + fprintf(stderr, "audio_init() mode = %d\n", mode); + + int sound_version = 0; + ioctl(audio_fd, OSS_GETVERSION, &sound_version); + // fprintf(stderr, "OSS Driver SOUND_VERSION = %x\n", SOUND_VERSION); + + ioctl(audio_fd, SNDCTL_DSP_SETDUPLEX, 0); + + /* The 16 most significant bits (MMMM) determine maximum number of + * fragments. By default the driver computes this based on available + * buffer space. + * The minimum value is 2 and the maximum depends on the situation. + * Set MMMM=0x7fff if you don't want to limit the number of fragments + */ + int frag = AUDIOBUFS << 16 | FRAGSIZELD; + if (2 == channels_) { + ++frag; // double FRAGSIZE in stereo mode + } + int frag_ = frag; + ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag); + // fprintf(stderr, "SETFRAGMENT=0x%x\n", frag); + assert_errno(frag_ == frag); + + int format = FORMAT_OSS; + ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); + assert_errno(format == FORMAT_OSS); + + int channels = channels_; + ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels); + assert_errno(channels_ == channels); + // fprintf(stderr, "SNDCTL_DSP_CHANNELS=%d\n", channels); + + int rate = RATE; + ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); + assert_errno(RATE == rate); + // fprintf(stderr, "mode=%d SNDCTL_DSP_SPEED=%d\n", mode, rate); + + fprintf(stderr, "\n"); + return audio_fd; +}