|
Packit |
c32a2d |
/*
|
|
Packit |
c32a2d |
hp: audio output for HP-UX
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
copyright ?-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
|
|
Packit |
c32a2d |
see COPYING and AUTHORS files in distribution or http://mpg123.org
|
|
Packit |
c32a2d |
initially written by Michael Hipp
|
|
Packit |
c32a2d |
*/
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
#include "out123_int.h"
|
|
Packit |
c32a2d |
#include <fcntl.h>
|
|
Packit |
c32a2d |
#include <sys/audio.h>
|
|
Packit |
c32a2d |
#include "debug.h"
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int set_rate(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if(ao->rate >= 0) {
|
|
Packit |
c32a2d |
return ioctl(ao->fn,AUDIO_SET_SAMPLE_RATE,ao->rate);
|
|
Packit |
c32a2d |
} else {
|
|
Packit |
c32a2d |
return 0;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int set_channels(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if(ao->channels<0) return 0;
|
|
Packit |
c32a2d |
return ioctl(ao->fn,AUDIO_SET_CHANNELS,ao->channels);
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int set_format(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
int fmt;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
switch(ao->format) {
|
|
Packit |
c32a2d |
case -1:
|
|
Packit |
c32a2d |
case MPG123_ENC_SIGNED_16:
|
|
Packit |
c32a2d |
default:
|
|
Packit |
c32a2d |
fmt = MPG123_ENC_LINEAR16BIT;
|
|
Packit |
c32a2d |
break;
|
|
Packit |
c32a2d |
case MPG123_ENC_UNSIGNED_8:
|
|
Packit |
c32a2d |
error("unsigned 8 bit linear not supported");
|
|
Packit |
c32a2d |
return -1;
|
|
Packit |
c32a2d |
case MPG123_ENC_SIGNED_8:
|
|
Packit |
c32a2d |
error("signed 8 bit linear not supported");
|
|
Packit |
c32a2d |
return -1;
|
|
Packit |
c32a2d |
case MPG123_ENC_ALAW_8:
|
|
Packit |
c32a2d |
fmt = MPG123_ENC_ALAW;
|
|
Packit |
c32a2d |
break;
|
|
Packit |
c32a2d |
case MPG123_ENC_ULAW_8:
|
|
Packit |
c32a2d |
fmt = MPG123_ENC_ULAW;
|
|
Packit |
c32a2d |
break;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
return ioctl(ao->fn,AUDIO_SET_DATA_FORMAT,fmt);
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int get_formats(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
return MPG123_ENC_SIGNED_16;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int reset_parameters(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
int ret;
|
|
Packit |
c32a2d |
ret = set_format(ai);
|
|
Packit |
c32a2d |
if(ret >= 0)
|
|
Packit |
c32a2d |
ret = set_channels_hp(ai);
|
|
Packit |
c32a2d |
if(ret >= 0)
|
|
Packit |
c32a2d |
ret = set_rate_hp(ai);
|
|
Packit |
c32a2d |
return ret;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int open_hp(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
struct audio_describe ades;
|
|
Packit |
c32a2d |
struct audio_gain again;
|
|
Packit |
c32a2d |
int i,audio;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
ao->fn = open("/dev/audio",O_RDWR);
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
if(ao->fn < 0)
|
|
Packit |
c32a2d |
return -1;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_DESCRIBE,&ades);
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
if(ao->gain != -1)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if(ao->gain > ades.max_transmit_gain)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
error("your gainvalue was to high -> set to maximum.");
|
|
Packit |
c32a2d |
ao->gain = ades.max_transmit_gain;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
if(ao->gain < ades.min_transmit_gain)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
error("your gainvalue was to low -> set to minimum.");
|
|
Packit |
c32a2d |
ao->gain = ades.min_transmit_gain;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_GET_GAINS,&again);
|
|
Packit |
c32a2d |
again.cgain[0].transmit_gain = ao->gain;
|
|
Packit |
c32a2d |
again.cgain[1].transmit_gain = ao->gain;
|
|
Packit |
c32a2d |
again.channel_mask = AUDIO_CHANNEL_0 | AUDIO_CHANNEL_1;
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_SET_GAINS,&again);
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
if(ao->flags != -1)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if(ao->flags & OUT123_INTERNAL_SPEAKER)
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_SET_OUTPUT,OUT123_SPEAKER);
|
|
Packit |
c32a2d |
else if(ao->flags & OUT123_HEADPHONES)
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_SET_OUTPUT,OUT123_HEADPHONE);
|
|
Packit |
c32a2d |
else if(ao->flags & OUT123_LINE_OUT)
|
|
Packit |
c32a2d |
ioctl(ao->fn,AUDIO_SET_OUTPUT,OUT123_LINE);
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
if(ao->rate == -1)
|
|
Packit |
c32a2d |
ao->rate = 44100;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
for(i=0;i
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if(ao->rate == ades.sample_rate[i])
|
|
Packit |
c32a2d |
break;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
if(i == ades.nrates)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
error1("Can't set sample-rate to %ld.\n",ao->rate);
|
|
Packit |
c32a2d |
i = 0;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
if(reset_parameters(ai) < 0)
|
|
Packit |
c32a2d |
return -1;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
return ao->fn;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int write_hp(out123_handle *ao,unsigned char *buf,int len)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
return write(ao->fn,buf,len);
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int close_hp(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
close (ao->fn);
|
|
Packit |
c32a2d |
return 0;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static void flush_hp(out123_handle *ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
static int init_hp(out123_handle* ao)
|
|
Packit |
c32a2d |
{
|
|
Packit |
c32a2d |
if (ao==NULL) return -1;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
/* Set callbacks */
|
|
Packit |
c32a2d |
ao->open = open_hp;
|
|
Packit |
c32a2d |
ao->flush = flush_hp;
|
|
Packit |
c32a2d |
ao->write = write_hp;
|
|
Packit |
c32a2d |
ao->get_formats = get_formats_hp;
|
|
Packit |
c32a2d |
ao->close = close_hp;
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
/* Success */
|
|
Packit |
c32a2d |
return 0;
|
|
Packit |
c32a2d |
}
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
/*
|
|
Packit |
c32a2d |
Module information data structure
|
|
Packit |
c32a2d |
*/
|
|
Packit |
c32a2d |
mpg123_module_t mpg123_output_module_info = {
|
|
Packit |
c32a2d |
/* api_version */ MPG123_MODULE_API_VERSION,
|
|
Packit |
c32a2d |
/* name */ "hp",
|
|
Packit |
c32a2d |
/* description */ "Output audio HP-UX",
|
|
Packit |
c32a2d |
/* revision */ "$Rev:$",
|
|
Packit |
c32a2d |
/* handle */ NULL,
|
|
Packit |
c32a2d |
|
|
Packit |
c32a2d |
/* init_output */ init_hp,
|
|
Packit |
c32a2d |
};
|