spu: rework synchronization
[pcsx_rearmed.git] / plugins / dfsound / oss.c
CommitLineData
ef79bbde
P
1/***************************************************************************
2 oss.c - description
3 -------------------
4 begin : Wed May 15 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. See also the license.txt file for *
14 * additional informations. *
15 * *
16 ***************************************************************************/
17
07c13dfd 18#include <stdio.h>
650adfd2 19#include <string.h>
07c13dfd 20#include <sys/types.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <sys/ioctl.h>
24#include <unistd.h>
25#include <sys/soundcard.h>
26#include "out.h"
ef79bbde
P
27
28////////////////////////////////////////////////////////////////////////
29// oss globals
30////////////////////////////////////////////////////////////////////////
31
32#define OSS_MODE_STEREO 1
33#define OSS_MODE_MONO 0
34
35#define OSS_SPEED_44100 44100
36
37static int oss_audio_fd = -1;
38extern int errno;
39
40////////////////////////////////////////////////////////////////////////
41// SETUP SOUND
42////////////////////////////////////////////////////////////////////////
43
07c13dfd 44static int oss_init(void)
ef79bbde
P
45{
46 int pspeed=44100;
47 int pstereo;
48 int format;
49 int fragsize = 0;
50 int myfrag;
51 int oss_speed, oss_stereo;
52
97ea4077 53 pstereo = OSS_MODE_STEREO;
ef79bbde
P
54 oss_speed = pspeed;
55 oss_stereo = pstereo;
56
57 if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
58 {
07c13dfd 59 printf("OSS device not available\n");
60 return -1;
ef79bbde
P
61 }
62
63 if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
64 {
65 printf("Sound reset failed\n");
07c13dfd 66 return -1;
ef79bbde
P
67 }
68
69 // we use 64 fragments with 1024 bytes each
17ed0d69 70 // rearmed: now using 10*4096 for better latency
ef79bbde 71
17ed0d69 72 fragsize=12;
73 myfrag=(10<<16)|fragsize;
ef79bbde
P
74
75 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
76 {
77 printf("Sound set fragment failed!\n");
07c13dfd 78 return -1;
ef79bbde
P
79 }
80
81 format = AFMT_S16_NE;
82
83 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
84 {
85 printf("Sound format not supported!\n");
07c13dfd 86 return -1;
ef79bbde
P
87 }
88
89 if(format!=AFMT_S16_NE)
90 {
91 printf("Sound format not supported!\n");
07c13dfd 92 return -1;
ef79bbde
P
93 }
94
97ea4077 95 if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1 || !oss_stereo)
ef79bbde
P
96 {
97 printf("Stereo mode not supported!\n");
07c13dfd 98 return -1;
ef79bbde
P
99 }
100
ef79bbde
P
101 if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
102 {
103 printf("Sound frequency not supported\n");
07c13dfd 104 return -1;
ef79bbde
P
105 }
106
107 if(oss_speed!=pspeed)
108 {
109 printf("Sound frequency not supported\n");
07c13dfd 110 return -1;
ef79bbde 111 }
07c13dfd 112
113 return 0;
ef79bbde
P
114}
115
116////////////////////////////////////////////////////////////////////////
117// REMOVE SOUND
118////////////////////////////////////////////////////////////////////////
119
07c13dfd 120static void oss_finish(void)
ef79bbde
P
121{
122 if(oss_audio_fd != -1 )
123 {
124 close(oss_audio_fd);
125 oss_audio_fd = -1;
126 }
127}
128
129////////////////////////////////////////////////////////////////////////
07c13dfd 130// GET BUFFERED STATUS
ef79bbde
P
131////////////////////////////////////////////////////////////////////////
132
07c13dfd 133static int oss_busy(void)
ef79bbde
P
134{
135 audio_buf_info info;
136 unsigned long l;
137
f8edb5bc 138 if(oss_audio_fd == -1) return 1;
ef79bbde
P
139 if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
140 l=0;
141 else
142 {
143 if(info.fragments<(info.fragstotal>>1)) // can we write in at least the half of fragments?
f8edb5bc 144 l=1; // -> no? wait
ef79bbde
P
145 else l=0; // -> else go on
146 }
147
148 return l;
149}
150
151////////////////////////////////////////////////////////////////////////
152// FEED SOUND DATA
153////////////////////////////////////////////////////////////////////////
154
07c13dfd 155static void oss_feed(void *buf, int bytes)
ef79bbde 156{
650adfd2 157 audio_buf_info info;
158 char sbuf[4096];
159
ef79bbde 160 if(oss_audio_fd == -1) return;
650adfd2 161 if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==0)
162 {
163 if(info.fragments==info.fragstotal)
164 {
165 memset(sbuf, 0, sizeof(sbuf));
166 write(oss_audio_fd, sbuf, sizeof(sbuf));
167 write(oss_audio_fd, sbuf, sizeof(sbuf));
168 }
169 }
170
07c13dfd 171 write(oss_audio_fd, buf, bytes);
172}
173
174void out_register_oss(struct out_driver *drv)
175{
176 drv->name = "oss";
177 drv->init = oss_init;
178 drv->finish = oss_finish;
179 drv->busy = oss_busy;
180 drv->feed = oss_feed;
ef79bbde 181}