Skip to content

Commit 92c4f9c

Browse files
author
falkTX
committed
First attempt at linux jack driver
1 parent f295d64 commit 92c4f9c

File tree

3 files changed

+83
-167
lines changed

3 files changed

+83
-167
lines changed

makefile.linux

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ LIBS = src/extralibs/tinyxml/tinyxml.o \
44
src/extralibs/tinyxml/tinyxmlparser.o \
55
src/extralibs/tinyxml/tinystr.o \
66
src/extralibs/tinyxml/tinyxmlerror.o \
7-
-lasound -lSDL -lsdldraw -lz
7+
-lasound -lSDL -lsdldraw -lz -ljack
88

99
FLAGS = -g -O3 -fno-strict-aliasing -ffast-math -fno-rtti -fexceptions -Wno-write-strings -Wno-multichar -Lsrc/extralibs/sdl_draw -Lsrc/extralibs/zlib-1.2.3 \
1010
-D __LINUX__ -D __GCC__ -D __LINUX_ALSASEQ__ -D __MOT_SWAP__

release/distrib/replay/lib/sounddriver/include/sounddriver_linux.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ typedef char int8;
7070

7171
// ------------------------------------------------------
7272
// Functions
73-
extern int AUDIO_Latency;
74-
extern int AUDIO_Milliseconds;
73+
// extern int AUDIO_Latency;
74+
// extern int AUDIO_Milliseconds;
7575

7676
#if !defined(__STAND_ALONE__) && !defined(__WINAMP__)
7777
void Message_Error(char *Message);

release/distrib/replay/lib/sounddriver/sounddriver_linux.cpp

Lines changed: 80 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -33,175 +33,94 @@
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;
5254
int 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);
5861
void (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)
253176
void 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
281189
void 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

Comments
 (0)