"Fossies" - the Fresh Open Source Software archive 
Member "tplay-0.6.1/audio_oss.c" of archive tplay-0.6.1.tar.gz:
/*
* tplay - buffered audio player
*
* (c) 1997 ilkka karvinen <ik@iki.fi>
*
* Copyright under the GNU GENERAL PUBLIC LICENSE
* (see the file COPYING in this directory)
*
*
* common functions for audio in OSS/API machines
*/
#include <stdarg.h>
#include "common.h"
#include "audio_oss.h"
void open_audio()
{
int block_size;
char *device;
/* Use predefined audio device if info.device is not set */
/* (is NULL). Otherwise use user given audio device. */
if (info.device == NULL)
device = AUDIO_DEVICE;
else
device = info.device;
if ((info.audio_fd = open(device, O_WRONLY, 0)) == -1)
errdie("Cannot open audio device");
ioctl(info.audio_fd, SNDCTL_DSP_GETBLKSIZE, &block_size);
/* Audio device driver may give exotic audio buffer size */
/* for some adapters, we'd better set limits to it */
/* In the newer sound drivers, this should work according to */
/* 4Front documents */
if (block_size < MIN_BLOCK_SIZE)
block_size = MIN_BLOCK_SIZE;
else if (block_size > MAX_BLOCK_SIZE)
block_size = MAX_BLOCK_SIZE;
/* Set audio block size and number of blocks */
info.blocksize = block_size;
}
void set_audio_parameters()
{
int format, stereo, stereo0, speed0;
double percentage;
/* sync_audio(); */
reset_audio();
stereo = 1;
switch(info.channels) {
case 1 :
stereo = 0;
break;
case 2 :
stereo = 1;
break;
default :
if (!info.force)
errdie("Invalid number of channels");
break;
}
/* Set format */
format = info.encoding;
if (ioctl(info.audio_fd, SNDCTL_DSP_SETFMT, &format) == -1)
errdie("SNDCTL_DSP_SETFMT");
if (!info.force && (format != info.encoding))
errdie("Audio device doesn't support this precision");
/* Set stereo mode */
stereo0 = stereo;
if (ioctl(info.audio_fd, SNDCTL_DSP_STEREO, &stereo0) == -1)
errdie("SNDCTL_DSP_STEREO");
if (!info.force && (stereo0 != stereo))
errdie("Audio device doesn't support stereo mode");
info.channels = stereo0 + 1;
/* Set sampling speed */
speed0 = info.speed;
if (ioctl(info.audio_fd, SNDCTL_DSP_SPEED, &speed0) == -1)
errdie("SNDCTL_DSP_SPEED");
/* Q: What to do if you cannot tune audio-card on exact speed? */
/* Author: Jerko Golubovic <jerko.golubovic@public.srce.hr> */
/* */
/* Variant A: you force playing even if speed is not exact */
/* - Don't say anything - user choosed this way with force option */
/* We assume he/she knows what this means..... */
/* - Just skip and go ahead, jump :) (100.000 Lemmings can't be wrong :) )*/
if (!info.force) {
/* Variant B: you don't force playing if speed is not exact */
/* If speed doesn't match, die and inform user about alternative */
if (speed0 != info.speed) {
fprintf(stderr, "Audio device doesn't support requested speed\n");
fprintf(stderr, " -> Requested: %d Hz, Got: %d Hz", info.speed, speed0);
percentage = ( (speed0-info.speed)/(double)info.speed ) * 100.0;
fprintf(stderr, " (%+dHz/%+.2f%%) \n", speed0-info.speed, percentage);
errdie("Use --force or -f in command-line to override.");
}
/* If they match, you have: */
/* a) good audio-card */
/* b) reasonable requirements */
/* Just proceed and be happy about. Don't bother user with messages :) */
}
info.speed = speed0;
/* sync_audio(); */
}
void sync_audio(void)
{
if (ioctl(info.audio_fd, SNDCTL_DSP_SYNC, NULL) < 0)
errdie("Audio sync failed");
}
void reset_audio(void)
{
if (ioctl(info.audio_fd, SNDCTL_DSP_RESET, 0) < 0)
errdie("Audio reset failed");
}
void post_audio(void)
{
if (ioctl(info.audio_fd, SNDCTL_DSP_POST, 0) < 0)
errdie("Audio reset failed");
}
void close_audio(void)
{
if (info.audio_fd != -1) {
close(info.audio_fd);
info.audio_fd = -1;
}
}