Some work in the lowlevel sound code.
- Added framework for polling wave data and use it for beep output in sdl. - Some work in the beep thread code (to be continued). - Moved macros required for multithreading to bochs.h.
This commit is contained in:
parent
2357175d79
commit
0c205fce26
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2014 The Bochs Project
|
||||
// Copyright (C) 2001-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -600,4 +600,19 @@ BX_CPP_INLINE Bit64u bx_bswap64(Bit64u val64)
|
||||
#define CopyHostQWordLittleEndian(hostAddrDst, hostAddrSrc) \
|
||||
(* (Bit64u *)(hostAddrDst)) = (* (Bit64u *)(hostAddrSrc));
|
||||
|
||||
// multithreading support
|
||||
#ifdef WIN32
|
||||
#define BX_LOCK(mutex) EnterCriticalSection(&(mutex))
|
||||
#define BX_UNLOCK(mutex) LeaveCriticalSection(&(mutex))
|
||||
#define BX_MUTEX(mutex) CRITICAL_SECTION (mutex)
|
||||
#define BX_INIT_MUTEX(mutex) InitializeCriticalSection(&(mutex))
|
||||
#define BX_FINI_MUTEX(mutex) DeleteCriticalSection(&(mutex))
|
||||
#else
|
||||
#define BX_LOCK(mutex) pthread_mutex_lock(&(mutex));
|
||||
#define BX_UNLOCK(mutex) pthread_mutex_unlock(&(mutex));
|
||||
#define BX_MUTEX(mutex) pthread_mutex_t (mutex)
|
||||
#define BX_INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL)
|
||||
#define BX_FINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex))
|
||||
#endif
|
||||
|
||||
#endif /* BX_BOCHS_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Donald Becker
|
||||
// http://www.psyon.org
|
||||
//
|
||||
// Copyright (C) 2001-2014 The Bochs Project
|
||||
// Copyright (C) 2001-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -89,17 +89,6 @@ IMPLEMENT_GUI_PLUGIN_CODE(vncsrv)
|
||||
#include <winsock2.h>
|
||||
#include <process.h>
|
||||
|
||||
#undef LOCK
|
||||
#undef UNLOCK
|
||||
#undef MUTEX
|
||||
#undef INIT_MUTEX
|
||||
#undef TINI_MUTEX
|
||||
#define LOCK(mutex) EnterCriticalSection(&(mutex))
|
||||
#define UNLOCK(mutex) LeaveCriticalSection(&(mutex))
|
||||
#define MUTEX(mutex) CRITICAL_SECTION (mutex)
|
||||
#define INIT_MUTEX(mutex) InitializeCriticalSection(&(mutex))
|
||||
#define TINI_MUTEX(mutex) DeleteCriticalSection(&(mutex))
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/socket.h>
|
||||
@ -153,7 +142,7 @@ static struct _rfbKeyboardEvent {
|
||||
int z;
|
||||
} rfbKeyboardEvent[MAX_KEY_EVENTS];
|
||||
static unsigned long rfbKeyboardEvents = 0;
|
||||
static MUTEX(bKeyboardInUse);
|
||||
static BX_MUTEX(bKeyboardInUse);
|
||||
|
||||
// Misc Stuff
|
||||
|
||||
@ -325,7 +314,7 @@ void bx_vncsrv_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
|
||||
rfbInitServer(screen);
|
||||
|
||||
client_connected = 0;
|
||||
INIT_MUTEX(bKeyboardInUse);
|
||||
BX_INIT_MUTEX(bKeyboardInUse);
|
||||
vncStartThread();
|
||||
|
||||
#ifdef WIN32
|
||||
@ -376,7 +365,7 @@ void bx_vncsrv_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y)
|
||||
|
||||
void bx_vncsrv_gui_c::handle_events(void)
|
||||
{
|
||||
LOCK(bKeyboardInUse);
|
||||
BX_LOCK(bKeyboardInUse);
|
||||
|
||||
if (rfbKeyboardEvents > 0) {
|
||||
for (unsigned i = 0; i < rfbKeyboardEvents; i++) {
|
||||
@ -388,7 +377,7 @@ void bx_vncsrv_gui_c::handle_events(void)
|
||||
}
|
||||
rfbKeyboardEvents = 0;
|
||||
}
|
||||
UNLOCK(bKeyboardInUse);
|
||||
BX_UNLOCK(bKeyboardInUse);
|
||||
|
||||
#if BX_SHOW_IPS
|
||||
if (rfbIPSupdate) {
|
||||
@ -810,7 +799,7 @@ void bx_vncsrv_gui_c::exit(void)
|
||||
while (!rfbServerDown) {
|
||||
usleep(10000); //10ms
|
||||
}
|
||||
TINI_MUTEX(bKeyboardInUse);
|
||||
BX_FINI_MUTEX(bKeyboardInUse);
|
||||
|
||||
for (i = 0; i < rfbBitmapCount; i++) {
|
||||
free(rfbBitmaps[i].bmap);
|
||||
@ -1424,14 +1413,14 @@ void dokey(rfbBool down, rfbKeySym key, rfbClientPtr cl)
|
||||
if (mouse_toggle) {
|
||||
bx_gui->toggle_mouse_enable();
|
||||
} else {
|
||||
LOCK(bKeyboardInUse);
|
||||
BX_LOCK(bKeyboardInUse);
|
||||
if (rfbKeyboardEvents >= MAX_KEY_EVENTS)
|
||||
return;
|
||||
rfbKeyboardEvent[rfbKeyboardEvents].type = KEYBOARD;
|
||||
rfbKeyboardEvent[rfbKeyboardEvents].key = key;
|
||||
rfbKeyboardEvent[rfbKeyboardEvents].down = down;
|
||||
rfbKeyboardEvents++;
|
||||
UNLOCK(bKeyboardInUse);
|
||||
BX_UNLOCK(bKeyboardInUse);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,7 +1431,7 @@ void doptr(int buttonMask, int x, int y, rfbClientPtr cl)
|
||||
if (bx_gui->mouse_toggle_check(BX_MT_MBUTTON, (buttonMask & 0x02) > 0)) {
|
||||
bx_gui->toggle_mouse_enable();
|
||||
} else {
|
||||
LOCK(bKeyboardInUse);
|
||||
BX_LOCK(bKeyboardInUse);
|
||||
if (rfbKeyboardEvents >= MAX_KEY_EVENTS)
|
||||
return;
|
||||
rfbKeyboardEvent[rfbKeyboardEvents].type = MOUSE;
|
||||
@ -1461,7 +1450,7 @@ void doptr(int buttonMask, int x, int y, rfbClientPtr cl)
|
||||
wheel_status = buttonMask & 0x18;
|
||||
}
|
||||
rfbKeyboardEvents++;
|
||||
UNLOCK(bKeyboardInUse);
|
||||
BX_UNLOCK(bKeyboardInUse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2014 The Bochs Project
|
||||
// Copyright (C) 2011-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -38,6 +38,7 @@
|
||||
#define BX_SOUNDLOW_ALSA 5
|
||||
|
||||
typedef Bit32u (*sound_record_handler_t)(void *arg, Bit32u len);
|
||||
typedef Bit32u (*waveout_callback_t)(void *arg, Bit16u rate, Bit8u *buffer, Bit32u len);
|
||||
|
||||
// The class with the input/output functions
|
||||
class bx_sound_lowlevel_c : public logfunctions {
|
||||
@ -76,6 +77,8 @@ public:
|
||||
|
||||
static void record_timer_handler(void *);
|
||||
void record_timer(void);
|
||||
|
||||
virtual bx_bool set_waveout_callback(void *, waveout_callback_t wocb) {return 0;}
|
||||
protected:
|
||||
int record_timer_index;
|
||||
int record_packet_size;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2014 The Bochs Project
|
||||
// Copyright (C) 2011-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -48,6 +48,12 @@
|
||||
|
||||
bx_soundmod_ctl_c* theSoundModCtl = NULL;
|
||||
|
||||
Bit8u *beep_buffer;
|
||||
unsigned int beep_bufsize;
|
||||
BX_MUTEX(beep_mutex);
|
||||
|
||||
Bit32u beep_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len);
|
||||
|
||||
int CDECL libsoundmod_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
|
||||
{
|
||||
if (type == PLUGTYPE_CORE) {
|
||||
@ -72,6 +78,7 @@ bx_soundmod_ctl_c::bx_soundmod_ctl_c()
|
||||
|
||||
bx_soundmod_ctl_c::~bx_soundmod_ctl_c()
|
||||
{
|
||||
free(beep_buffer);
|
||||
if (soundmod != NULL) {
|
||||
soundmod->closewaveoutput();
|
||||
}
|
||||
@ -121,6 +128,17 @@ void bx_soundmod_ctl_c::init()
|
||||
int ret = soundmod->openwaveoutput(waveout);
|
||||
if (ret != BX_SOUNDLOW_OK) {
|
||||
BX_PANIC(("Could not open wave output device"));
|
||||
} else {
|
||||
beep_active = 0;
|
||||
use_new_sound_api = soundmod->set_waveout_callback(theSoundModCtl, beep_callback);
|
||||
beep_cur_freq = 0.0;
|
||||
beep_level = 0x40;
|
||||
beep_bufsize = 4410;
|
||||
beep_buffer = (Bit8u*)malloc(beep_bufsize);
|
||||
BX_INIT_MUTEX(beep_mutex);
|
||||
if (use_new_sound_api) {
|
||||
soundmod->startwaveplayback(44100, 16, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,11 +147,38 @@ void* bx_soundmod_ctl_c::get_module()
|
||||
return soundmod;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
pthread_t thread;
|
||||
Bit32u bx_soundmod_ctl_c::beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
Bit32u j = 0;
|
||||
|
||||
if (!beep_active) {
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
buffer[j++] = 0;
|
||||
buffer[j++] = beep_level;
|
||||
buffer[j++] = 0;
|
||||
buffer[j++] = beep_level;
|
||||
BX_LOCK(beep_mutex);
|
||||
if ((++beep_pos % beep_samples) == 0) {
|
||||
beep_level ^= 0x80;
|
||||
beep_pos = 0;
|
||||
}
|
||||
BX_UNLOCK(beep_mutex);
|
||||
} while (j < len);
|
||||
return len;
|
||||
}
|
||||
|
||||
Bit32u beep_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
return ((bx_soundmod_ctl_c*)dev)->beep_generator(rate, buffer, len);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD threadID;
|
||||
#else
|
||||
pthread_t threadID;
|
||||
#endif
|
||||
Bit8u *beep_buffer;
|
||||
unsigned int beep_bytes, beep_bufsize;
|
||||
Bit8u beep_control = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
@ -142,33 +187,24 @@ DWORD WINAPI beep_thread(LPVOID indata)
|
||||
void beep_thread(void *indata)
|
||||
#endif
|
||||
{
|
||||
Bit8u level;
|
||||
unsigned int i, j;
|
||||
int ret;
|
||||
|
||||
bx_sound_lowlevel_c *soundmod = (bx_sound_lowlevel_c*)indata;
|
||||
level = 0x40;
|
||||
i = 0;
|
||||
while (beep_control == 2) {
|
||||
j = 0;
|
||||
do {
|
||||
beep_buffer[j++] = level;
|
||||
if ((++i % beep_bytes) == 0) level ^= 0x40;
|
||||
} while (j < beep_bufsize);
|
||||
theSoundModCtl->beep_generator(44100, beep_buffer, beep_bufsize);
|
||||
ret = soundmod->sendwavepacket(beep_bufsize, beep_buffer);
|
||||
if (ret == BX_SOUNDLOW_ERR) break;
|
||||
if (soundmod->get_type() == BX_SOUNDLOW_WIN) {
|
||||
#ifdef WIN32
|
||||
Sleep(100);
|
||||
Sleep(25);
|
||||
#endif
|
||||
} else if (soundmod->get_type() == BX_SOUNDLOW_SDL) {
|
||||
#if BX_WITH_SDL || BX_WITH_SDL2
|
||||
SDL_Delay(100);
|
||||
SDL_Delay(25);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
soundmod->stopwaveplayback();
|
||||
free(beep_buffer);
|
||||
beep_control = 0;
|
||||
#ifdef WIN32
|
||||
return 0;
|
||||
@ -181,23 +217,29 @@ bx_bool bx_soundmod_ctl_c::beep_on(float frequency)
|
||||
{
|
||||
if (soundmod != NULL) {
|
||||
BX_DEBUG(("Beep ON (frequency=%.2f)",frequency));
|
||||
if (beep_control > 0) {
|
||||
beep_off();
|
||||
if (frequency != beep_cur_freq) {
|
||||
BX_LOCK(beep_mutex);
|
||||
beep_cur_freq = frequency;
|
||||
beep_samples = (Bit32u)(44100.0 / beep_cur_freq / 2);
|
||||
beep_active = 1;
|
||||
BX_UNLOCK(beep_mutex);
|
||||
}
|
||||
if (soundmod->startwaveplayback(44100, 8, 0, 0) == BX_SOUNDLOW_ERR) {
|
||||
return 0;
|
||||
}
|
||||
beep_bytes = (int)(44100.0 / frequency / 2);
|
||||
beep_bufsize = 4410;
|
||||
beep_buffer = (Bit8u*)malloc(beep_bufsize);
|
||||
beep_control = 2;
|
||||
if (use_new_sound_api) {
|
||||
return 1;
|
||||
} else {
|
||||
if (beep_control != 2) {
|
||||
if (soundmod->startwaveplayback(44100, 16, 1, 1) == BX_SOUNDLOW_ERR) {
|
||||
return 0;
|
||||
}
|
||||
beep_control = 2;
|
||||
#ifdef WIN32
|
||||
DWORD threadID;
|
||||
CreateThread(NULL, 0, beep_thread, soundmod, 0, &threadID);
|
||||
CreateThread(NULL, 0, beep_thread, soundmod, 0, &threadID);
|
||||
#else
|
||||
pthread_create(&thread, NULL, (void *(*)(void *))&beep_thread, soundmod);
|
||||
pthread_create(&threadID, NULL, (void *(*)(void *))&beep_thread, soundmod);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -206,15 +248,20 @@ bx_bool bx_soundmod_ctl_c::beep_off()
|
||||
{
|
||||
if (soundmod != NULL) {
|
||||
BX_DEBUG(("Beep OFF"));
|
||||
if (beep_control > 0) {
|
||||
beep_control = 1;
|
||||
beep_active = 0;
|
||||
if (use_new_sound_api) {
|
||||
return 1;
|
||||
} else {
|
||||
if (beep_control > 0) {
|
||||
beep_control = 1;
|
||||
#ifdef WIN32
|
||||
while (beep_control > 0) Sleep(1);
|
||||
while (beep_control > 0) Sleep(1);
|
||||
#else
|
||||
pthread_join(thread, NULL);
|
||||
pthread_join(threadID, NULL);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2011-2014 The Bochs Project
|
||||
// Copyright (C) 2011-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -36,6 +36,12 @@ public:
|
||||
Bit8u header[], Bit32u datalen, Bit8u data[]);
|
||||
virtual void pcm_apply_volume(Bit32u datalen, Bit8u data[], Bit16u volume,
|
||||
Bit8u bits, bx_bool stereo, bx_bool issigned);
|
||||
Bit32u beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len);
|
||||
private:
|
||||
bx_sound_lowlevel_c *soundmod;
|
||||
bx_bool use_new_sound_api;
|
||||
bx_bool beep_active;
|
||||
Bit8u beep_level;
|
||||
Bit16u beep_samples, beep_pos;
|
||||
float beep_cur_freq;
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2012-2014 The Bochs Project
|
||||
// Copyright (C) 2012-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -43,6 +43,7 @@ bx_sound_sdl_c::bx_sound_sdl_c()
|
||||
:bx_sound_lowlevel_c()
|
||||
{
|
||||
WaveOpen = 0;
|
||||
wo_cb = NULL;
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
|
||||
BX_PANIC(("Initialization of sound lowlevel module 'sdl' failed"));
|
||||
} else {
|
||||
@ -58,12 +59,31 @@ bx_sound_sdl_c::~bx_sound_sdl_c()
|
||||
|
||||
int bx_sound_sdl_c::openwaveoutput(const char *wavedev)
|
||||
{
|
||||
WaveOpen = 1;
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
void sdl_callback(void *unused, Bit8u *stream, int len)
|
||||
Bit32u bx_sound_sdl_c::get_wave_data(Bit8u *stream, int len)
|
||||
{
|
||||
if (wo_cb == NULL) {
|
||||
return 0;
|
||||
}
|
||||
Bit8u *tmpbuffer = (Bit8u*)malloc(len);
|
||||
memset(tmpbuffer, 0, len);
|
||||
Bit32u len2 = wo_cb(dev, 44100, tmpbuffer, len);
|
||||
if (len2 > 0) {
|
||||
SDL_MixAudio(stream, tmpbuffer, len2, SDL_MIX_MAXVOLUME);
|
||||
}
|
||||
free(tmpbuffer);
|
||||
return len2;
|
||||
}
|
||||
|
||||
void sdl_callback(void *thisptr, Bit8u *stream, int len)
|
||||
{
|
||||
memset(stream, 0, len);
|
||||
// FIXME: mix wave data
|
||||
if (((bx_sound_sdl_c*)thisptr)->get_wave_data(stream, len) > 0) {
|
||||
return;
|
||||
}
|
||||
int amount = audio_buffer.iptr - audio_buffer.optr;
|
||||
if (amount < 0) {
|
||||
amount += BX_SOUND_SDL_BUFSIZE;
|
||||
@ -107,13 +127,20 @@ int bx_sound_sdl_c::startwaveplayback(int frequency, int bits, bx_bool stereo, i
|
||||
fmt.channels = stereo + 1;
|
||||
fmt.samples = frequency / 10;
|
||||
fmt.callback = sdl_callback;
|
||||
fmt.userdata = NULL;
|
||||
fmt.userdata = this;
|
||||
if (WaveOpen) {
|
||||
SDL_CloseAudio();
|
||||
}
|
||||
if (SDL_OpenAudio(&fmt, NULL) < 0) {
|
||||
BX_PANIC(("SDL_OpenAudio() failed"));
|
||||
WaveOpen = 0;
|
||||
return BX_SOUNDLOW_ERR;
|
||||
} else {
|
||||
WaveOpen = 1;
|
||||
}
|
||||
audio_buffer.iptr = 0;
|
||||
audio_buffer.optr = 0;
|
||||
SDL_PauseAudio(0);
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
@ -166,13 +193,20 @@ int bx_sound_sdl_c::stopwaveplayback()
|
||||
SDL_Delay(1);
|
||||
}
|
||||
SDL_CloseAudio();
|
||||
WaveOpen = 0;
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_sdl_c::closewaveoutput()
|
||||
{
|
||||
WaveOpen = 0;
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
bx_bool bx_sound_sdl_c::set_waveout_callback(void *arg, waveout_callback_t wocb)
|
||||
{
|
||||
dev = arg;
|
||||
wo_cb = wocb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // BX_WITH_SDL || BX_WITH_SDL2
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2012 The Bochs Project
|
||||
// Copyright (C) 2012-2015 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -39,8 +39,13 @@ public:
|
||||
virtual int sendwavepacket(int length, Bit8u data[]);
|
||||
virtual int stopwaveplayback();
|
||||
virtual int closewaveoutput();
|
||||
|
||||
virtual bx_bool set_waveout_callback(void *, waveout_callback_t wocb);
|
||||
Bit32u get_wave_data(Bit8u *stream, int len);
|
||||
private:
|
||||
bx_bool WaveOpen;
|
||||
void *dev;
|
||||
waveout_callback_t wo_cb;
|
||||
};
|
||||
|
||||
#endif // BX_WITH_SDL || BX_WITH_SDL2
|
||||
|
Loading…
x
Reference in New Issue
Block a user