mirror of
https://git.freebsd.org/ports.git
synced 2025-05-24 23:16:33 -04:00
146 lines
4.3 KiB
C
146 lines
4.3 KiB
C
--- libao2/ao_oss.c.orig 2021-04-15 19:26:53 UTC
|
|
+++ libao2/ao_oss.c
|
|
@@ -57,6 +57,8 @@ static const ao_info_t info =
|
|
""
|
|
};
|
|
|
|
+static int volume = -1;
|
|
+
|
|
/* Support for >2 output channels added 2001-11-25 - Steve Davies <steve@daviesfam.org> */
|
|
|
|
LIBAO_EXTERN(oss)
|
|
@@ -73,6 +75,11 @@ static int format2oss(int format)
|
|
case AF_FORMAT_S16_BE: return AFMT_S16_BE;
|
|
#ifdef AFMT_S24_PACKED
|
|
case AF_FORMAT_S24_LE: return AFMT_S24_PACKED;
|
|
+#elif defined(__FreeBSD__) && defined(AFMT_S24_LE)
|
|
+ case AF_FORMAT_U24_LE: return AFMT_U24_LE;
|
|
+ case AF_FORMAT_U24_BE: return AFMT_U24_BE;
|
|
+ case AF_FORMAT_S24_LE: return AFMT_S24_LE;
|
|
+ case AF_FORMAT_S24_BE: return AFMT_S24_BE;
|
|
#endif
|
|
#ifdef AFMT_U32_LE
|
|
case AF_FORMAT_U32_LE: return AFMT_U32_LE;
|
|
@@ -116,6 +123,11 @@ static int oss2format(int format)
|
|
case AFMT_S16_BE: return AF_FORMAT_S16_BE;
|
|
#ifdef AFMT_S24_PACKED
|
|
case AFMT_S24_PACKED: return AF_FORMAT_S24_LE;
|
|
+#elif defined(__FreeBSD__) && defined(AFMT_S24_LE)
|
|
+ case AFMT_U24_LE: return AF_FORMAT_U24_LE;
|
|
+ case AFMT_U24_BE: return AF_FORMAT_U24_BE;
|
|
+ case AFMT_S24_LE: return AF_FORMAT_S24_LE;
|
|
+ case AFMT_S24_BE: return AF_FORMAT_S24_BE;
|
|
#endif
|
|
#ifdef AFMT_U32_LE
|
|
case AFMT_U32_LE: return AF_FORMAT_U32_LE;
|
|
@@ -217,6 +229,48 @@ static int control(int cmd,void *arg){
|
|
return CONTROL_UNKNOWN;
|
|
}
|
|
|
|
+static void setfragment(int audio_fd)
|
|
+{
|
|
+ int buffer_bytes = ao_data.channels * ao_data.samplerate;
|
|
+ int block_size = 0;
|
|
+
|
|
+ switch (ao_data.format & AF_FORMAT_BITS_MASK) {
|
|
+ case AF_FORMAT_8BIT:
|
|
+ break;
|
|
+ case AF_FORMAT_16BIT:
|
|
+ buffer_bytes *= 2;
|
|
+ break;
|
|
+ case AF_FORMAT_24BIT:
|
|
+ buffer_bytes *= 3;
|
|
+ break;
|
|
+ case AF_FORMAT_32BIT:
|
|
+ buffer_bytes *= 4;
|
|
+ break;
|
|
+ }
|
|
+ buffer_bytes *= 0.050;
|
|
+
|
|
+ if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &block_size)==0){
|
|
+ int setfrag;
|
|
+ /* make block size power of two */
|
|
+ while (block_size & (block_size - 1))
|
|
+ block_size += block_size & ~(block_size - 1);
|
|
+ /* set number of fragments */
|
|
+ setfrag = ((buffer_bytes + block_size - 1) / block_size) << 16;
|
|
+ /* need at least double buffering */
|
|
+ if (setfrag < (2 << 16))
|
|
+ setfrag = (2 << 16);
|
|
+ /* set block size in power of two */
|
|
+ while (block_size) {
|
|
+ setfrag++;
|
|
+ block_size /= 2;
|
|
+ }
|
|
+ /* try to set a total buffer of 50ms */
|
|
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &setfrag)==-1){
|
|
+ mp_msg(MSGT_AO,MSGL_V,"audio_setup: setfragment %d failed\n", setfrag);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
// open & setup audio device
|
|
// return: 1=success 0=fail
|
|
static int init(int rate,int channels,int format,int flags){
|
|
@@ -364,6 +418,7 @@ ac3_retry:
|
|
mp_msg(MSGT_AO,MSGL_WARN, "OSS: Failed setting sample-rate %i %s\n", rate, strerror(errno));
|
|
mp_msg(MSGT_AO,MSGL_V,"audio_setup: using %d Hz samplerate (requested: %d)\n",ao_data.samplerate,rate);
|
|
}
|
|
+ setfragment(audio_fd);
|
|
|
|
if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)==-1){
|
|
int r=0;
|
|
@@ -441,10 +496,30 @@ static void uninit(int immed){
|
|
audio_fd = -1;
|
|
}
|
|
|
|
+static void savevol(void){
|
|
+ int fd;
|
|
+ if (volume < 0) {
|
|
+ if ((fd = open(oss_mixer_device, O_RDONLY)) >= 0) {
|
|
+ ioctl(fd, MIXER_READ(oss_mixer_channel), &volume);
|
|
+ close(fd);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void restorevol(void){
|
|
+ int fd;
|
|
+ if ((fd = open(oss_mixer_device, O_RDONLY)) >= 0) {
|
|
+ ioctl(fd, MIXER_WRITE(oss_mixer_channel), &volume);
|
|
+ close(fd);
|
|
+ }
|
|
+ volume = -1;
|
|
+}
|
|
+
|
|
// stop playing and empty buffers (for seeking/pause)
|
|
static void reset(void){
|
|
int fail = 0;
|
|
int oss_format;
|
|
+ savevol();
|
|
uninit(1);
|
|
audio_fd=open(dsp, O_WRONLY);
|
|
if(audio_fd < 0){
|
|
@@ -456,6 +531,7 @@ static void reset(void){
|
|
fcntl(audio_fd, F_SETFD, FD_CLOEXEC);
|
|
#endif
|
|
|
|
+ ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate);
|
|
oss_format = format2oss(ao_data.format);
|
|
if(AF_FORMAT_IS_AC3(ao_data.format))
|
|
fail |= ioctl (audio_fd, SNDCTL_DSP_SPEED, &ao_data.samplerate) == -1;
|
|
@@ -471,11 +547,14 @@ static void reset(void){
|
|
}
|
|
if (fail)
|
|
mp_msg(MSGT_AO,MSGL_WARN, "OSS: Reset failed\n");
|
|
+ setfragment(audio_fd);
|
|
+ restorevol();
|
|
}
|
|
|
|
// stop playing, keep buffers (for pause)
|
|
static void audio_pause(void)
|
|
{
|
|
+ savevol();
|
|
prepause_space = get_space();
|
|
uninit(1);
|
|
}
|