3333// Includes
3434#include " include/sounddriver_linux.h"
3535
36+ #include " jack/jack.h"
37+
38+ // ------------------------------------------------------
39+ // Variables (internal)
40+ int AUDIO_Samples = 0 ;
41+ int AUDIO_Play_Flag = FALSE ;
42+ float AUDIO_Timer = 0 .0f ;
43+
44+ // ------------------------------------------------------
45+ // Variables (jack)
46+ jack_client_t * jaudio_client = NULL ;
47+ jack_port_t * jaudio_port1 = NULL ;
48+ jack_port_t * jaudio_port2 = NULL ;
49+
3650// ------------------------------------------------------
37- // Variables
38- unsigned int AUDIO_To_Fill;
39- int AUDIO_Samples;
40- int AUDIO_Play_Flag;
41- float AUDIO_Timer;
42-
43- int volatile AUDIO_Acknowledge;
44- int AUDIO_Device;
45- short *AUDIO_SoundBuffer;
46- audio_buf_info AUDIO_Info_Buffer;
47- pthread_t hThread;
48- int volatile Thread_Running;
49- int AUDIO_SoundBuffer_Size;
50-
51- int AUDIO_Latency;
51+ // Variables (external helpers, not really used here)
52+ int volatile AUDIO_Acknowledge = 0 ;
53+ int AUDIO_Latency = 0 ;
5254int AUDIO_Milliseconds = 20 ;
5355
56+ int AUDIO_Create_Sound_Buffer (int ) {}
57+ void AUDIO_Stop_Sound_Buffer (void ) {}
58+
5459// ------------------------------------------------------
5560// Functions
56- int AUDIO_Create_Sound_Buffer (int milliseconds);
57- void AUDIO_Stop_Sound_Buffer (void );
5861void (STDCALL *AUDIO_Mixer)(Uint8 *, Uint32);
59- void AUDIO_Mixer_Fill_Buffer (void *, Uint32);
60- void AUDIO_Synth_Play (void );
6162
62- // ------------------------------------------------------
63- // Name: AUDIO_Thread()
64- // Desc: Audio rendering
65- void *AUDIO_Thread (void *arg)
63+ static int jaudio_process_callback (jack_nframes_t nframes, void *)
6664{
67- while (Thread_Running)
65+ float * audioBuf1 = (float *)jack_port_get_buffer (jaudio_port1, nframes);
66+ float * audioBuf2 = (float *)jack_port_get_buffer (jaudio_port2, nframes);
67+
68+ AUDIO_Acknowledge = FALSE ;
69+
70+ if (AUDIO_Play_Flag)
6871 {
69- if (AUDIO_SoundBuffer)
72+ Uint8 mixerBuf[nframes*2 ];
73+ AUDIO_Mixer (mixerBuf, nframes*2 );
74+
75+ for (jack_nframes_t i=0 ; i < nframes; ++i)
7076 {
71- AUDIO_Acknowledge = FALSE ;
72- if (AUDIO_Play_Flag)
73- {
74- AUDIO_Mixer ((Uint8 *) AUDIO_SoundBuffer, AUDIO_SoundBuffer_Size);
75- }
76- else
77- {
78- unsigned int i;
79- char *pSamples = (char *) AUDIO_SoundBuffer;
80- for (i = 0 ; i < AUDIO_SoundBuffer_Size; i++)
81- {
82- pSamples[i] = 0 ;
83- }
84- AUDIO_Acknowledge = TRUE ;
85- }
86- write (AUDIO_Device, AUDIO_SoundBuffer, AUDIO_SoundBuffer_Size);
87-
88- AUDIO_Samples += AUDIO_SoundBuffer_Size;
89- AUDIO_Timer = ((((float ) AUDIO_Samples) * (1 .0f / (float ) AUDIO_Latency)) * 1000 .0f );
77+ audioBuf1[i] = float (mixerBuf[ i])*2 .0f -1 .0f ;
78+ audioBuf2[i] = float (mixerBuf[nframes+i])*2 .0f -1 .0f ;
9079 }
91- usleep (10 );
92- }
93- Thread_Running = 1 ;
94- pthread_exit (0 );
95- return (0 );
96- }
97-
98- // ------------------------------------------------------
99- // Name: AUDIO_Init_Driver()
100- // Desc: Init the audio driver
101- int AUDIO_Init_Driver (void (*Mixer)(Uint8 *, Uint32))
102- {
103- AUDIO_Mixer = Mixer;
104-
105- char *Mixer_Name;
106- int8 Mixer_Volume[4 ];
10780
108- AUDIO_Device = open (" /dev/dsp" , O_WRONLY, 0 );
109- if (AUDIO_Device >= 0 )
110- {
111- return (AUDIO_Create_Sound_Buffer (AUDIO_Milliseconds));
81+ AUDIO_Samples += nframes;
82+ AUDIO_Timer = ((((float ) AUDIO_Samples) * (1 .0f / (float ) AUDIO_Latency)) * 1000 .0f );
11283 }
113-
114- #if !defined(__STAND_ALONE__) && !defined(__WINAMP__)
11584 else
11685 {
117- Message_Error (" Error while calling open(\" /dev/dsp\" )" );
86+ for (jack_nframes_t i=0 ; i < nframes; ++i)
87+ *audioBuf1++ = *audioBuf2++ = 0 .0f ;
88+
89+ AUDIO_Acknowledge = TRUE ;
11890 }
119- #endif
12091
121- return ( FALSE ) ;
92+ return 0 ;
12293}
12394
124- // ------------------------------------------------------
125- // Name: AUDIO_Create_Sound_Buffer()
126- // Desc: Create an audio buffer of given milliseconds
127- int AUDIO_Create_Sound_Buffer (int milliseconds)
95+ static void jaudio_shutdown_callback (void * arg)
12896{
129- int num_fragments;
130- int frag_size;
131-
132- if (milliseconds < 10 ) milliseconds = 10 ;
133- if (milliseconds > 250 ) milliseconds = 250 ;
134-
135- num_fragments = 6 ;
136- frag_size = (int ) (AUDIO_PCM_FREQ * (milliseconds / 1000 .0f ));
137-
138- int Dsp_Val;
139- struct sched_param p;
140-
141- frag_size = 10 + (int ) (logf ((float ) (frag_size >> 9 )) / logf (2 .0f ));
142-
143- Dsp_Val = (num_fragments << 16 ) | frag_size;
144- ioctl (AUDIO_Device, SNDCTL_DSP_SETFRAGMENT, &Dsp_Val);
145-
146- Dsp_Val = AUDIO_DBUF_CHANNELS;
147- ioctl (AUDIO_Device, SNDCTL_DSP_CHANNELS, &Dsp_Val);
148- Dsp_Val = AFMT_S16_NE;
149- ioctl (AUDIO_Device, SNDCTL_DSP_SETFMT, &Dsp_Val);
150- Dsp_Val = AUDIO_PCM_FREQ;
151- ioctl (AUDIO_Device, SNDCTL_DSP_SPEED, &Dsp_Val);
152-
153- if ((ioctl (AUDIO_Device, SNDCTL_DSP_GETOSPACE, &AUDIO_Info_Buffer) < 0 ))
154- {
155- ioctl (AUDIO_Device, SNDCTL_DSP_GETBLKSIZE, &AUDIO_Info_Buffer.fragsize );
156- }
97+ jaudio_client = NULL ;
98+ jaudio_port1 = NULL ;
99+ jaudio_port2 = NULL ;
100+ AUDIO_Play_Flag = FALSE ;
101+ }
157102
158- AUDIO_SoundBuffer_Size = AUDIO_Info_Buffer.fragsize ;
159- AUDIO_Latency = AUDIO_SoundBuffer_Size;
103+ // ------------------------------------------------------
104+ // Name: AUDIO_Init_Driver()
105+ // Desc: Init the audio driver
106+ int AUDIO_Init_Driver (void (*Mixer)(Uint8 *, Uint32))
107+ {
108+ AUDIO_Mixer = Mixer;
160109
161- AUDIO_SoundBuffer = ( short *) malloc (AUDIO_SoundBuffer_Size << 1 );
110+ jaudio_client = jack_client_open ( " protrekkr " , JackNullOption, NULL );
162111
163- p.sched_priority = 1 ;
164- Thread_Running = 1 ;
165- pthread_setschedparam (pthread_self (), SCHED_FIFO , &p);
166- if (pthread_create (&hThread, NULL , AUDIO_Thread, NULL ) == 0 )
167- {
168- return (TRUE );
169- }
112+ if (jaudio_client == NULL )
113+ return FALSE ;
170114
171- #if !defined(__STAND_ALONE__) && !defined(__WINAMP__)
172- Message_Error (" Error while calling pthread_create()" );
173- #endif
115+ jaudio_port1 = jack_port_register (jaudio_client, " out1" , JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
116+ jaudio_port2 = jack_port_register (jaudio_client, " out2" , JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
174117
175- Thread_Running = 0 ;
118+ jack_set_process_callback (jaudio_client, jaudio_process_callback, NULL );
119+ jack_on_shutdown (jaudio_client, jaudio_shutdown_callback, NULL );
176120
177- return (FALSE );
178- }
121+ AUDIO_Latency = jack_get_buffer_size (jaudio_client);
179122
180- // ------------------------------------------------------
181- // Name: AUDIO_Wait_For_Thread()
182- // Desc: Wait for a command acknowledgment from the thread
183- void AUDIO_Wait_For_Thread (void )
184- {
185- if (Thread_Running)
186- {
187- if (AUDIO_Play_Flag)
188- {
189- while (AUDIO_Acknowledge)
190- {
191- usleep (10 );
192- };
193- }
194- else
195- {
196- if (hThread)
197- {
198- while (!AUDIO_Acknowledge)
199- {
200- usleep (10 );
201- };
202- }
203- }
204- }
123+ return (jaudio_client != NULL ) ? TRUE : FALSE ;
205124}
206125
207126// ------------------------------------------------------
@@ -211,7 +130,11 @@ void AUDIO_Play(void)
211130{
212131 AUDIO_ResetTimer ();
213132 AUDIO_Play_Flag = TRUE ;
214- AUDIO_Wait_For_Thread ();
133+
134+ if (jaudio_client == NULL )
135+ return ;
136+
137+ jack_activate (jaudio_client);
215138}
216139
217140// ------------------------------------------------------
@@ -253,34 +176,27 @@ int AUDIO_GetSamples(void)
253176void AUDIO_Stop (void )
254177{
255178 AUDIO_Play_Flag = FALSE ;
256- AUDIO_Wait_For_Thread ();
257- }
258179
259- // ------------------------------------------------------
260- // Name: AUDIO_Stop_Sound_Buffer()
261- // Desc: Release the audio buffer
262- void AUDIO_Stop_Sound_Buffer (void )
263- {
264- AUDIO_Stop ();
180+ if (jaudio_client == NULL )
181+ return ;
265182
266- if (hThread)
267- {
268- Thread_Running = 0 ;
269- while (!Thread_Running)
270- {
271- usleep (10 );
272- }
273- if (AUDIO_SoundBuffer) free (AUDIO_SoundBuffer);
274- AUDIO_SoundBuffer = NULL ;
275- }
183+ jack_deactivate (jaudio_client);
276184}
277185
278186// ------------------------------------------------------
279187// Name: AUDIO_Stop_Driver()
280188// Desc: Stop everything
281189void AUDIO_Stop_Driver (void )
282190{
283- AUDIO_Stop_Sound_Buffer ();
284- if (AUDIO_Device) close (AUDIO_Device);
285- AUDIO_Device = 0 ;
191+ if (jaudio_client == NULL )
192+ return ;
193+
194+ jack_port_unregister (jaudio_client, jaudio_port2);
195+ jaudio_port2 = NULL ;
196+
197+ jack_port_unregister (jaudio_client, jaudio_port1);
198+ jaudio_port1 = NULL ;
199+
200+ jack_client_close (jaudio_client);
201+ jaudio_client = NULL ;
286202}
0 commit comments