Merge pull request #642 from Holzhaus/audio-system-cleanup

Audio backends cleanup
This commit is contained in:
TwistedUmbrella 2015-06-27 18:31:31 -04:00
commit 28a6d1d9b6
24 changed files with 446 additions and 332 deletions

View File

@ -110,9 +110,6 @@ void emit_WriteCodeCache();
static int JoyFD = -1; // Joystick file descriptor
static int kbfd = -1;
#ifdef TARGET_PANDORA
static int audio_fd = -1;
#endif
#define MAP_SIZE 32
@ -755,7 +752,6 @@ void clean_exit(int sig_num) {
// close files
if (JoyFD>=0) close(JoyFD);
if (kbfd>=0) close(kbfd);
if(audio_fd>=0) close(audio_fd);
// Close EGL context ???
if (sig_num!=0)
@ -781,26 +777,6 @@ void clean_exit(int sig_num) {
}
}
void init_sound()
{
if((audio_fd=open("/dev/dsp",O_WRONLY))<0) {
printf("Couldn't open /dev/dsp.\n");
}
else
{
printf("sound enabled, dsp openned for write\n");
int tmp=44100;
int err_ret;
err_ret=ioctl(audio_fd,SNDCTL_DSP_SPEED,&tmp);
printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp);
int channels=2;
err_ret=ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels);
printf("set dsp to stereo (%i => %i)\n", channels, err_ret);
int format=AFMT_S16_LE;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret);
}
}
#endif
int main(int argc, wchar* argv[])
@ -812,11 +788,6 @@ int main(int argc, wchar* argv[])
#ifdef TARGET_PANDORA
signal(SIGSEGV, clean_exit);
signal(SIGKILL, clean_exit);
init_sound();
#else
void os_InitAudio();
os_InitAudio();
#endif
#if defined(USES_HOMEDIR) && HOST_OS != OS_DARWIN
@ -873,21 +844,6 @@ int main(int argc, wchar* argv[])
return 0;
}
u32 alsa_Push(void* frame, u32 samples, bool wait);
u32 os_Push(void* frame, u32 samples, bool wait)
{
#ifndef TARGET_PANDORA
int audio_fd = -1;
#endif
if (audio_fd > 0) {
write(audio_fd, frame, samples*4);
} else {
return alsa_Push(frame, samples, wait);
}
return 1;
}
#endif
int get_mic_data(u8* buffer) { return 0; }

View File

@ -1,81 +1,12 @@
#include "audiostream_rif.h"
#include "oslib/oslib.h"
#include "cfg/cfg.h"
#if HOST_OS==OS_LINUX && !defined(TARGET_NACL32) && !defined(ANDROID)
#if 1
#include "oslib/audiobackend_alsa.h"
#if USE_ALSA
#include <alsa/asoundlib.h>
#include <pthread.h>
snd_pcm_t *handle;
u32 alsa_Push(void* frame, u32 samples, bool wait) {
snd_pcm_nonblock(handle, wait ? 0 : 1);
int rc = snd_pcm_writei(handle, frame, samples);
if (rc == -EPIPE)
{
/* EPIPE means underrun */
fprintf(stderr, "ALSA: underrun occurred\n");
snd_pcm_prepare(handle);
alsa_Push(frame, samples * 8, wait);
}
else if (rc < 0)
{
fprintf(stderr, "ALSA: error from writei: %s\n", snd_strerror(rc));
}
else if (rc != samples)
{
fprintf(stderr, "ALSA: short write, wrote %d frames of %d\n", rc, samples);
}
return 1;
}
#if 0
u8 Tempbuffer[8192*4];
void* AudioThread(void*)
// We're making these functions static - there's no need to pollute the global namespace
static void alsa_init()
{
sched_param sched;
int policy;
pthread_getschedparam(pthread_self(),&policy,&sched);
sched.sched_priority++;//policy=SCHED_RR;
pthread_setschedparam(pthread_self(),policy,&sched);
for(;;)
{
UpdateBuff(Tempbuffer);
int rc = snd_pcm_writei(handle, Tempbuffer, settings.aica.BufferSize);
if (rc == -EPIPE)
{
/* EPIPE means underrun */
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
}
else if (rc < 0)
{
fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
}
else if (rc != (int)settings.aica.BufferSize)
{
fprintf(stderr, "short write, write %d frames\n", rc);
}
}
}
cThread aud_thread(AudioThread,0);
#endif
void os_InitAudio()
{
if (cfgLoadInt("audio","disable",0))
return;
cfgSaveInt("audio","disable",0);
long loops;
int size;
@ -171,12 +102,40 @@ void os_InitAudio()
}
}
void os_TermAudio()
static u32 alsa_push(void* frame, u32 samples, bool wait)
{
snd_pcm_nonblock(handle, wait ? 0 : 1);
int rc = snd_pcm_writei(handle, frame, samples);
if (rc == -EPIPE)
{
/* EPIPE means underrun */
fprintf(stderr, "ALSA: underrun occurred\n");
snd_pcm_prepare(handle);
alsa_push(frame, samples * 8, wait);
}
else if (rc < 0)
{
fprintf(stderr, "ALSA: error from writei: %s\n", snd_strerror(rc));
}
else if (rc != samples)
{
fprintf(stderr, "ALSA: short write, wrote %d frames of %d\n", rc, samples);
}
return 1;
}
static void alsa_term()
{
snd_pcm_drain(handle);
snd_pcm_close(handle);
}
#else
audiobackend_t audiobackend_alsa = {
"alsa", // Slug
"Advanced Linux Sound Architecture", // Name
&alsa_init,
&alsa_push,
&alsa_term
};
#endif
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_alsa;

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_android;

View File

@ -1,10 +1,8 @@
#include "types.h"
#include "oslib/audiobackend_directsound.h"
#if HOST_OS==OS_WINDOWS
#include "oslib.h"
#include <initguid.h>
#include <dsound.h>
#include "audiostream_rif.h"
#include "oslib.h"
void* SoundThread(void* param);
#define V2_BUFFERSZ (16*1024)
@ -14,7 +12,7 @@ IDirectSoundBuffer8* buffer;
u32 ds_ring_size;
void os_InitAudio()
static void directsound_init()
{
verifyc(DirectSoundCreate8(NULL,&dsound,NULL));
@ -80,7 +78,7 @@ void os_InitAudio()
DWORD wc=0;
int os_getfreesz()
static int directsound_getfreesz()
{
DWORD pc,wch;
@ -96,25 +94,12 @@ int os_getfreesz()
return fsz;
}
int os_getusedSamples()
static int directsound_getusedSamples()
{
return (ds_ring_size-os_getfreesz())/4;
return (ds_ring_size-directsound_getfreesz())/4;
}
bool os_IsAudioBuffered()
{
return os_getusedSamples()>=3000;
}
bool os_IsAudioBufferedLots()
{
u32 xxx=os_getusedSamples();
return xxx>=4096;
}
u32 os_Push_nw(void* frame, u32 samplesb)
static u32 directsound_push_nw(void* frame, u32 samplesb)
{
DWORD pc,wch;
@ -155,7 +140,7 @@ u32 os_Push_nw(void* frame, u32 samplesb)
//ds_ring_size
}
u32 os_Push(void* frame, u32 samples, bool wait)
static u32 directsound_push(void* frame, u32 samples, bool wait)
{
u16* f=(u16*)frame;
@ -175,16 +160,17 @@ u32 os_Push(void* frame, u32 samples, bool wait)
int ffs=1;
while (os_IsAudioBufferedLots() && wait)
while (directsound_IsAudioBufferedLots() && wait)
if (ffs == 0)
ffs = printf("AUD WAIT %d\n",os_getusedSamples());
ffs = printf("AUD WAIT %d\n", directsound_getusedSamples());
while(!os_Push_nw(frame,samples) && wait)
printf("FAILED waiting on audio FAILED %d\n",os_getusedSamples());
while(!directsound_Push_nw(frame,samples) && wait)
printf("FAILED waiting on audio FAILED %d\n", directsound_getusedSamples());
return 1;
}
void os_TermAudio()
static void directsound_term()
{
buffer->Stop();
@ -192,4 +178,11 @@ void os_TermAudio()
dsound->Release();
}
#endif
audiobackend_t audiobackend_directsound = {
"directsound", // Slug
"Microsoft DirectSound", // Name
&directsound_init,
&directsound_push,
&directsound_term
};
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_directsound;

View File

@ -0,0 +1,54 @@
#include "oslib/audiobackend_oss.h"
#ifdef USE_OSS
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/unistd.h>
#include <sys/soundcard.h>
static int oss_audio_fd = -1;
static void oss_init()
{
oss_audio_fd = open("/dev/dsp", O_WRONLY);
if (oss_audio_fd < 0)
{
printf("Couldn't open /dev/dsp.\n");
}
else
{
printf("sound enabled, dsp openned for write\n");
int tmp=44100;
int err_ret;
err_ret=ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&tmp);
printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp);
int channels=2;
err_ret=ioctl(oss_audio_fd, SNDCTL_DSP_CHANNELS, &channels);
printf("set dsp to stereo (%i => %i)\n", channels, err_ret);
int format=AFMT_S16_LE;
err_ret=ioctl(oss_audio_fd, SNDCTL_DSP_SETFMT, &format);
printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed", AFMT_S16_LE, format, err_ret);
}
}
static u32 oss_push(void* frame, u32 samples, bool wait)
{
write(oss_audio_fd, frame, samples*4);
return 1;
}
static void oss_term() {
if(oss_audio_fd >= 0)
{
close(oss_audio_fd);
}
}
audiobackend_t audiobackend_oss = {
"oss", // Slug
"Open Sound System", // Name
&oss_init,
&oss_push,
&oss_term
};
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_oss;

View File

@ -0,0 +1,48 @@
#include "oslib/audiobackend_pulseaudio.h"
#ifdef USE_PULSEAUDIO
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/unistd.h>
#include <pulse/simple.h>
static pa_simple *pulse_stream;
static void pulseaudio_init()
{
pa_sample_spec ss;
ss.format = PA_SAMPLE_S16LE;
ss.channels = 2;
ss.rate = 44100;
/* Create a new playback stream */
pulse_stream = pa_simple_new(NULL, "reicast", PA_STREAM_PLAYBACK, NULL, "reicast", &ss, NULL, NULL, NULL);
if (!pulse_stream) {
fprintf(stderr, "PulseAudio: pa_simple_new() failed!\n");
}
}
static u32 pulseaudio_push(void* frame, u32 samples, bool wait)
{
if (pa_simple_write(pulse_stream, frame, (size_t) samples*4, NULL) < 0) {
fprintf(stderr, "PulseAudio: pa_simple_write() failed!\n");
}
}
static void pulseaudio_term() {
if(pulse_stream != NULL)
{
// Make sure that every single sample was played
if (pa_simple_drain(pulse_stream, NULL) < 0) {
fprintf(stderr, "PulseAudio: pa_simple_drain() failed!\n");
}
pa_simple_free(pulse_stream);
}
}
audiobackend_t audiobackend_pulseaudio = {
"pulse", // Slug
"PulseAudio", // Name
&pulseaudio_init,
&pulseaudio_push,
&pulseaudio_term
};
#endif

View File

@ -0,0 +1,4 @@
#pragma once
#include "oslib/audiostream.h"
extern audiobackend_t audiobackend_pulseaudio;

View File

@ -1,8 +1,12 @@
#include "audiostream_rif.h"
#include "stdclass.h"
#include <limits.h>
#include "cfg/cfg.h"
#include "oslib/oslib.h"
//cResetEvent speed_limit(true,true);
#include "audiostream.h"
#include "oslib/audiobackend_directsound.h"
#include "oslib/audiobackend_android.h"
#include "oslib/audiobackend_alsa.h"
#include "oslib/audiobackend_oss.h"
#include "oslib/audiobackend_pulseaudio.h"
struct SoundFrame { s16 l;s16 r; };
#define SAMPLE_COUNT 512
@ -16,14 +20,117 @@ volatile u32 ReadPtr; //next sample to read
u32 gen_samples=0;
double time_diff, time_last;
double time_diff = 128/44100.0;
double time_last;
#ifdef LOG_SOUND
WaveWriter rawout("d:\\aica_out.wav");
#endif
static bool audiobackends_registered = false;
static unsigned int audiobackends_num_max = 1;
static unsigned int audiobackends_num_registered = 0;
static audiobackend_t **audiobackends = static_cast<audiobackend_t**>(calloc(audiobackends_num_max, sizeof(audiobackend_t*)));
static audiobackend_t *audiobackend_current = NULL;
u32 os_Push(void* frame, u32 amt, bool wait);
//void os_Pull(u32 level)
bool RegisterAudioBackend(audiobackend_t *backend)
{
/* This function announces the availability of an audio backend to reicast. */
// Check if backend is valid
if (backend == NULL)
{
printf("ERROR: Tried to register invalid audio backend (NULL pointer).\n");
return false;
}
if (backend->slug == "auto" || backend->slug == "none") {
printf("ERROR: Tried to register invalid audio backend (slug \"%s\" is a reserved keyword).\n", backend->slug.c_str());
return false;
}
// Check if we need to allocate addition memory for storing the pointers and allocate if neccessary
if (audiobackends_num_registered == audiobackends_num_max)
{
// Check for integer overflows
if (audiobackends_num_max == UINT_MAX)
{
printf("ERROR: Registering audio backend \"%s\" (%s) failed. Cannot register more than %u backends\n", backend->slug.c_str(), backend->name.c_str(), audiobackends_num_max);
return false;
}
audiobackends_num_max++;
audiobackend_t **new_ptr = static_cast<audiobackend_t**>(realloc(audiobackends, audiobackends_num_max*sizeof(audiobackend_t*)));
// Make sure that allocation worked
if (new_ptr == NULL)
{
printf("ERROR: Registering audio backend \"%s\" (%s) failed. Cannot allocate additional memory.\n", backend->slug.c_str(), backend->name.c_str());
return false;
}
audiobackends = new_ptr;
}
audiobackends[audiobackends_num_registered] = backend;
audiobackends_num_registered++;
return true;
}
void RegisterAllAudioBackends() {
#if HOST_OS==OS_WINDOWS
RegisterAudioBackend(&audiobackend_directsound);
#endif
#if ANDROID
RegisterAudioBackend(&audiobackend_android);
#endif
#if USE_ALSA
RegisterAudioBackend(&audiobackend_alsa);
#endif
#if USE_OSS
RegisterAudioBackend(&audiobackend_oss);
#endif
#if USE_PULSEAUDIO
RegisterAudioBackend(&audiobackend_pulseaudio);
#endif
audiobackends_registered = true;
}
static audiobackend_t* GetAudioBackend(std::string slug)
{
if (slug == "none")
{
printf("WARNING: Audio backend set to \"none\"!\n");
}
else if(audiobackends_num_registered > 0)
{
if (slug == "auto")
{
/* FIXME: At some point, one might want to insert some intelligent
algorithm for autoselecting the approriate audio backend here.
I'm too lazy right now. */
printf("Auto-selected audio backend \"%s\" (%s).\n", audiobackends[0]->slug.c_str(), audiobackends[0]->name.c_str());
return audiobackends[0];
}
else
{
for(unsigned int i = 0; i < audiobackends_num_registered; i++)
{
if(audiobackends[i]->slug == slug)
{
return audiobackends[i];
}
}
printf("WARNING: Audio backend \"%s\" not found!\n", slug.c_str());
}
}
else
{
printf("WARNING: No audio backends available!\n");
}
return NULL;
}
u32 PushAudio(void* frame, u32 amt, bool wait) {
if (audiobackend_current != NULL) {
return audiobackend_current->push(frame, amt, wait);
} else {
printf("AUDIO: Backend is NULL!\n");
}
return 0;
}
u32 asRingUsedCount()
{
@ -41,49 +148,6 @@ u32 asRingFreeCount()
void WriteSample(s16 r, s16 l)
{
#if 0
#if HOST_OS==OS_WINDOWS
#ifdef LOG_SOUND
rawout.Write(l,r);
#endif
if (!asRingFreeCount())
{
//printf("Buffer overrun\n");
if (settings.aica.LimitFPS)
{
//speed_limit.Wait();
}
else
return;
}
gen_samples++;
//while limit on, 128 samples done, there is a buffer ready to be service AND speed is too fast then wait
if (settings.aica.LimitFPS==1 && gen_samples>128)
{
for(;asRingUsedCount()>BufferSampleCount && (os_GetSeconds()-time_last)<=time_diff;)
;
gen_samples=0;
time_last=os_GetSeconds();
}
#else
if (!asRingFreeCount())
{
if (settings.aica.LimitFPS)
{
while(!asRingFreeCount()) ;
}
else
{
return;
}
}
#endif
#endif
const u32 ptr=(WritePtr+1)%RingBufferSampleCount;
RingBuffer[ptr].r=r;
RingBuffer[ptr].l=l;
@ -91,16 +155,44 @@ void WriteSample(s16 r, s16 l)
if (WritePtr==(SAMPLE_COUNT-1))
{
os_Push(RingBuffer,SAMPLE_COUNT,settings.aica.LimitFPS);
PushAudio(RingBuffer,SAMPLE_COUNT,settings.aica.LimitFPS);
}
}
void InitAudio()
{
time_diff=128/44100.0;
if (cfgLoadInt("audio", "disable", 0)) {
printf("WARNING: Audio disabled in config!\n");
return;
}
cfgSaveInt("audio","disable",0);
if (!audiobackends_registered) {
//FIXME: There might some nicer way to do this.
RegisterAllAudioBackends();
}
if (audiobackend_current != NULL) {
printf("ERROR: The audio backend \"%s\" (%s) has already been initialized, you need to terminate it before you can call audio_init() again!\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str());
return;
}
string audiobackend_slug = cfgLoadStr("audio", "backend", "auto"); // FIXME: This could be made a parameter
audiobackend_current = GetAudioBackend(audiobackend_slug);
if (audiobackend_current == NULL) {
printf("WARNING: Running without audio!\n");
return;
}
printf("Initializing audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str());
audiobackend_current->init();
}
void TermAudio()
{
if (audiobackend_current != NULL) {
audiobackend_current->term();
printf("Terminating audio backend \"%s\" (%s)...\n", audiobackend_current->slug.c_str(), audiobackend_current->name.c_str());
audiobackend_current = NULL;
}
}

26
core/oslib/audiostream.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include "types.h"
//Get used size in the ring buffer
u32 asRingUsedCount();
//Get free size in the ring buffer
u32 asRingFreeCount();
//Read 'Count' samples from the ring buffer.Returns true if successful.
//If sz==0 then a whole buffer is read
bool asRingRead(u8* dst,u32 count=0);
void UpdateBuff(u8* pos);
typedef void (*audio_backend_init_func_t)();
typedef u32 (*audio_backend_push_func_t)(void*, u32, bool);
typedef void (*audio_backend_term_func_t)();
typedef struct {
string slug;
string name;
audio_backend_init_func_t init;
audio_backend_push_func_t push;
audio_backend_term_func_t term;
} audiobackend_t;
extern bool RegisterAudioBackend(audiobackend_t* backend);
extern void InitAudio();
extern u32 PushAudio(void* frame, u32 amt, bool wait);
extern void TermAudio();

View File

@ -1,14 +0,0 @@
#pragma once
#include "types.h"
//Get used size in the ring buffer
u32 asRingUsedCount();
//Get free size in the ring buffer
u32 asRingFreeCount();
//Read 'Count' samples from the ring buffer.Returns true if successful.
//If sz==0 then a whole buffer is read
bool asRingRead(u8* dst,u32 count=0);
void UpdateBuff(u8* pos);
void os_InitAudio();
void os_TermAudio();

View File

@ -7,9 +7,6 @@ double os_GetSeconds();
void os_DoEvents();
void os_CreateWindow();
bool os_IsAudioBuffered();
int os_getusedSamples();
bool os_IsAudioBufferedLots();
void WriteSample(s16 right, s16 left);
#if BUILD_COMPILER==COMPILER_VC

View File

@ -17,11 +17,6 @@
#include <SDL/SDL.h>
#include <EGL/egl.h>
#ifdef USE_OSS
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#endif
#include <signal.h>
#include <execinfo.h>
@ -103,11 +98,6 @@ static SDL_Joystick *JoySDL = 0;
extern bool FrameSkipping;
#ifdef USE_OSS
static int audio_fd = -1;
#endif
#define MAP_SIZE 32
const u32 JMapBtn_USB[MAP_SIZE] =
@ -426,9 +416,6 @@ void clean_exit(int sig_num) {
// close files
if (JoySDL) SDL_JoystickClose(JoySDL);
#ifdef USE_OSS
if (audio_fd>=0) close(audio_fd);
#endif
// Close EGL context ???
if (sig_num!=0)
@ -437,37 +424,6 @@ void clean_exit(int sig_num) {
SDL_Quit();
}
#ifdef USE_OSS
void init_sound()
{
if((audio_fd=open("/dev/dsp",O_WRONLY))<0)
printf("Couldn't open /dev/dsp.\n");
else
{
printf("sound enabled, dsp openned for write\n");
int tmp=44100;
int err_ret;
err_ret=ioctl(audio_fd,SNDCTL_DSP_SPEED,&tmp);
printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp);
int channels=2;
err_ret=ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels);
printf("set dsp to stereo (%i => %i)\n", channels, err_ret);
int format=AFMT_S16_LE;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret);
int frag=(4<<16)|11;
int f=frag;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag);
printf("set dsp fragment to %i of %i bytes (0x%x => %i)\n", "16bits signed" ,(f>>16), 1<<(f&0xff), frag, err_ret);
/*
// this doesn't help stutering, and the emu goes too fast after that
err_ret=ioctl(audio_fd, SNDCTL_DSP_NONBLOCK, NULL);
printf("set dsp to non-blocking ( => %i)\n", err_ret);
*/
}
}
#endif
int main(int argc, wchar* argv[])
{
//if (argc==2)
@ -501,10 +457,6 @@ int main(int argc, wchar* argv[])
die("error initializing SDL");
SetupInput();
#ifdef USE_OSS
init_sound();
#endif
FrameSkipping=false;
@ -514,16 +466,3 @@ int main(int argc, wchar* argv[])
return 0;
}
u32 os_Push(void* frame, u32 samples, bool wait)
{
#ifdef USE_OSS
static bool blocking = true;
if (wait!=blocking) {
fcntl(audio_fd, F_SETFD, O_WRONLY | wait?0:O_NONBLOCK);
blocking=wait;
}
write(audio_fd, frame, samples*4);
#endif
return 1;
}

View File

@ -1,5 +1,5 @@
#include "oslib\oslib.h"
#include "oslib\audiostream_rif.h"
#include "oslib\audiostream.h"
#include "imgread\common.h"
#define _WIN32_WINNT 0x0500
@ -365,48 +365,6 @@ cResetEvent evt_hld(false,true);
double speed_load_mspdf;
extern double full_rps;
void os_wait_cycl(u32 cycl)
{
if (cycl>8*1000*1000)
cycl=8*1000*1000;
static double trolol=os_GetSeconds();
double newt=os_GetSeconds();
double ets=(newt-trolol)*200*1000*1000;
bool fast_enough=ets < cycl;
bool wait = full_rps >5 && (fast_enough || os_IsAudioBufferedLots());
speed_load_mspdf=(speed_load_mspdf*0.96235 + ets/cycl*10)/1.96235;
if (wait && os_IsAudioBuffered())
{
while (cycl_glob<cycl && os_IsAudioBuffered())
evt_hld.Wait(8);
if (cycl_glob>cycl)
InterlockedExchangeSubtract(&cycl_glob,cycl);
}
else //if (os_IsAudioBufferedLots())
{
//cycl_glob=0;
}
static int last_fe=fast_enough;
if (!fast_enough || !last_fe)
printf("Speed %.2f (%.2f%%) (%d)\n",ets/cycl*10,cycl/ets*100,os_getusedSamples());
last_fe=fast_enough;
trolol=os_GetSeconds();
}
void os_consume(double t)
{

View File

@ -16,6 +16,7 @@
#include "rend/TexCache.h"
#include "hw/maple/maple_devs.h"
#include "hw/maple/maple_if.h"
#include "oslib/audiobackend_android.h"
#include "util.h"
@ -485,7 +486,8 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_initControllers(JNIEn
env->ReleaseBooleanArrayElements(controllers, controllers_body, 0);
}
u32 os_Push(void* frame, u32 amt, bool wait)
// Audio Stuff
u32 androidaudio_push(void* frame, u32 amt, bool wait)
{
verify(amt==SAMPLE_COUNT);
//yeah, do some audio piping magic here !
@ -493,11 +495,29 @@ u32 os_Push(void* frame, u32 amt, bool wait)
return jenv->CallIntMethod(emu,writemid,jsamples,wait);
}
void androidaudio_init()
{
// Nothing to do here...
}
void androidaudio_term()
{
// Move along, there is nothing to see here!
}
bool os_IsAudioBuffered()
{
return jenv->CallIntMethod(emu,writemid,jsamples,-1)==0;
}
audiobackend_t audiobackend_android = {
"android", // Slug
"Android Audio", // Name
&androidaudio_init,
&androidaudio_push,
&androidaudio_term
};
int get_mic_data(u8* buffer)
{
jbyteArray jdata = (jbyteArray)jenv->CallObjectMethod(sipemu,getmicdata);

View File

@ -1,6 +1,9 @@
LOCAL_PATH := $(call my-dir)
FOR_LINUX :=1
USE_ALSA := 1
USE_OSS := 1
#USE_PULSEAUDIO := 1
RZDCY_SRC_DIR = ../../newdc
@ -55,7 +58,21 @@ INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I
LIBS := -L../linux-deps/lib
LIBS += -lm -lrt -lEGL -lGLESv2 #-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread -lasound -lX11 -lXdmcp -lXau
LIBS += -lpthread -lX11 -lXdmcp -lXau
ifdef USE_ALSA
CXXFLAGS += -D USE_ALSA
LIBS += -lasound
endif
ifdef USE_OSS
CXXFLAGS += -D USE_OSS
endif
ifdef USE_PULSEAUDIO
CXXFLAGS += -D USE_PULSEAUDIO
LIBS += -lpulse-simple
endif
OBJECTS=$(RZDCY_FILES:.cpp=.build_obj)

View File

@ -4,6 +4,9 @@ FOR_LINUX :=1
NOT_ARM := 1
NO_REC := 1
#NO_REND := 1
USE_ALSA := 1
#USE_OSS := 1
#USE_PULSEAUDIO := 1
RZDCY_SRC_DIR = ../../core
@ -62,7 +65,21 @@ INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos -I
LIBS := -L../linux-deps/lib -L./enta_viv
LIBS += -lglapi
LIBS += -lm -lrt -lEGL -lGLESv2 #-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread -lasound #-lX11 -lXdmcp -lXau
LIBS += -lpthread #-lX11 -lXdmcp -lXau
ifdef USE_ALSA
CXXFLAGS += -D USE_ALSA
LIBS += -lasound
endif
ifdef USE_OSS
CXXFLAGS += -D USE_OSS
endif
ifdef USE_PULSEAUDIO
CXXFLAGS += -D USE_PULSEAUDIO
LIBS += -lpulse-simple
endif
OBJECTS=$(RZDCY_FILES:.cpp=.build_obj)

View File

@ -550,6 +550,11 @@
9C7A3A7118C806E00070BB5F /* gl3platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl3platform.h; sourceTree = "<group>"; };
9C7A3A7318C806E00070BB5F /* khrplatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = khrplatform.h; sourceTree = "<group>"; };
9C7A3A7C18C806E00070BB5F /* nullDC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nullDC.cpp; sourceTree = "<group>"; };
9C7A3A7E18C806E00070BB5F /* alsa_audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = alsa_audiostream.cpp; sourceTree = "<group>"; };
9C7A3A7F18C806E00070BB5F /* audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiostream.cpp; sourceTree = "<group>"; };
9C7A3A8018C806E00070BB5F /* audiostream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiostream.h; sourceTree = "<group>"; };
9C7A3A8118C806E00070BB5F /* ds_audiostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ds_audiostream.cpp; sourceTree = "<group>"; };
9C7A3A8218C806E00070BB5F /* oslib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oslib.h; sourceTree = "<group>"; };
9C7A3A8418C806E00070BB5F /* profiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profiler.cpp; sourceTree = "<group>"; };
9C7A3A8518C806E00070BB5F /* profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = profiler.h; sourceTree = "<group>"; };
9C7A3A8618C806E00070BB5F /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };

View File

@ -6,6 +6,9 @@ X86_REC := 1
#NO_REC := 1
#NO_REND := 1
WEBUI :=1
USE_ALSA := 1
USE_OSS := 1
#USE_PULSEAUDIO := 1
RZDCY_SRC_DIR = ../../core
@ -71,7 +74,21 @@ LIBS += -lm -lrt
LIBS += -ldl -lGL #for desktop gl
#use this for GLES
#LIBS += -lEGL -lGLESv2 #-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread -lasound -lX11
LIBS += -lpthread -lX11
ifdef USE_ALSA
CXXFLAGS += -D USE_ALSA
LIBS += -lasound
endif
ifdef USE_OSS
CXXFLAGS += -D USE_OSS
endif
ifdef USE_PULSEAUDIO
CXXFLAGS += -D USE_PULSEAUDIO
LIBS += -lpulse-simple
endif
OBJECTS=$(RZDCY_FILES:.cpp=.build_obj)

View File

@ -4,7 +4,9 @@ FOR_LINUX :=1
FOR_ARM :=1
FOR_PANDORA :=1
USE_SDL :=1
#USE_ALSA :=1
USE_OSS :=1
#USE_PULSEAUDIO :=1
#PGO_MAKE :=1
#PGO_USE :=1
#USE_CCACHE :=1
@ -79,12 +81,20 @@ LIBS += -lm -lrt -lEGL -lGLESv2
#-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread
ifdef USE_OSS
CXXFLAGS += -DUSE_OSS
else
ifdef USE_ALSA
CXXFLAGS += -D USE_ALSA
LIBS += -lasound
endif
ifdef USE_OSS
CXXFLAGS += -D USE_OSS
endif
ifdef USE_PULSEAUDIO
CXXFLAGS += -D USE_PULSEAUDIO
LIBS += -lpulse-simple
endif
ifdef USE_SDL
LIBS += `sdl-config --libs`
else

View File

@ -317,7 +317,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Fast|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Fast|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\core\oslib\audiostream_rif.h" />
<ClInclude Include="..\core\oslib\audiostream.h" />
<ClInclude Include="..\core\oslib\oslib.h" />
<ClInclude Include="..\core\profiler\profiler.h" />
<ClInclude Include="..\core\rec-x86\win86_ngen.h">

View File

@ -751,7 +751,7 @@
<ClInclude Include="..\core\hw\sh4\sh4_mem.h">
<Filter>hw\sh4</Filter>
</ClInclude>
<ClInclude Include="..\core\oslib\audiostream_rif.h">
<ClInclude Include="..\core\oslib\audiostream.h">
<Filter>oslib</Filter>
</ClInclude>
<ClInclude Include="..\core\hw\sh4\modules\ccn.h">