Skip to content

Commit 552e347

Browse files
author
lantus360
committed
(mostly )working audio - Will still need to resolve the 8bit unsigned source formats. Signed 16bit formats are working. Thanks to gligli
1 parent 2ac80ab commit 552e347

File tree

7 files changed

+170
-66
lines changed

7 files changed

+170
-66
lines changed

include/SDL_config_xenon.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ typedef unsigned int size_t;
4242

4343
#define SDL_BYTEORDER SDL_BIG_ENDIAN
4444
#define SDL_LOADSO_DISABLED 1
45-
#define SDL_THREADS_DISABLED 1 //ugh
45+
#define SDL_THREADS_XENON 1 //ugh
4646
#define SDL_AUDIO_DRIVER_XENON 1
4747
#define SDL_VIDEO_DRIVER_XENON 1
4848
#define SDL_HAS_64BIT_TYPE 1

src/SDL.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ int SDL_Init(Uint32 flags)
152152

153153
#if defined (__XENON__)
154154
/* !!!! NOTE: THE CALLING CODE in main() needs to call these first !!!!*/
155-
/* if SDL_Init() is called to late in the code with these functions it seems to crash libxenon **/
155+
/* if SDL_Init() is called too late in the code with these functions it seems to crash libxenon **/
156156
//xenon_make_it_faster(XENON_SPEED_FULL);
157157
//xenos_init(VIDEO_MODE_AUTO);
158158
//xenon_sound_init();

src/audio/xenon/SDL_xenonaudio.c

+155-47
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,26 @@
2929
#include "SDL_audio_c.h"
3030
#include "SDL_xenonaudio.h"
3131

32+
#define MAX_UNPLAYED 32768
33+
#define BUFFER_SIZE 65536
34+
35+
static Uint32 dma_buffer[2048];
36+
37+
static char buffer[BUFFER_SIZE];
38+
static unsigned int real_freq;
39+
static double freq_ratio;
40+
41+
int buffer_size = 1024;
42+
43+
static unsigned int thread_lock __attribute__ ((aligned (128))) =0;
3244

45+
static unsigned char thread_stack[0x10000];
46+
static unsigned char thread_stack_get[0x10000];
3347

48+
static volatile void * thread_buffer=NULL;
49+
static volatile int thread_bufsize=0;
50+
static int thread_bufmaxsize=0;
51+
static volatile int thread_terminate=0;
3452

3553
/* Audio driver functions */
3654
static int XENON_OpenAudio(_THIS, SDL_AudioSpec *spec);
@@ -48,6 +66,49 @@ static int Audio_Available(void)
4866
return(1);
4967
}
5068

69+
static void inline play_buffer(void)
70+
{
71+
int i;
72+
73+
while(xenon_sound_get_unplayed()>MAX_UNPLAYED);
74+
75+
for(i=0;i<buffer_size/4;++i) ((int*)buffer)[i]=bswap_32(((int*)buffer)[i]);
76+
77+
xenon_sound_submit(buffer,buffer_size);
78+
79+
80+
}
81+
82+
static s16 prevLastSample[2]={0,0};
83+
84+
void ResampleLinear(s16* pStereoSamples, s32 oldsamples, s16* pNewSamples, s32 newsamples)
85+
{
86+
s32 newsampL, newsampR;
87+
s32 i;
88+
89+
for (i = 0; i < newsamples; ++i)
90+
{
91+
s32 io = i * oldsamples;
92+
s32 old = io / newsamples;
93+
s32 rem = io - old * newsamples;
94+
95+
old *= 2;
96+
97+
if (old==0){
98+
newsampL = prevLastSample[0] * (newsamples - rem) + pStereoSamples[0] * rem;
99+
newsampR = prevLastSample[1] * (newsamples - rem) + pStereoSamples[1] * rem;
100+
}else{
101+
newsampL = pStereoSamples[old-2] * (newsamples - rem) + pStereoSamples[old] * rem;
102+
newsampR = pStereoSamples[old-1] * (newsamples - rem) + pStereoSamples[old+1] * rem;
103+
}
104+
105+
pNewSamples[2 * i] = newsampL / newsamples;
106+
pNewSamples[2 * i + 1] = newsampR / newsamples;
107+
}
108+
109+
prevLastSample[0]=pStereoSamples[oldsamples*2-2];
110+
prevLastSample[1]=pStereoSamples[oldsamples*2-1];
111+
}
51112

52113
static void XENON_Unload(void)
53114
{
@@ -116,76 +177,123 @@ static void XENON_WaitAudio_BusyWait(_THIS)
116177

117178
static void XENON_PlayAudio(_THIS)
118179
{
180+
181+
}
182+
183+
static void XENON_WaitDone(_THIS)
184+
{
119185

120-
121-
//while(xenon_sound_get_unplayed()>(4*mixlen)) udelay(50);
122-
123-
124-
//memcpy(&pAudioBuffers[currentBuffer * mixlen], locked_buf, mixlen);
125-
//xenon_sound_submit(&pAudioBuffers[currentBuffer * mixlen], mixlen);
126-
127186

128-
currentBuffer++;
129-
currentBuffer %= (NUM_BUFFERS);
187+
188+
130189
}
131190

132-
static Uint8 *XENON_GetAudioBuf(_THIS)
133-
{
134-
return(locked_buf);
191+
static void XENON_CloseAudio(_THIS)
192+
{
193+
194+
135195
}
136196

137-
static void XENON_WaitDone(_THIS)
197+
static void thread_enqueue(void * buffer,int size)
138198
{
139-
Uint8 *stream;
199+
while(thread_bufsize);
200+
201+
lock(&thread_lock);
140202

141-
/* Wait for the playing chunk to finish */
142-
stream = this->GetAudioBuf(this);
143-
if ( stream != NULL ) {
144-
memset(stream, silence, mixlen);
145-
this->PlayAudio(this);
146-
}
147-
this->WaitAudio(this);
203+
if(thread_bufmaxsize<size){
204+
thread_bufmaxsize=size;
205+
thread_buffer=realloc((void*)thread_buffer,thread_bufmaxsize);
206+
}
148207

149-
150-
208+
thread_bufsize=size;
209+
memcpy((void*)thread_buffer,buffer,thread_bufsize);
210+
211+
unlock(&thread_lock);
212+
151213
}
152214

153-
static void XENON_CloseAudio(_THIS)
215+
static void inline add_to_buffer(void* stream, unsigned int length){
216+
unsigned int lengthLeft = length >> 2;
217+
unsigned int rlengthLeft = ceil(lengthLeft / freq_ratio);
218+
ResampleLinear((s16 *)stream,lengthLeft,(s16 *)buffer,rlengthLeft);
219+
buffer_size=rlengthLeft<<2;
220+
play_buffer();
221+
}
222+
223+
static void thread_loop()
154224
{
225+
static char * local_buffer[0x10000];
226+
int local_bufsize=0;
227+
int k;
228+
229+
while(!thread_terminate){
230+
231+
short *stream = (short *)dma_buffer;
232+
233+
// grab the audio
234+
current_audio->spec.callback(
235+
current_audio->spec.userdata,
236+
(Uint8 *)dma_buffer,
237+
2048);
238+
239+
240+
// queue it up
241+
thread_enqueue((short *)stream, 2048);
242+
243+
lock(&thread_lock);
244+
245+
if (thread_bufsize){
246+
local_bufsize=thread_bufsize;
247+
if (local_bufsize>sizeof(local_buffer)) local_bufsize=sizeof(local_buffer);
248+
memcpy(local_buffer,(void*)thread_buffer,local_bufsize);
249+
thread_bufsize-=local_bufsize;
250+
}
251+
252+
unlock(&thread_lock);
155253

156-
if (locked_buf)
157-
{
158-
free(locked_buf);
159-
locked_buf = NULL;
160-
}
254+
if (local_bufsize){
255+
add_to_buffer(local_buffer,local_bufsize);
256+
local_bufsize=0;
257+
}
161258

162-
if (pAudioBuffers)
163-
{
164-
free(pAudioBuffers);
165-
pAudioBuffers = NULL;
166-
}
259+
for(k=0;k<100;++k) asm volatile("nop");
260+
}
261+
}
262+
263+
static Uint8 *XENON_GetAudioBuf(_THIS)
264+
{
265+
266+
return NULL;
167267
}
168268

169269
static int XENON_OpenAudio(_THIS, SDL_AudioSpec *spec)
170270
{
171-
172-
// Set up actual spec.
173-
spec->freq = 48000;
271+
272+
spec->freq = 32000;
174273
spec->format = AUDIO_S16MSB;
175-
spec->channels = 2;
274+
spec->channels = 2;
275+
276+
freq_ratio = (double)spec->freq / 48000;
176277

177278
/* Update the fragment size as size in bytes */
178279
SDL_CalculateAudioSpec(spec);
179-
180-
locked_buf = (unsigned char *)malloc(spec->size);
181-
182-
/* Create the audio buffer to which we write */
183-
NUM_BUFFERS = 2;
184-
185-
186-
pAudioBuffers = (unsigned char *)malloc(spec->size *NUM_BUFFERS);
280+
281+
187282
playing = 0;
188283
mixlen = spec->size;
189284

190-
return(0);
285+
thread_lock=0;
286+
thread_buffer=NULL;
287+
thread_bufsize=0;
288+
thread_bufmaxsize=0;
289+
thread_terminate=0;
290+
291+
// Semaphores/Mutexes dont exist yet in libXenon so we dont want libSDL to handle
292+
// the threading. Instead create our own thread here to handle the audio.
293+
294+
xenon_run_thread_task(1,&thread_stack[sizeof(thread_stack)-0x100],thread_loop);
295+
296+
// 1 means that libSDL wont call SDL_CreateThread();
297+
298+
return(1);
191299
}

src/audio/xenon/SDL_xenonaudio.h

+6-9
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@
2222

2323
#ifndef _SDL_xenonaudio_h
2424
#define _SDL_xenonaudio_h
25-
25+
26+
#include <math.h>
2627
#include <xenon_sound/sound.h>
27-
28+
#include <byteswap.h>
2829
#include "SDL_sysaudio.h"
2930

3031
/* Hidden "this" pointer for the video functions */
@@ -34,9 +35,7 @@ struct SDL_PrivateAudioData {
3435
int NUM_BUFFERS;
3536
int mixlen, silence;
3637
int currentBuffer;
37-
long playing;
38-
Uint8 *locked_buf;
39-
unsigned char* pAudioBuffers;
38+
long playing;
4039
};
4140

4241
#define sound (this->hidden->sound)
@@ -45,10 +44,8 @@ struct SDL_PrivateAudioData {
4544
#define NUM_BUFFERS (this->hidden->NUM_BUFFERS)
4645
#define mixlen (this->hidden->mixlen)
4746
#define silence (this->hidden->silence)
48-
#define playing (this->hidden->playing)
49-
#define locked_buf (this->hidden->locked_buf)
50-
#define audio_event (this->hidden->audio_event)
51-
#define pAudioBuffers (this->hidden->pAudioBuffers)
47+
#define playing (this->hidden->playing)
48+
#define audio_event (this->hidden->audio_event)
5249
#define currentBuffer (this->hidden->currentBuffer)
5350

5451
#endif /* _SDL_xenonaudio_h */

src/joystick/SDL_joystick.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,8 @@ int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
538538
void SDL_JoystickUpdate(void)
539539
{
540540
int i;
541-
542-
for ( i=0; SDL_joysticks[i]; ++i ) {
541+
542+
for ( i=0; SDL_joysticks[i]; ++i ) {
543543
SDL_SYS_JoystickUpdate(SDL_joysticks[i]);
544544
}
545545
}

src/joystick/xenon/SDL_xenonjoystick.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ char joyName[50];
2222
/* The private structure used to keep track of a joystick */
2323
struct joystick_hwdata
2424
{
25-
struct controller_data_s curpad;
26-
struct controller_data_s oldpad;
25+
struct controller_data_s curpad;
2726

2827
};
2928

@@ -59,6 +58,7 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
5958
joystick->nbuttons = MAX_BUTTONS;
6059
joystick->naxes = MAX_AXES;
6160
joystick->nhats = MAX_HATS;
61+
joystick->name = "XENON SDL Gamepad";
6262
return(0);
6363
}
6464

@@ -289,7 +289,7 @@ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
289289
SDL_PrivateJoystickAxis(joystick, (Uint8)3, (Sint16)nYR);
290290

291291

292-
joystick->hwdata->oldpad = joystick->hwdata->curpad;
292+
//joystick->hwdata->oldpad = joystick->hwdata->curpad;
293293
}
294294

295295
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)

src/thread/xenon/SDL_syssem.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
4343
return NULL;
4444
}
4545
sem->count = initial_value;
46-
sem->waiters_count = 0;
47-
46+
sem->waiters_count = 0;
4847
return sem;
4948
}
5049

@@ -68,7 +67,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
6867
{
6968
int retval = 0;
7069

71-
70+
SDL_Delay(timeout);
7271

7372
return retval;
7473
}

0 commit comments

Comments
 (0)