mirror of
https://github.com/mpv-player/mpv
synced 2025-01-29 11:12:56 +00:00
SUN-Solaris audio out
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1042 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
d5925fe568
commit
96d03d719d
223
libao2/ao_sun.c
Normal file
223
libao2/ao_sun.c
Normal file
@ -0,0 +1,223 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/audioio.h>
|
||||
#ifdef __svr4__
|
||||
#include <stropts.h>
|
||||
#endif
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#include "audio_out.h"
|
||||
#include "audio_out_internal.h"
|
||||
|
||||
static ao_info_t info =
|
||||
{
|
||||
"Sun audio output",
|
||||
"sun",
|
||||
"jk@tools.de",
|
||||
""
|
||||
};
|
||||
|
||||
LIBAO_EXTERN(sun)
|
||||
|
||||
|
||||
#ifndef AUDIO_PRECISION_8
|
||||
#define AUDIO_PRECISION_8 8
|
||||
#define AUDIO_PRECISION_16 16
|
||||
#endif
|
||||
|
||||
|
||||
// there are some globals:
|
||||
// ao_samplerate
|
||||
// ao_channels
|
||||
// ao_format
|
||||
// ao_bps
|
||||
// ao_outburst
|
||||
// ao_buffersize
|
||||
|
||||
static char *dsp="/dev/audio";
|
||||
static int queued_bursts = 0;
|
||||
static int audio_fd=-1;
|
||||
|
||||
// to set/get/query special features/parameters
|
||||
static int control(int cmd,int arg){
|
||||
switch(cmd){
|
||||
case AOCONTROL_SET_DEVICE:
|
||||
dsp=(char*)arg;
|
||||
return CONTROL_OK;
|
||||
case AOCONTROL_QUERY_FORMAT:
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
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 byte_per_sec;
|
||||
|
||||
printf("ao2: %d Hz %d chans 0x%X\n",rate,channels,format);
|
||||
|
||||
audio_fd=open(dsp, O_WRONLY);
|
||||
if(audio_fd<0){
|
||||
printf("Can't open audio device %s -> nosound\n",dsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ioctl(audio_fd, AUDIO_DRAIN, 0);
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
info.play.encoding = ao_format = format;
|
||||
info.play.precision = (format==AUDIO_ENCODING_LINEAR? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
|
||||
info.play.channels = ao_channels = channels;
|
||||
--ao_channels;
|
||||
info.play.sample_rate = ao_samplerate = rate;
|
||||
info.play.samples = 0;
|
||||
info.play.eof = 0;
|
||||
if(ioctl (audio_fd, AUDIO_SETINFO, &info)<0)
|
||||
printf("audio_setup: your card doesn't support %d Hz samplerate\n",rate);
|
||||
byte_per_sec = (channels
|
||||
* (format==AUDIO_ENCODING_LINEAR ? 16 : 8)
|
||||
* rate);
|
||||
ao_outburst=byte_per_sec > 100000 ? 16384 : 8192;
|
||||
queued_bursts = 0;
|
||||
|
||||
if(ao_buffersize==-1){
|
||||
// Measuring buffer size:
|
||||
void* data;
|
||||
ao_buffersize=0;
|
||||
#ifdef HAVE_AUDIO_SELECT
|
||||
data=malloc(ao_outburst); memset(data,0,ao_outburst);
|
||||
while(ao_buffersize<0x40000){
|
||||
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)) break;
|
||||
write(audio_fd,data,ao_outburst);
|
||||
ao_buffersize+=ao_outburst;
|
||||
}
|
||||
free(data);
|
||||
if(ao_buffersize==0){
|
||||
printf("\n *** Your audio driver DOES NOT support select() ***\n");
|
||||
printf("Recompile mplayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef __svr4__
|
||||
ioctl(audio_fd, I_FLUSH, FLUSHW);
|
||||
#endif
|
||||
ioctl(audio_fd, AUDIO_DRAIN, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// close audio device
|
||||
static void uninit(){
|
||||
close(audio_fd);
|
||||
}
|
||||
|
||||
// stop playing and empty buffers (for seeking/pause)
|
||||
static void reset(){
|
||||
audio_info_t info;
|
||||
|
||||
#ifdef __svr4__
|
||||
ioctl(audio_fd, I_FLUSH, FLUSHW);
|
||||
#endif
|
||||
uninit();
|
||||
audio_fd=open(dsp, O_WRONLY);
|
||||
if(audio_fd<0){
|
||||
printf("\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE ***\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl(audio_fd, AUDIO_DRAIN, 0);
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
info.play.encoding = ao_format;
|
||||
info.play.precision = (ao_format==AUDIO_ENCODING_LINEAR? AUDIO_PRECISION_16:AUDIO_PRECISION_8);
|
||||
info.play.channels = ao_channels+1;
|
||||
info.play.sample_rate = ao_samplerate;
|
||||
info.play.samples = 0;
|
||||
info.play.eof = 0;
|
||||
ioctl (audio_fd, AUDIO_SETINFO, &info);
|
||||
queued_bursts = 0;
|
||||
}
|
||||
|
||||
// stop playing, keep buffers (for pause)
|
||||
static void audio_pause()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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(){
|
||||
int playsize=ao_outburst;
|
||||
|
||||
// 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
|
||||
|
||||
{
|
||||
audio_info_t info;
|
||||
ioctl(audio_fd, AUDIO_GETINFO, &info);
|
||||
if(queued_bursts - info.play.eof > 2)
|
||||
return 0;
|
||||
}
|
||||
return ao_outburst;
|
||||
}
|
||||
|
||||
// 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){
|
||||
len/=ao_outburst;
|
||||
len=write(audio_fd,data,len*ao_outburst);
|
||||
if(len>0) {
|
||||
queued_bursts ++;
|
||||
write(audio_fd,data,0);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int audio_delay_method=2;
|
||||
|
||||
// return: how many unplayed bytes are in the buffer
|
||||
static int get_delay(){
|
||||
int q;
|
||||
audio_info_t info;
|
||||
ioctl(audio_fd, AUDIO_GETINFO, &info);
|
||||
return (queued_bursts - info.play.eof) * ao_outburst;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user