Updated the Amiga OS port of SDL (thanks Gabriele)
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%4022
This commit is contained in:
parent
ac645d34ed
commit
df7866c435
26 changed files with 1381 additions and 913 deletions
|
@ -76,6 +76,10 @@ static AudioBootStrap *bootstrap[] = {
|
|||
#ifdef _AIX
|
||||
&Paud_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_AHI
|
||||
&AHI_bootstrap,
|
||||
#endif
|
||||
|
||||
NULL
|
||||
};
|
||||
SDL_AudioDevice *current_audio = NULL;
|
||||
|
@ -84,6 +88,9 @@ SDL_AudioDevice *current_audio = NULL;
|
|||
int SDL_AudioInit(const char *driver_name);
|
||||
void SDL_AudioQuit(void);
|
||||
|
||||
#ifdef ENABLE_AHI
|
||||
static int audio_configured = 0;
|
||||
#endif
|
||||
|
||||
/* The general mixing thread function */
|
||||
int SDL_RunAudio(void *audiop)
|
||||
|
@ -94,6 +101,21 @@ int SDL_RunAudio(void *audiop)
|
|||
void *udata;
|
||||
void (*fill)(void *userdata,Uint8 *stream, int len);
|
||||
int silence;
|
||||
#ifdef ENABLE_AHI
|
||||
int started = 0;
|
||||
|
||||
/* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
|
||||
|
||||
D(bug("Task audio started audio struct:<%lx>...\n",audiop));
|
||||
|
||||
D(bug("Before Openaudio..."));
|
||||
if(audio->OpenAudio(audio, &audio->spec)==-1)
|
||||
{
|
||||
D(bug("Open audio failed...\n"));
|
||||
return(-1);
|
||||
}
|
||||
D(bug("OpenAudio...OK\n"));
|
||||
#endif
|
||||
|
||||
/* Perform any thread setup */
|
||||
if ( audio->ThreadInit ) {
|
||||
|
@ -104,6 +126,15 @@ int SDL_RunAudio(void *audiop)
|
|||
/* Set up the mixing function */
|
||||
fill = audio->spec.callback;
|
||||
udata = audio->spec.userdata;
|
||||
|
||||
#ifdef ENABLE_AHI
|
||||
audio_configured = 1;
|
||||
|
||||
D(bug("Audio configured... Checking for conversion\n"));
|
||||
SDL_mutexP(audio->mixer_lock);
|
||||
D(bug("Semaphore obtained...\n"));
|
||||
#endif
|
||||
|
||||
if ( audio->convert.needed ) {
|
||||
if ( audio->convert.src_format == AUDIO_U8 ) {
|
||||
silence = 0x80;
|
||||
|
@ -117,6 +148,12 @@ int SDL_RunAudio(void *audiop)
|
|||
}
|
||||
stream = audio->fake_stream;
|
||||
|
||||
#ifdef ENABLE_AHI
|
||||
SDL_mutexV(audio->mixer_lock);
|
||||
D(bug("Entering audio loop...\n"));
|
||||
#endif
|
||||
|
||||
|
||||
/* Loop, filling the audio buffers */
|
||||
while ( audio->enabled ) {
|
||||
|
||||
|
@ -124,12 +161,14 @@ int SDL_RunAudio(void *audiop)
|
|||
if ( stream == audio->fake_stream ) {
|
||||
SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
|
||||
} else {
|
||||
#ifdef ENABLE_AHI
|
||||
if ( started > 1 )
|
||||
#endif
|
||||
audio->WaitAudio(audio);
|
||||
}
|
||||
|
||||
/* Fill the current buffer with sound */
|
||||
if ( audio->convert.needed ) {
|
||||
/* The buffer may not be allocated yet */
|
||||
if ( audio->convert.buf ) {
|
||||
stream = audio->convert.buf;
|
||||
} else {
|
||||
|
@ -163,12 +202,25 @@ int SDL_RunAudio(void *audiop)
|
|||
/* Ready current buffer for play and change current buffer */
|
||||
if ( stream != audio->fake_stream ) {
|
||||
audio->PlayAudio(audio);
|
||||
#ifdef ENABLE_AHI
|
||||
/* AmigaOS don't have to wait the first time audio is played! */
|
||||
started++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* Wait for the audio to drain.. */
|
||||
if ( audio->WaitDone ) {
|
||||
audio->WaitDone(audio);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AHI
|
||||
D(bug("WaitAudio...Done\n"));
|
||||
|
||||
audio->CloseAudio(audio);
|
||||
|
||||
D(bug("CloseAudio..Done, subtask exiting...\n"));
|
||||
audio_configured = 0;
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -312,11 +364,33 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
|||
audio->convert.needed = 0;
|
||||
audio->enabled = 1;
|
||||
audio->paused = 1;
|
||||
|
||||
#ifndef ENABLE_AHI
|
||||
|
||||
/* AmigaOS opens audio inside the main loop */
|
||||
audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
|
||||
|
||||
if ( ! audio->opened ) {
|
||||
SDL_CloseAudio();
|
||||
return(-1);
|
||||
}
|
||||
#else
|
||||
D(bug("Locking semaphore..."));
|
||||
SDL_mutexP(audio->mixer_lock);
|
||||
|
||||
audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
|
||||
D(bug("Created thread...\n"));
|
||||
|
||||
if ( audio->thread == NULL ) {
|
||||
SDL_mutexV(audio->mixer_lock);
|
||||
SDL_CloseAudio();
|
||||
SDL_SetError("Couldn't create audio thread");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
while(!audio_configured)
|
||||
SDL_Delay(100);
|
||||
#endif
|
||||
|
||||
/* If the audio driver changes the buffer size, accept it */
|
||||
if ( audio->spec.samples != desired->samples ) {
|
||||
|
@ -365,6 +439,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef ENABLE_AHI
|
||||
/* Start the audio thread if necessary */
|
||||
switch (audio->opened) {
|
||||
case 1:
|
||||
|
@ -381,6 +456,12 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
|||
/* The audio is now playing */
|
||||
break;
|
||||
}
|
||||
#else
|
||||
SDL_mutexV(audio->mixer_lock);
|
||||
D(bug("SDL_OpenAudio USCITA...\n"));
|
||||
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -457,12 +538,14 @@ void SDL_AudioQuit(void)
|
|||
}
|
||||
if ( audio->convert.needed ) {
|
||||
SDL_FreeAudioMem(audio->convert.buf);
|
||||
|
||||
}
|
||||
#ifndef ENABLE_AHI
|
||||
if ( audio->opened ) {
|
||||
audio->CloseAudio(audio);
|
||||
audio->opened = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Free the driver data */
|
||||
audio->free(audio);
|
||||
current_audio = NULL;
|
||||
|
|
|
@ -126,14 +126,17 @@ extern AudioBootStrap DSOUND_bootstrap;
|
|||
#ifdef ENABLE_WINDIB
|
||||
extern AudioBootStrap WAVEOUT_bootstrap;
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
extern AudioBootStrap Paud_bootstrap;
|
||||
#endif
|
||||
#ifdef __BEOS__
|
||||
extern AudioBootStrap BAUDIO_bootstrap;
|
||||
#endif
|
||||
#if defined(macintosh) || TARGET_API_MAC_CARBON
|
||||
extern AudioBootStrap SNDMGR_bootstrap;
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
extern AudioBootStrap Paud_bootstrap;
|
||||
#ifdef ENABLE_AHI
|
||||
extern AudioBootStrap AHI_bootstrap;
|
||||
#endif
|
||||
|
||||
/* This is the current audio device */
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
noinst_LTLIBRARIES = libaudio_arch.la
|
||||
|
||||
ARCH_SRCS = SDL_ahiaudio.c SDL_audio.c SDL_lowaudio.h SDL_sysaudio.h
|
||||
ARCH_SRCS = SDL_ahiaudio.c SDL_ahiaudio.h
|
||||
|
||||
libaudio_arch_la_SOURCES = $(ARCH_SRCS)
|
||||
|
|
|
@ -27,13 +27,17 @@ static char rcsid =
|
|||
"@(#) $Id$";
|
||||
#endif
|
||||
|
||||
/* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */
|
||||
/* Allow access to a raw mixing buffer (for AmigaOS) */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_audiomem.h"
|
||||
#include "SDL_audio_c.h"
|
||||
#include "SDL_lowaudio.h"
|
||||
#include "SDL_ahiaudio.h"
|
||||
|
||||
/* Audio driver functions */
|
||||
static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
||||
|
@ -54,11 +58,29 @@ static void AHI_CloseAudio(_THIS);
|
|||
|
||||
static int Audio_Available(void)
|
||||
{
|
||||
#ifndef NO_AMIGADEBUG
|
||||
D(bug("AHI available.\n"));
|
||||
#endif
|
||||
int ok=0;
|
||||
struct MsgPort *p;
|
||||
struct AHIRequest *req;
|
||||
|
||||
return 1;
|
||||
if(p=CreateMsgPort())
|
||||
{
|
||||
if(req=(struct AHIRequest *)CreateIORequest(p,sizeof(struct AHIRequest)))
|
||||
{
|
||||
req->ahir_Version=4;
|
||||
|
||||
if(!OpenDevice(AHINAME,0,(struct IORequest *)req,NULL))
|
||||
{
|
||||
D(bug("AHI available.\n"));
|
||||
ok=1;
|
||||
CloseDevice((struct IORequest *)req);
|
||||
}
|
||||
DeleteIORequest((struct IORequest *)req);
|
||||
}
|
||||
DeleteMsgPort(p);
|
||||
}
|
||||
|
||||
D(if(!ok) bug("AHI not available\n"));
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void Audio_DeleteDevice(SDL_AudioDevice *device)
|
||||
|
@ -125,7 +147,7 @@ static void AHI_PlayAudio(_THIS)
|
|||
/* Write the audio data out */
|
||||
audio_req[current_buffer] -> ahir_Std. io_Message.mn_Node.ln_Pri = 60;
|
||||
audio_req[current_buffer] -> ahir_Std. io_Data = mixbuf[current_buffer];
|
||||
audio_req[current_buffer] -> ahir_Std. io_Length = this->spec.samples*this->hidden->bytespersample;
|
||||
audio_req[current_buffer] -> ahir_Std. io_Length = this->hidden->size;
|
||||
audio_req[current_buffer] -> ahir_Std. io_Offset = 0;
|
||||
audio_req[current_buffer] -> ahir_Std . io_Command = CMD_WRITE;
|
||||
audio_req[current_buffer] -> ahir_Frequency = this->hidden->freq;
|
||||
|
@ -149,43 +171,58 @@ static void AHI_CloseAudio(_THIS)
|
|||
{
|
||||
D(bug("Closing audio...\n"));
|
||||
|
||||
if ( mixbuf[0] != NULL ) {
|
||||
myfree(mixbuf[0]);
|
||||
// SDL_FreeAudioMem(mixbuf[0]);
|
||||
mixbuf[0] = NULL;
|
||||
}
|
||||
|
||||
if ( mixbuf[1] != NULL ) {
|
||||
myfree(mixbuf[1]);
|
||||
// SDL_FreeAudioMem(mixbuf[1]);
|
||||
mixbuf[1] = NULL;
|
||||
}
|
||||
|
||||
playing=0;
|
||||
|
||||
if(audio_req[0])
|
||||
{
|
||||
if(audio_req[1])
|
||||
{
|
||||
if(!CheckIO((struct IORequest *)audio_req[1]))
|
||||
{
|
||||
AbortIO((struct IORequest *)audio_req[1]);
|
||||
WaitIO((struct IORequest *)audio_req[1]);
|
||||
}
|
||||
myfree(audio_req[1]);
|
||||
D(bug("Break req[1]...\n"));
|
||||
|
||||
AbortIO((struct IORequest *)audio_req[1]);
|
||||
WaitIO((struct IORequest *)audio_req[1]);
|
||||
}
|
||||
|
||||
if(!CheckIO((struct IORequest *)audio_req[0]))
|
||||
D(bug("Break req[0]...\n"));
|
||||
|
||||
AbortIO((struct IORequest *)audio_req[0]);
|
||||
WaitIO((struct IORequest *)audio_req[0]);
|
||||
|
||||
if(audio_req[1])
|
||||
{
|
||||
AbortIO((struct IORequest *)audio_req[0]);
|
||||
WaitIO((struct IORequest *)audio_req[0]);
|
||||
D(bug("Break AGAIN req[1]...\n"));
|
||||
AbortIO((struct IORequest *)audio_req[1]);
|
||||
WaitIO((struct IORequest *)audio_req[1]);
|
||||
}
|
||||
// Double abort to be sure to break the dbuffering process.
|
||||
|
||||
SDL_Delay(200);
|
||||
|
||||
D(bug("Reqs breaked, closing device...\n"));
|
||||
CloseDevice((struct IORequest *)audio_req[0]);
|
||||
D(bug("Device closed, freeing memory...\n"));
|
||||
myfree(audio_req[1]);
|
||||
D(bug("Memory freed, deleting IOReq...\n"));
|
||||
DeleteIORequest((struct IORequest *)audio_req[0]);
|
||||
audio_req[0]=audio_req[1]=NULL;
|
||||
}
|
||||
|
||||
D(bug("Freeing mixbuf[0]...\n"));
|
||||
if ( mixbuf[0] != NULL ) {
|
||||
myfree(mixbuf[0]);
|
||||
// SDL_FreeAudioMem(mixbuf[0]);
|
||||
mixbuf[0] = NULL;
|
||||
}
|
||||
|
||||
D(bug("Freeing mixbuf[1]...\n"));
|
||||
if ( mixbuf[1] != NULL ) {
|
||||
myfree(mixbuf[1]);
|
||||
// SDL_FreeAudioMem(mixbuf[1]);
|
||||
mixbuf[1] = NULL;
|
||||
}
|
||||
|
||||
D(bug("Freeing audio_port...\n"));
|
||||
|
||||
if ( audio_port != NULL ) {
|
||||
DeleteMsgPort(audio_port);
|
||||
audio_port = NULL;
|
||||
|
@ -206,8 +243,10 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
D(bug("Samples a 8 bit...\n"));
|
||||
spec->format = AUDIO_S8;
|
||||
this->hidden->bytespersample=1;
|
||||
this->hidden->type = AHIST_M8S;
|
||||
|
||||
if(spec->channels<2)
|
||||
this->hidden->type = AHIST_M8S;
|
||||
else
|
||||
this->hidden->type = AHIST_S8S;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -215,7 +254,10 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
D(bug("Samples a 16 bit...\n"));
|
||||
spec->format = AUDIO_S16MSB;
|
||||
this->hidden->bytespersample=2;
|
||||
this->hidden->type = AHIST_M16S;
|
||||
if(spec->channels<2)
|
||||
this->hidden->type = AHIST_M16S;
|
||||
else
|
||||
this->hidden->type = AHIST_S16S;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -225,6 +267,13 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
}
|
||||
}
|
||||
|
||||
if(spec->channels!=1 && spec->channels!=2)
|
||||
{
|
||||
D(bug("Wrong channel number!\n"));
|
||||
SDL_SetError("Channel number non supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
D(bug("Before CalculateAudioSpec\n"));
|
||||
/* Update the fragment size as size in bytes */
|
||||
SDL_CalculateAudioSpec(spec);
|
||||
|
@ -258,8 +307,9 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
|
||||
D(bug("AFTER opendevice\n"));
|
||||
|
||||
/* Set output frequency */
|
||||
/* Set output frequency and size */
|
||||
this->hidden->freq = spec->freq;
|
||||
this->hidden->size = spec->size;
|
||||
|
||||
D(bug("Before buffer allocation\n"));
|
||||
|
||||
|
@ -292,7 +342,7 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
|||
current_buffer=0;
|
||||
playing=0;
|
||||
|
||||
D(bug("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld\n",spec->freq,mixbuf[0],mixbuf[1],spec->size,this->hidden->bytespersample*8));
|
||||
D(bug("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld channels:%ld\n",spec->freq,mixbuf[0],mixbuf[1],spec->size,this->hidden->bytespersample*8,spec->channels));
|
||||
|
||||
/* We're ready to rock and roll. :-) */
|
||||
return(0);
|
||||
|
|
|
@ -25,15 +25,20 @@ static char rcsid =
|
|||
"@(#) $Id$";
|
||||
#endif
|
||||
|
||||
#ifndef _SDL_lowaudio_h
|
||||
#define _SDL_lowaudio_h
|
||||
#ifndef _SDL_ahiaudio_h
|
||||
#define _SDL_ahiaudio_h
|
||||
|
||||
// #include <libraries/ahi_sub.h>
|
||||
#include <exec/exec.h>
|
||||
#include <dos/dos.h>
|
||||
#ifdef __SASC
|
||||
#include <proto/exec.h>
|
||||
#else
|
||||
#include <inline/exec.h>
|
||||
#endif
|
||||
|
||||
#include <devices/ahi.h>
|
||||
#include "mydebug.h"
|
||||
#include "SDL_sysaudio.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
@ -55,4 +60,4 @@ struct SDL_PrivateAudioData {
|
|||
#define current_buffer (this->hidden->current_buffer)
|
||||
#define playing (this->hidden->playing)
|
||||
|
||||
#endif /* _SDL_lowaudio_h */
|
||||
#endif /* _SDL_ahiaudio_h */
|
|
@ -1,532 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
#ifdef SAVE_RCSID
|
||||
static char rcsid =
|
||||
"@(#) $Id$";
|
||||
#endif
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_audio_c.h"
|
||||
#include "SDL_audiomem.h"
|
||||
#include "SDL_sysaudio.h"
|
||||
|
||||
|
||||
/* Available audio drivers */
|
||||
static AudioBootStrap *bootstrap[] = {
|
||||
#ifdef unix
|
||||
&AUDIO_bootstrap,
|
||||
#endif
|
||||
#ifdef linux
|
||||
&DMA_bootstrap,
|
||||
#endif
|
||||
#ifdef ESD_SUPPORT
|
||||
&ESD_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_DIRECTX
|
||||
&DSOUND_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_WINDIB
|
||||
&WAVEOUT_bootstrap,
|
||||
#endif
|
||||
#ifdef __BEOS__
|
||||
&BAUDIO_bootstrap,
|
||||
#endif
|
||||
#ifdef macintosh
|
||||
&AUDIO_bootstrap,
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
&Paud_bootstrap,
|
||||
#endif
|
||||
#ifdef ENABLE_CYBERGRAPHICS
|
||||
&AHI_bootstrap,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
SDL_AudioDevice *current_audio = NULL;
|
||||
|
||||
/* Various local functions */
|
||||
int SDL_AudioInit(const char *driver_name);
|
||||
void SDL_AudioQuit(void);
|
||||
|
||||
struct SignalSemaphore AudioSem;
|
||||
|
||||
/* The general mixing thread function */
|
||||
int RunAudio(void *audiop)
|
||||
{
|
||||
SDL_AudioDevice *audio = (SDL_AudioDevice *)audiop;
|
||||
Uint8 *stream;
|
||||
int stream_len;
|
||||
void *udata;
|
||||
void (*fill)(void *userdata,Uint8 *stream, int len);
|
||||
int silence,started=0;
|
||||
|
||||
D(bug("Task audio started audio struct:<%lx>...\n",audiop));
|
||||
|
||||
D(bug("Before Openaudio..."));
|
||||
if(audio->OpenAudio(audio, &audio->spec)==-1)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
D(bug("OpenAudio...OK\n"));
|
||||
|
||||
/* Perform any thread setup */
|
||||
if ( audio->ThreadInit ) {
|
||||
audio->ThreadInit(audio);
|
||||
}
|
||||
audio->threadid = SDL_ThreadID();
|
||||
|
||||
/* Set up the mixing function */
|
||||
fill = audio->spec.callback;
|
||||
udata = audio->spec.userdata;
|
||||
if ( audio->convert.needed ) {
|
||||
if ( audio->convert.src_format == AUDIO_U8 ) {
|
||||
silence = 0x80;
|
||||
D(bug("*** Silence 0x80 ***\n"));
|
||||
} else {
|
||||
silence = 0;
|
||||
}
|
||||
stream_len = audio->convert.len;
|
||||
} else {
|
||||
silence = audio->spec.silence;
|
||||
stream_len = audio->spec.size;
|
||||
}
|
||||
stream = audio->fake_stream;
|
||||
|
||||
ObtainSemaphore(&AudioSem);
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
|
||||
D(bug("Enering audio loop...\n"));
|
||||
|
||||
D(if(audio->convert.needed)bug("*** Conversion needed.\n"));
|
||||
|
||||
/* Loop, filling the audio buffers */
|
||||
while ( audio->enabled )
|
||||
{
|
||||
/* Wait for new current buffer to finish playing */
|
||||
|
||||
if ( stream == audio->fake_stream )
|
||||
SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
|
||||
else
|
||||
{
|
||||
if(started>1)
|
||||
{
|
||||
// D(bug("Waiting audio...\n"));
|
||||
audio->WaitAudio(audio);
|
||||
}
|
||||
}
|
||||
|
||||
ObtainSemaphore(&AudioSem);
|
||||
|
||||
/* Fill the current buffer with sound */
|
||||
if ( audio->convert.needed ) {
|
||||
stream = audio->convert.buf;
|
||||
} else {
|
||||
stream = audio->GetAudioBuf(audio);
|
||||
}
|
||||
|
||||
if(stream!=audio->fake_stream)
|
||||
memset(stream, silence, stream_len);
|
||||
|
||||
if ( ! audio->paused ) {
|
||||
ObtainSemaphore(&audio->mixer_lock);
|
||||
(*fill)(udata, stream, stream_len);
|
||||
ReleaseSemaphore(&audio->mixer_lock);
|
||||
}
|
||||
|
||||
/* Convert the audio if necessary */
|
||||
if ( audio->convert.needed ) {
|
||||
SDL_ConvertAudio(&audio->convert);
|
||||
stream = audio->GetAudioBuf(audio);
|
||||
memcpy(stream, audio->convert.buf,audio->convert.len_cvt);
|
||||
}
|
||||
|
||||
if(stream!=audio->fake_stream)
|
||||
{
|
||||
// D(bug("Playing stream at %lx\n",stream));
|
||||
|
||||
audio->PlayAudio(audio);
|
||||
started++;
|
||||
}
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
|
||||
}
|
||||
D(bug("Out of subtask loop...\n"));
|
||||
|
||||
/* Wait for the audio to drain.. */
|
||||
if ( audio->WaitDone ) {
|
||||
audio->WaitDone(audio);
|
||||
}
|
||||
|
||||
D(bug("WaitAudio...Done\n"));
|
||||
|
||||
audio->CloseAudio(audio);
|
||||
|
||||
D(bug("CloseAudio..Done, subtask exiting...\n"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int SDL_AudioInit(const char *driver_name)
|
||||
{
|
||||
SDL_AudioDevice *audio;
|
||||
int i = 0, idx;
|
||||
|
||||
/* Check to make sure we don't overwrite 'current_audio' */
|
||||
if ( current_audio != NULL ) {
|
||||
SDL_AudioQuit();
|
||||
}
|
||||
|
||||
/* Select the proper audio driver */
|
||||
audio = NULL;
|
||||
idx = 0;
|
||||
|
||||
InitSemaphore(&AudioSem);
|
||||
|
||||
if ( audio == NULL ) {
|
||||
if ( driver_name != NULL ) {
|
||||
if ( strrchr(driver_name, ':') != NULL ) {
|
||||
idx = atoi(strrchr(driver_name, ':')+1);
|
||||
}
|
||||
for ( i=0; bootstrap[i]; ++i ) {
|
||||
if (strncmp(bootstrap[i]->name, driver_name,
|
||||
strlen(bootstrap[i]->name)) == 0) {
|
||||
if ( bootstrap[i]->available() ) {
|
||||
audio=bootstrap[i]->create(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( i=0; bootstrap[i]; ++i ) {
|
||||
if ( bootstrap[i]->available() ) {
|
||||
audio = bootstrap[i]->create(idx);
|
||||
if ( audio != NULL ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( audio == NULL ) {
|
||||
SDL_SetError("No available audio device");
|
||||
#if 0 /* Don't fail SDL_Init() if audio isn't available.
|
||||
SDL_OpenAudio() will handle it at that point. *sigh*
|
||||
*/
|
||||
return(-1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
current_audio = audio;
|
||||
if ( current_audio ) {
|
||||
current_audio->name = bootstrap[i]->name;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
char *SDL_AudioDriverName(char *namebuf, int maxlen)
|
||||
{
|
||||
if ( current_audio != NULL ) {
|
||||
strncpy(namebuf, current_audio->name, maxlen-1);
|
||||
namebuf[maxlen-1] = '\0';
|
||||
return(namebuf);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
||||
{
|
||||
SDL_AudioDevice *audio;
|
||||
|
||||
/* Start up the audio driver, if necessary */
|
||||
if ( ! current_audio ) {
|
||||
if ( (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) ||
|
||||
(current_audio == NULL) ) {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
audio = current_audio;
|
||||
|
||||
D(bug("Chiamata SDL_OpenAudio...\n"));
|
||||
|
||||
/* Verify some parameters */
|
||||
if ( desired->callback == NULL ) {
|
||||
SDL_SetError("SDL_OpenAudio() passed a NULL callback");
|
||||
return(-1);
|
||||
}
|
||||
switch ( desired->channels ) {
|
||||
case 1: /* Mono */
|
||||
case 2: /* Stereo */
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("1 (mono) and 2 (stereo) channels supported");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Create a semaphore for locking the sound buffers */
|
||||
InitSemaphore(&audio->mixer_lock);
|
||||
|
||||
/* Calculate the silence and size of the audio specification */
|
||||
SDL_CalculateAudioSpec(desired);
|
||||
|
||||
/* Open the audio subsystem */
|
||||
memcpy(&audio->spec, desired, sizeof(audio->spec));
|
||||
audio->convert.needed = 0;
|
||||
audio->enabled = 1;
|
||||
audio->paused = 1;
|
||||
|
||||
ObtainSemaphore(&AudioSem);
|
||||
|
||||
audio->thread = SDL_CreateThread(RunAudio, audio);
|
||||
|
||||
if ( audio->thread == NULL ) {
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
SDL_CloseAudio();
|
||||
SDL_SetError("Couldn't create audio thread");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* If the audio driver changes the buffer size, accept it */
|
||||
if ( audio->spec.samples != desired->samples ) {
|
||||
desired->samples = audio->spec.samples;
|
||||
SDL_CalculateAudioSpec(desired);
|
||||
}
|
||||
|
||||
/* Allocate a fake audio memory buffer */
|
||||
audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
|
||||
if ( audio->fake_stream == NULL ) {
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
SDL_CloseAudio();
|
||||
SDL_OutOfMemory();
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* See if we need to do any conversion */
|
||||
if ( memcmp(desired, &audio->spec, sizeof(audio->spec)) == 0 ) {
|
||||
/* Just copy over the desired audio specification */
|
||||
if ( obtained != NULL ) {
|
||||
memcpy(obtained, &audio->spec, sizeof(audio->spec));
|
||||
}
|
||||
} else {
|
||||
/* Copy over the audio specification if possible */
|
||||
if ( obtained != NULL ) {
|
||||
memcpy(obtained, &audio->spec, sizeof(audio->spec));
|
||||
} else {
|
||||
/* Build an audio conversion block */
|
||||
D(bug("Need conversion:\n desired: C:%ld F:%ld T:%lx\navailable: C:%ld F:%ld T:%lx\n",
|
||||
desired->channels, desired->freq, desired->format,
|
||||
audio->spec.channels,audio->spec.freq,audio->spec.format));
|
||||
|
||||
Forbid();
|
||||
|
||||
// Magari poi lo sostiutisco con un semaforo.
|
||||
|
||||
if ( SDL_BuildAudioCVT(&audio->convert,
|
||||
desired->format, desired->channels,
|
||||
desired->freq,
|
||||
audio->spec.format, audio->spec.channels,
|
||||
audio->spec.freq) < 0 ) {
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
SDL_CloseAudio();
|
||||
return(-1);
|
||||
}
|
||||
if ( audio->convert.needed ) {
|
||||
audio->convert.len = desired->size;
|
||||
audio->convert.buf =(Uint8 *)SDL_AllocAudioMem(
|
||||
audio->convert.len*audio->convert.len_mult);
|
||||
if ( audio->convert.buf == NULL ) {
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
SDL_CloseAudio();
|
||||
SDL_OutOfMemory();
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseSemaphore(&AudioSem);
|
||||
|
||||
D(bug("SDL_OpenAudio USCITA...\n"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
SDL_audiostatus SDL_GetAudioStatus(void)
|
||||
{
|
||||
SDL_AudioDevice *audio = current_audio;
|
||||
SDL_audiostatus status;
|
||||
|
||||
status = SDL_AUDIO_STOPPED;
|
||||
if ( audio && audio->enabled ) {
|
||||
if ( audio->paused ) {
|
||||
status = SDL_AUDIO_PAUSED;
|
||||
} else {
|
||||
status = SDL_AUDIO_PLAYING;
|
||||
}
|
||||
}
|
||||
return(status);
|
||||
}
|
||||
|
||||
void SDL_PauseAudio (int pause_on)
|
||||
{
|
||||
SDL_AudioDevice *audio = current_audio;
|
||||
|
||||
if ( audio ) {
|
||||
audio->paused = pause_on;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_LockAudio (void)
|
||||
{
|
||||
SDL_AudioDevice *audio = current_audio;
|
||||
|
||||
/* Obtain a lock on the mixing buffers */
|
||||
if ( audio ) {
|
||||
if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
|
||||
return;
|
||||
}
|
||||
ObtainSemaphore(&audio->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_UnlockAudio (void)
|
||||
{
|
||||
SDL_AudioDevice *audio = current_audio;
|
||||
|
||||
/* Release lock on the mixing buffers */
|
||||
if ( audio ) {
|
||||
if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
|
||||
return;
|
||||
}
|
||||
ReleaseSemaphore(&audio->mixer_lock);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_CloseAudio (void)
|
||||
{
|
||||
SDL_AudioDevice *audio = current_audio;
|
||||
|
||||
if ( audio ) {
|
||||
if(audio->enabled)
|
||||
{
|
||||
audio->enabled = 0;
|
||||
|
||||
if ( audio->thread != NULL ) {
|
||||
D(bug("Waiting audio thread...\n"));
|
||||
SDL_WaitThread(audio->thread, NULL);
|
||||
D(bug("...audio replied\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if ( audio->fake_stream != NULL ) {
|
||||
SDL_FreeAudioMem(audio->fake_stream);
|
||||
audio->fake_stream=NULL;
|
||||
}
|
||||
if ( audio->convert.needed && current_audio->convert.buf!=NULL) {
|
||||
SDL_FreeAudioMem(audio->convert.buf);
|
||||
current_audio->convert.buf=NULL;
|
||||
}
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
}
|
||||
|
||||
void SDL_AudioQuit(void)
|
||||
{
|
||||
if ( current_audio ) {
|
||||
if(current_audio->enabled)
|
||||
{
|
||||
D(bug("Closing audio in AudioQuit...\n"));
|
||||
current_audio->enabled = 0;
|
||||
|
||||
if ( current_audio->thread != NULL ) {
|
||||
D(bug("Waiting audio thread...\n"));
|
||||
SDL_WaitThread(current_audio->thread, NULL);
|
||||
D(bug("...audio replied\n"));
|
||||
}
|
||||
}
|
||||
if ( current_audio->fake_stream != NULL ) {
|
||||
SDL_FreeAudioMem(current_audio->fake_stream);
|
||||
}
|
||||
if ( current_audio->convert.needed &&
|
||||
current_audio->convert.buf) {
|
||||
SDL_FreeAudioMem(current_audio->convert.buf);
|
||||
}
|
||||
|
||||
current_audio->free(current_audio);
|
||||
current_audio = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_FORMATS 6
|
||||
static int format_idx;
|
||||
static int format_idx_sub;
|
||||
static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
|
||||
{ AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
|
||||
{ AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
|
||||
{ AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 },
|
||||
{ AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 },
|
||||
{ AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 },
|
||||
{ AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 },
|
||||
};
|
||||
|
||||
Uint16 SDL_FirstAudioFormat(Uint16 format)
|
||||
{
|
||||
for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) {
|
||||
if ( format_list[format_idx][0] == format ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
format_idx_sub = 0;
|
||||
return(SDL_NextAudioFormat());
|
||||
}
|
||||
|
||||
Uint16 SDL_NextAudioFormat(void)
|
||||
{
|
||||
if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) {
|
||||
return(0);
|
||||
}
|
||||
return(format_list[format_idx][format_idx_sub++]);
|
||||
}
|
||||
|
||||
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
|
||||
{
|
||||
switch (spec->format) {
|
||||
case AUDIO_U8:
|
||||
spec->silence = 0x80;
|
||||
break;
|
||||
default:
|
||||
spec->silence = 0x00;
|
||||
break;
|
||||
}
|
||||
spec->size = (spec->format&0xFF)/8;
|
||||
spec->size *= spec->channels;
|
||||
spec->size *= spec->samples;
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
SDL - Simple DirectMedia Layer
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Sam Lantinga
|
||||
slouken@devolution.com
|
||||
*/
|
||||
|
||||
#ifdef SAVE_RCSID
|
||||
static char rcsid =
|
||||
"@(#) $Id$";
|
||||
#endif
|
||||
|
||||
#ifndef _SDL_sysaudio_h
|
||||
#define _SDL_sysaudio_h
|
||||
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#include <exec/exec.h>
|
||||
#include <dos/dos.h>
|
||||
#ifdef __SASC
|
||||
#include <proto/exec.h>
|
||||
#else
|
||||
#include <inline/exec.h>
|
||||
#endif
|
||||
|
||||
#include <devices/ahi.h>
|
||||
#include "mydebug.h"
|
||||
|
||||
/* The SDL audio driver */
|
||||
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
||||
|
||||
/* Define the SDL audio driver structure */
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
#ifndef _STATUS
|
||||
#define _STATUS SDL_status *status
|
||||
#endif
|
||||
struct SDL_AudioDevice {
|
||||
/* * * */
|
||||
/* The name of this audio driver */
|
||||
const char *name;
|
||||
|
||||
/* * * */
|
||||
/* Public driver functions */
|
||||
int (*OpenAudio)(_THIS, SDL_AudioSpec *spec);
|
||||
void (*ThreadInit)(_THIS); /* Called by audio thread at start */
|
||||
void (*WaitAudio)(_THIS);
|
||||
void (*PlayAudio)(_THIS);
|
||||
Uint8 *(*GetAudioBuf)(_THIS);
|
||||
void (*WaitDone)(_THIS);
|
||||
void (*CloseAudio)(_THIS);
|
||||
|
||||
/* * * */
|
||||
/* Data common to all devices */
|
||||
|
||||
/* The current audio specification (shared with audio thread) */
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
/* An audio conversion block for audio format emulation */
|
||||
SDL_AudioCVT convert;
|
||||
|
||||
/* Current state flags */
|
||||
int enabled;
|
||||
int paused;
|
||||
|
||||
/* Fake audio buffer for when the audio hardware is busy */
|
||||
Uint8 *fake_stream;
|
||||
|
||||
/* A semaphore for locking the mixing buffers */
|
||||
struct SignalSemaphore mixer_lock;
|
||||
|
||||
/* A thread to feed the audio device */
|
||||
SDL_Thread *thread;
|
||||
Uint32 threadid;
|
||||
|
||||
/* * * */
|
||||
/* Data private to this driver */
|
||||
struct SDL_PrivateAudioData *hidden;
|
||||
|
||||
/* * * */
|
||||
/* The function used to dispose of this structure */
|
||||
void (*free)(_THIS);
|
||||
};
|
||||
#undef _THIS
|
||||
|
||||
typedef struct AudioBootStrap {
|
||||
const char *name;
|
||||
int (*available)(void);
|
||||
SDL_AudioDevice *(*create)(int devindex);
|
||||
} AudioBootStrap;
|
||||
|
||||
#ifdef ESD_SUPPORT
|
||||
extern AudioBootStrap ESD_bootstrap;
|
||||
#endif
|
||||
#ifdef linux
|
||||
extern AudioBootStrap DMA_bootstrap;
|
||||
#endif
|
||||
#ifdef unix
|
||||
extern AudioBootStrap AUDIO_bootstrap;
|
||||
#endif
|
||||
#ifdef ENABLE_WINDIB
|
||||
extern AudioBootStrap WAVEOUT_bootstrap;
|
||||
#endif
|
||||
#ifdef ENABLE_DIRECTX
|
||||
extern AudioBootStrap DSOUND_bootstrap;
|
||||
#endif
|
||||
#ifdef __BEOS__
|
||||
extern AudioBootStrap BAUDIO_bootstrap;
|
||||
#endif
|
||||
#ifdef macintosh
|
||||
extern AudioBootStrap AUDIO_bootstrap;
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
extern AudioBootStrap Paud_bootstrap;
|
||||
#endif
|
||||
#ifdef ENABLE_CYBERGRAPHICS
|
||||
extern AudioBootStrap AHI_bootstrap;
|
||||
#endif
|
||||
|
||||
/* This is the current audio device */
|
||||
extern SDL_AudioDevice *current_audio;
|
||||
|
||||
#ifndef __SASC
|
||||
extern struct ExecBase *SysBase;
|
||||
#endif
|
||||
|
||||
#endif /* _SDL_sysaudio_h */
|
Loading…
Add table
Add a link
Reference in a new issue