aboutsummaryrefslogtreecommitdiffhomepage
path: root/libao2/ao_sun.c
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@mplayer2.org>2012-07-28 20:20:17 +0200
committerGravatar wm4 <wm4@mplayer2.org>2012-07-28 20:44:59 +0200
commit16145ff43fd92947cb8fe301ebce46e7be52a9fb (patch)
tree5a5ade633d922f416d3b1c7c68e8aff878da9a8f /libao2/ao_sun.c
parentf03eed6469e34a5bff975ed43292016a621296ea (diff)
libvo, libao: remove useless video and audio output drivers
Some of these have only limited use, and some of these have no use at all. Remove them. They make maintainance harder and nobody needs them. It's possible that many of the removed drivers were very useful a dozen of years ago, but now it's 2012. Note that some of these could be added back, in case they were more useful than I thought. But right now, they are just a burden. Reason for removal for each module: vo_3dfx, vo_dfbmga, vo_dxr3, vo_ivtv, vo_mga, vo_s3fb, vo_tdfxfb, vo_xmga, vo_tdfx_vid: All of these are for very specific and outdated hardware. Some of them require non-standard kernel drivers or do direct HW access. vo_dga: the most crappy and ancient way to get fast output on X. vo_aa: there's vo_caca for the same purpose. vo_ggi: this never lived, and is entirely useless. vo_mpegpes: for DVB cards, I can't test this and it's crappy. vo_fbdev, vo_fbdev2: there's vo_directfb2 vo_bl: what is this even? But it's neither important, nor alive. vo_svga, vo_vesa: you want to use this? You can't be serious. vo_wii: I can't test this, and who the hell uses this? vo_xvr100: some Sun thing. vo_xover: only useful in connection with xvr100. ao_nas: still alive, but I doubt it has any meaning today. ao_sun: Sun. ao_win32: use ao_dsound or ao_portaudio instead. ao_ivtv: removed along vo_ivtv. Also get rid of anything SDL related. SDL 1.x is total crap for video output, and will be replaced with SDL 2.x soon (perhaps), so if you want to use SDL, write output drivers for SDL 2.x. Additionally, I accidentally damaged Sun support, which made me completely remove Sun/Solaris support. Nobody cares about this anyway. Some left overs from previous commits removing modules were cleaned up.
Diffstat (limited to 'libao2/ao_sun.c')
-rw-r--r--libao2/ao_sun.c692
1 files changed, 0 insertions, 692 deletions
diff --git a/libao2/ao_sun.c b/libao2/ao_sun.c
deleted file mode 100644
index ecdb23d4af..0000000000
--- a/libao2/ao_sun.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * SUN audio output driver
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/audioio.h>
-#ifdef AUDIO_SWFEATURE_MIXER /* solaris8 or newer? */
-# define HAVE_SYS_MIXER_H 1
-#endif
-#if HAVE_SYS_MIXER_H
-# include <sys/mixer.h>
-#endif
-#ifdef __svr4__
-#include <stropts.h>
-#endif
-
-#include "config.h"
-#include "mixer.h"
-
-#include "audio_out.h"
-#include "audio_out_internal.h"
-#include "libaf/af_format.h"
-#include "mp_msg.h"
-
-static const ao_info_t info =
-{
- "Sun audio output",
- "sun",
- "Juergen Keil",
- ""
-};
-
-LIBAO_EXTERN(sun)
-
-
-/* These defines are missing on NetBSD */
-#ifndef AUDIO_PRECISION_8
-#define AUDIO_PRECISION_8 8
-#define AUDIO_PRECISION_16 16
-#endif
-#ifndef AUDIO_CHANNELS_MONO
-#define AUDIO_CHANNELS_MONO 1
-#define AUDIO_CHANNELS_STEREO 2
-#endif
-
-
-static char *sun_mixer_device = NULL;
-static char *audio_dev = NULL;
-static int queued_bursts = 0;
-static int queued_samples = 0;
-static int bytes_per_sample = 0;
-static int byte_per_sec = 0;
-static int audio_fd = -1;
-static enum {
- RTSC_UNKNOWN = 0,
- RTSC_ENABLED,
- RTSC_DISABLED
-} enable_sample_timing;
-
-
-static void flush_audio(int fd) {
-#ifdef AUDIO_FLUSH
- ioctl(fd, AUDIO_FLUSH, 0);
-#elif defined(__svr4__)
- ioctl(fd, I_FLUSH, FLUSHW);
-#endif
-}
-
-// convert an OSS audio format specification into a sun audio encoding
-static int af2sunfmt(int format)
-{
- switch (format){
- case AF_FORMAT_MU_LAW:
- return AUDIO_ENCODING_ULAW;
- case AF_FORMAT_A_LAW:
- return AUDIO_ENCODING_ALAW;
- case AF_FORMAT_S16_NE:
- return AUDIO_ENCODING_LINEAR;
-#ifdef AUDIO_ENCODING_LINEAR8 // Missing on SunOS 5.5.1...
- case AF_FORMAT_U8:
- return AUDIO_ENCODING_LINEAR8;
-#endif
- case AF_FORMAT_S8:
- return AUDIO_ENCODING_LINEAR;
-#ifdef AUDIO_ENCODING_DVI // Missing on NetBSD...
- case AF_FORMAT_IMA_ADPCM:
- return AUDIO_ENCODING_DVI;
-#endif
- default:
- return AUDIO_ENCODING_NONE;
- }
-}
-
-// try to figure out, if the soundcard driver provides usable (precise)
-// sample counter information
-static int realtime_samplecounter_available(char *dev)
-{
- int fd = -1;
- audio_info_t info;
- int rtsc_ok = RTSC_DISABLED;
- int len;
- void *silence = NULL;
- struct timeval start, end;
- struct timespec delay;
- int usec_delay;
- unsigned last_samplecnt;
- unsigned increment;
- unsigned min_increment;
-
- len = 44100 * 4 / 4; /* amount of data for 0.25sec of 44.1khz, stereo,
- * 16bit. 44kbyte can be sent to all supported
- * sun audio devices without blocking in the
- * "write" below.
- */
- silence = calloc(1, len);
- if (silence == NULL)
- goto error;
-
- if ((fd = open(dev, O_WRONLY)) < 0)
- goto error;
-
- AUDIO_INITINFO(&info);
- info.play.sample_rate = 44100;
- info.play.channels = AUDIO_CHANNELS_STEREO;
- info.play.precision = AUDIO_PRECISION_16;
- info.play.encoding = AUDIO_ENCODING_LINEAR;
- info.play.samples = 0;
- if (ioctl(fd, AUDIO_SETINFO, &info)) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- mp_tmsg(MSGT_AO, MSGL_ERR, "[AO SUN] rtsc: SETINFO failed.\n");
- goto error;
- }
-
- if (write(fd, silence, len) != len) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- mp_tmsg(MSGT_AO, MSGL_ERR, "[AO SUN] rtsc: write failed.\n");
- goto error;
- }
-
- if (ioctl(fd, AUDIO_GETINFO, &info)) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- perror("rtsc: GETINFO1");
- goto error;
- }
-
- last_samplecnt = info.play.samples;
- min_increment = ~0;
-
- gettimeofday(&start, NULL);
- for (;;) {
- delay.tv_sec = 0;
- delay.tv_nsec = 10000000;
- nanosleep(&delay, NULL);
- gettimeofday(&end, NULL);
- usec_delay = (end.tv_sec - start.tv_sec) * 1000000
- + end.tv_usec - start.tv_usec;
-
- // stop monitoring sample counter after 0.2 seconds
- if (usec_delay > 200000)
- break;
-
- if (ioctl(fd, AUDIO_GETINFO, &info)) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- perror("rtsc: GETINFO2 failed");
- goto error;
- }
- if (info.play.samples < last_samplecnt) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- mp_msg(MSGT_AO,MSGL_V,"rtsc: %d > %d?\n", last_samplecnt, info.play.samples);
- goto error;
- }
-
- if ((increment = info.play.samples - last_samplecnt) > 0) {
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- mp_msg(MSGT_AO,MSGL_V,"ao_sun: sample counter increment: %d\n", increment);
- if (increment < min_increment) {
- min_increment = increment;
- if (min_increment < 2000)
- break; // looks good
- }
- }
- last_samplecnt = info.play.samples;
- }
-
- /*
- * For 44.1kkz, stereo, 16-bit format we would send sound data in 16kbytes
- * chunks (== 4096 samples) to the audio device. If we see a minimum
- * sample counter increment from the soundcard driver of less than
- * 2000 samples, we assume that the driver provides a useable realtime
- * sample counter in the AUDIO_INFO play.samples field. Timing based
- * on sample counts should be much more accurate than counting whole
- * 16kbyte chunks.
- */
- if (min_increment < 2000)
- rtsc_ok = RTSC_ENABLED;
-
- if ( mp_msg_test(MSGT_AO,MSGL_V) )
- mp_msg(MSGT_AO,MSGL_V,"ao_sun: minimum sample counter increment per 10msec interval: %d\n"
- "\t%susing sample counter based timing code\n",
- min_increment, rtsc_ok == RTSC_ENABLED ? "" : "not ");
-
-
-error:
- free(silence);
- if (fd >= 0) {
- // remove the 0 bytes from the above measurement from the
- // audio driver's STREAMS queue
- flush_audio(fd);
- close(fd);
- }
-
- return rtsc_ok;
-}
-
-
-// match the requested sample rate |sample_rate| against the
-// sample rates supported by the audio device |dev|. Return
-// a supported sample rate, if that sample rate is close to
-// (< 1% difference) the requested rate; return 0 otherwise.
-
-#define MAX_RATE_ERR 1
-
-static unsigned
-find_close_samplerate_match(int dev, unsigned sample_rate)
-{
-#if HAVE_SYS_MIXER_H
- am_sample_rates_t *sr;
- unsigned i, num, err, best_err, best_rate;
-
- for (num = 16; num < 1024; num *= 2) {
- sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num));
- if (!sr)
- return 0;
- sr->type = AUDIO_PLAY;
- sr->flags = 0;
- sr->num_samp_rates = num;
- if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) {
- free(sr);
- return 0;
- }
- if (sr->num_samp_rates <= num)
- break;
- free(sr);
- }
-
- if (sr->flags & MIXER_SR_LIMITS) {
- /*
- * HW can playback any rate between
- * sr->samp_rates[0] .. sr->samp_rates[1]
- */
- free(sr);
- return 0;
- } else {
- /* HW supports fixed sample rates only */
-
- best_err = 65535;
- best_rate = 0;
-
- for (i = 0; i < sr->num_samp_rates; i++) {
- err = abs(sr->samp_rates[i] - sample_rate);
- if (err == 0) {
- /*
- * exact supported sample rate match, no need to
- * retry something else
- */
- best_rate = 0;
- break;
- }
- if (err < best_err) {
- best_err = err;
- best_rate = sr->samp_rates[i];
- }
- }
-
- free(sr);
-
- if (best_rate > 0 && (100/MAX_RATE_ERR)*best_err < sample_rate) {
- /* found a supported sample rate with <1% error? */
- return best_rate;
- }
- return 0;
- }
-#else /* old audioio driver, cannot return list of supported rates */
- /* XXX: hardcoded sample rates */
- unsigned i, err;
- unsigned audiocs_rates[] = {
- 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
- 27420, 32000, 33075, 37800, 44100, 48000, 0
- };
-
- for (i = 0; audiocs_rates[i]; i++) {
- err = abs(audiocs_rates[i] - sample_rate);
- if (err == 0) {
- /*
- * exact supported sample rate match, no need to
- * retry something elise
- */
- return 0;
- }
- if ((100/MAX_RATE_ERR)*err < audiocs_rates[i]) {
- /* <1% error? */
- return audiocs_rates[i];
- }
- }
-
- return 0;
-#endif
-}
-
-
-// return the highest sample rate supported by audio device |dev|.
-static unsigned
-find_highest_samplerate(int dev)
-{
-#if HAVE_SYS_MIXER_H
- am_sample_rates_t *sr;
- unsigned i, num, max_rate;
-
- for (num = 16; num < 1024; num *= 2) {
- sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num));
- if (!sr)
- return 0;
- sr->type = AUDIO_PLAY;
- sr->flags = 0;
- sr->num_samp_rates = num;
- if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) {
- free(sr);
- return 0;
- }
- if (sr->num_samp_rates <= num)
- break;
- free(sr);
- }
-
- if (sr->flags & MIXER_SR_LIMITS) {
- /*
- * HW can playback any rate between
- * sr->samp_rates[0] .. sr->samp_rates[1]
- */
- max_rate = sr->samp_rates[1];
- } else {
- /* HW supports fixed sample rates only */
- max_rate = 0;
- for (i = 0; i < sr->num_samp_rates; i++) {
- if (sr->samp_rates[i] > max_rate)
- max_rate = sr->samp_rates[i];
- }
- }
- free(sr);
- return max_rate;
-
-#else /* old audioio driver, cannot return list of supported rates */
- return 44100; /* should be supported even on old ISA SB cards */
-#endif
-}
-
-
-static void setup_device_paths(void)
-{
- if (audio_dev == NULL) {
- if ((audio_dev = getenv("AUDIODEV")) == NULL)
- audio_dev = "/dev/audio";
- }
-
- if (sun_mixer_device == NULL) {
- if ((sun_mixer_device = mixer_device) == NULL || !sun_mixer_device[0]) {
- sun_mixer_device = malloc(strlen(audio_dev) + 4);
- strcpy(sun_mixer_device, audio_dev);
- strcat(sun_mixer_device, "ctl");
- }
- }
-
- if (ao_subdevice) audio_dev = ao_subdevice;
-}
-
-// to set/get/query special features/parameters
-static int control(int cmd,void *arg){
- switch(cmd){
- case AOCONTROL_GET_VOLUME:
- {
- int fd;
-
- if ( !sun_mixer_device ) /* control function is used before init? */
- setup_device_paths();
-
- fd=open( sun_mixer_device,O_RDONLY );
- if ( fd != -1 )
- {
- ao_control_vol_t *vol = (ao_control_vol_t *)arg;
- float volume;
- struct audio_info info;
- ioctl( fd,AUDIO_GETINFO,&info);
- volume = info.play.gain * 100. / AUDIO_MAX_GAIN;
- if ( info.play.balance == AUDIO_MID_BALANCE ) {
- vol->right = vol->left = volume;
- } else if ( info.play.balance < AUDIO_MID_BALANCE ) {
- vol->left = volume;
- vol->right = volume * info.play.balance / AUDIO_MID_BALANCE;
- } else {
- vol->left = volume * (AUDIO_RIGHT_BALANCE-info.play.balance)
- / AUDIO_MID_BALANCE;
- vol->right = volume;
- }
- close( fd );
- return CONTROL_OK;
- }
- return CONTROL_ERROR;
- }
- case AOCONTROL_SET_VOLUME:
- {
- ao_control_vol_t *vol = (ao_control_vol_t *)arg;
- int fd;
-
- if ( !sun_mixer_device ) /* control function is used before init? */
- setup_device_paths();
-
- fd=open( sun_mixer_device,O_RDONLY );
- if ( fd != -1 )
- {
- struct audio_info info;
- float volume;
- AUDIO_INITINFO(&info);
- volume = vol->right > vol->left ? vol->right : vol->left;
- if ( volume != 0 ) {
- info.play.gain = volume * AUDIO_MAX_GAIN / 100;
- if ( vol->right == vol->left )
- info.play.balance = AUDIO_MID_BALANCE;
- else
- info.play.balance = (vol->right - vol->left + volume) * AUDIO_RIGHT_BALANCE / (2*volume);
- }
-#if !defined (__OpenBSD__) && !defined (__NetBSD__)
- info.output_muted = (volume == 0);
-#endif
- ioctl( fd,AUDIO_SETINFO,&info );
- close( fd );
- return CONTROL_OK;
- }
- return CONTROL_ERROR;
- }
- }
- return CONTROL_UNKNOWN;
-}
-
-// open & setup audio device
-// return: 1=success 0=fail
-static int init(int rate,int channels,int format,int flags){
-
- audio_info_t info;
- int pass;
- int ok;
- int convert_u8_s8;
-
- setup_device_paths();
-
- if (enable_sample_timing == RTSC_UNKNOWN
- && !getenv("AO_SUN_DISABLE_SAMPLE_TIMING")) {
- enable_sample_timing = realtime_samplecounter_available(audio_dev);
- }
-
- mp_msg(MSGT_AO,MSGL_STATUS,"ao2: %d Hz %d chans %s [0x%X]\n",
- rate,channels,af_fmt2str_short(format),format);
-
- audio_fd=open(audio_dev, O_WRONLY);
- if(audio_fd<0){
- mp_tmsg(MSGT_AO, MSGL_ERR, "[AO SUN] Can't open audio device %s, %s -> nosound.\n", audio_dev, strerror(errno));
- return 0;
- }
-
- if (af2sunfmt(format) == AUDIO_ENCODING_NONE)
- format = AF_FORMAT_S16_NE;
-
- for (ok = pass = 0; pass <= 5; pass++) { /* pass 6&7 not useful */
-
- AUDIO_INITINFO(&info);
- info.play.encoding = af2sunfmt(ao_data.format = format);
- info.play.precision =
- (format==AF_FORMAT_S16_NE
- ? AUDIO_PRECISION_16
- : AUDIO_PRECISION_8);
- info.play.channels = ao_data.channels = channels;
- info.play.sample_rate = ao_data.samplerate = rate;
-
- convert_u8_s8 = 0;
-
- if (pass & 1) {
- /*
- * on some sun audio drivers, 8-bit unsigned LINEAR8 encoding is
- * not supported, but 8-bit signed encoding is.
- *
- * Try S8, and if it works, use our own U8->S8 conversion before
- * sending the samples to the sound driver.
- */
-#ifdef AUDIO_ENCODING_LINEAR8
- if (info.play.encoding != AUDIO_ENCODING_LINEAR8)
-#endif
- continue;
- info.play.encoding = AUDIO_ENCODING_LINEAR;
- convert_u8_s8 = 1;
- }
-
- if (pass & 2) {
- /*
- * on some sun audio drivers, only certain fixed sample rates are
- * supported.
- *
- * In case the requested sample rate is very close to one of the
- * supported rates, use the fixed supported rate instead.
- */
- if (!(info.play.sample_rate =
- find_close_samplerate_match(audio_fd, rate)))
- continue;
-
- /*
- * I'm not returning the correct sample rate in
- * |ao_data.samplerate|, to avoid software resampling.
- *
- * ao_data.samplerate = info.play.sample_rate;
- */
- }
-
- if (pass & 4) {
- /* like "pass & 2", but use the highest supported sample rate */
- if (!(info.play.sample_rate
- = ao_data.samplerate
- = find_highest_samplerate(audio_fd)))
- continue;
- }
-
- ok = ioctl(audio_fd, AUDIO_SETINFO, &info) >= 0;
- if (ok) {
- /* audio format accepted by audio driver */
- break;
- }
-
- /*
- * format not supported?
- * retry with different encoding and/or sample rate
- */
- }
-
- if (!ok) {
- char buf[128];
- mp_tmsg(MSGT_AO, MSGL_ERR, "[AO SUN] audio_setup: your card doesn't support %d channel, %s, %d Hz samplerate.\n",
- channels, af_fmt2str(format, buf, 128), rate);
- return 0;
- }
-
- if (convert_u8_s8)
- ao_data.format = AF_FORMAT_S8;
-
- bytes_per_sample = channels * info.play.precision / 8;
- ao_data.bps = byte_per_sec = bytes_per_sample * ao_data.samplerate;
- ao_data.outburst = byte_per_sec > 100000 ? 16384 : 8192;
-
- reset();
-
- return 1;
-}
-
-// close audio device
-static void uninit(int immed){
- // throw away buffered data in the audio driver's STREAMS queue
- if (immed)
- flush_audio(audio_fd);
- else
- ioctl(audio_fd, AUDIO_DRAIN, 0);
- close(audio_fd);
-}
-
-// stop playing and empty buffers (for seeking/pause)
-static void reset(void){
- audio_info_t info;
- flush_audio(audio_fd);
-
- AUDIO_INITINFO(&info);
- info.play.samples = 0;
- info.play.eof = 0;
- info.play.error = 0;
- ioctl(audio_fd, AUDIO_SETINFO, &info);
-
- queued_bursts = 0;
- queued_samples = 0;
-}
-
-// stop playing, keep buffers (for pause)
-static void audio_pause(void)
-{
- struct audio_info info;
- AUDIO_INITINFO(&info);
- info.play.pause = 1;
- ioctl(audio_fd, AUDIO_SETINFO, &info);
-}
-
-// resume playing, after audio_pause()
-static void audio_resume(void)
-{
- struct audio_info info;
- AUDIO_INITINFO(&info);
- info.play.pause = 0;
- ioctl(audio_fd, AUDIO_SETINFO, &info);
-}
-
-
-// return: how many bytes can be played without blocking
-static int get_space(void){
- audio_info_t info;
-
- // check buffer
-#ifdef HAVE_AUDIO_SELECT
- {
- fd_set rfds;
- struct timeval tv;
- FD_ZERO(&rfds);
- FD_SET(audio_fd, &rfds);
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- if(!select(audio_fd+1, NULL, &rfds, NULL, &tv)) return 0; // not block!
- }
-#endif
-
- ioctl(audio_fd, AUDIO_GETINFO, &info);
-#if !defined (__OpenBSD__) && !defined(__NetBSD__)
- if (queued_bursts - info.play.eof > 2)
- return 0;
- return ao_data.outburst;
-#else
- return info.hiwat * info.blocksize - info.play.seek;
-#endif
-
-}
-
-// plays 'len' bytes of 'data'
-// it should round it down to outburst*n
-// return: number of bytes played
-static int play(void* data,int len,int flags){
- if (!(flags & AOPLAY_FINAL_CHUNK)) {
- len /= ao_data.outburst;
- len *= ao_data.outburst;
- }
- if (len <= 0) return 0;
-
- len = write(audio_fd, data, len);
- if(len > 0) {
- queued_samples += len / bytes_per_sample;
- if (write(audio_fd,data,0) < 0)
- perror("ao_sun: send EOF audio record");
- else
- queued_bursts ++;
- }
- return len;
-}
-
-
-// return: delay in seconds between first and last sample in buffer
-static float get_delay(void){
- audio_info_t info;
- ioctl(audio_fd, AUDIO_GETINFO, &info);
-#if defined (__OpenBSD__) || defined(__NetBSD__)
- return (float) info.play.seek/ (float)byte_per_sec ;
-#else
- if (info.play.samples && enable_sample_timing == RTSC_ENABLED)
- return (float)(queued_samples - info.play.samples) / (float)ao_data.samplerate;
- else
- return (float)((queued_bursts - info.play.eof) * ao_data.outburst) / (float)byte_per_sec;
-#endif
-}