mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2025-01-18 23:41:36 +00:00
Applied patch from KO Myung-Hun for OS/2 support including Dart audio driver.
This commit is contained in:
parent
7f3e9a171f
commit
b49458e817
9 changed files with 605 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
|||
[:Team:]
|
||||
Current development team
|
||||
|
||||
Josh Green
|
||||
Bernat Arlandis i Mañó
|
||||
Pedro Lopez-Cabanillas
|
||||
|
||||
|
||||
[:Idea:]
|
||||
|
||||
|
@ -97,6 +104,8 @@ summary of contributions.
|
|||
signed integer type). Mozilla NSPR library, www.mozilla.org. file:
|
||||
iiwu_phase.h
|
||||
|
||||
* KO Myung-Hun for OS/2 support with Dart audio driver.
|
||||
|
||||
* Growing list of individuals who contributed bug fixes, corrections and minor features:
|
||||
Pedro Lopez-Cabanillas for midi.winmidi.device setting.
|
||||
Nicolas Boulicault for ALSA sequencer midi.portname setting.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2009-02-03 Josh Green <jgreen@users.sourceforge.net>
|
||||
* Applied patch from KO Myung-Hun for OS/2 support including Dart audio
|
||||
driver.
|
||||
|
||||
2009-01-29 Josh Green <jgreen@users.sourceforge.net>
|
||||
* src/Makefile.am: Added PortAudio driver conditional build.
|
||||
* src/fluid_adriver.c: Registered fluid_portaudio_driver_settings.
|
||||
|
|
|
@ -76,6 +76,10 @@ mingw*)
|
|||
LIBFLUID_LDFLAGS="-no-undefined"
|
||||
FLUID_CPPFLAGS="-DFLUIDSYNTH_NOT_A_DLL"
|
||||
;;
|
||||
os2*)
|
||||
LDFLAGS="$LDFLAGS -Zbin-files"
|
||||
LIBFLUID_LDFLAGS="-no-undefined"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(LIBFLUID_LIBS)
|
||||
|
@ -285,6 +289,24 @@ fi
|
|||
AM_CONDITIONAL(COREMIDI_SUPPORT, test "$COREMIDI_SUPPORT" = "1")
|
||||
AC_SUBST(COREMIDI_LIBS)
|
||||
|
||||
dnl
|
||||
dnl - Check support for DART
|
||||
dnl
|
||||
AC_CHECK_HEADER(os2me.h, DART_FOUND="yes", DART_FOUND="no")
|
||||
AC_ARG_ENABLE(dart, AS_HELP_STRING([--disable-dart],
|
||||
[disable DART support (default=auto)]),
|
||||
enable_dart=$enableval, enable_dart="yes")
|
||||
|
||||
DART_SUPPORT=0
|
||||
if test "$enable_dart" = "yes" -a "$DART_FOUND" = "yes"; then
|
||||
AC_DEFINE(DART_SUPPORT, 1, [whether or not we are supporting DART])
|
||||
DART_SUPPORT=1
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(DART_SUPPORT, test "$DART_SUPPORT" = "1")
|
||||
AC_SUBST(DART_CFLAGS)
|
||||
AC_SUBST(DART_LIBS)
|
||||
|
||||
dnl
|
||||
dnl Check for readline support (Josh Green 2003-06-10)
|
||||
dnl
|
||||
|
@ -456,6 +478,12 @@ else
|
|||
echo "LADCCA support: no"
|
||||
fi
|
||||
|
||||
if test "${DART_SUPPORT}" = "1"; then
|
||||
echo "OS/2 DART support: yes"
|
||||
else
|
||||
echo "OS/2 DART support: no"
|
||||
fi
|
||||
|
||||
dnl if test "${AUFILE_SUPPORT}" = "1"; then
|
||||
dnl echo "Sound file: yes"
|
||||
dnl else
|
||||
|
|
|
@ -42,13 +42,16 @@ fluid_lash = fluid_lash.c
|
|||
endif
|
||||
endif
|
||||
|
||||
if DART_SUPPORT
|
||||
fluid_dart = fluid_dart.c
|
||||
endif
|
||||
|
||||
# Extra files and optional drivers
|
||||
EXTRA_DIST = fluid_dll.c fluid_dsound.c fluid_winmidi.c fluid_portaudio.c \
|
||||
fluid_coreaudio.c fluid_alsa.c fluid_oss.c \
|
||||
fluid_coreaudio.c fluid_alsa.c fluid_oss.c fluid_pulse.c \
|
||||
fluid_dsp_simple.c \
|
||||
fluid_sndmgr.c config_macos.h config_macosx.h config_macosx_pb.h \
|
||||
config_win32.h fluid_jack.c
|
||||
config_win32.h fluid_jack.c fluid_dart.c
|
||||
|
||||
lib_LTLIBRARIES = libfluidsynth.la
|
||||
bin_PROGRAMS = fluidsynth
|
||||
|
@ -63,6 +66,7 @@ libfluidsynth_la_SOURCES = \
|
|||
$(fluid_portaudio) \
|
||||
$(fluid_pulse) \
|
||||
$(fluid_windows) \
|
||||
$(fluid_dart) \
|
||||
fluid_adriver.c \
|
||||
fluid_adriver.h \
|
||||
fluid_chan.c \
|
||||
|
@ -120,16 +124,20 @@ libfluidsynth_la_SOURCES = \
|
|||
fluid_aufile.c
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include $(LASH_CFLAGS) $(LADCCA_CFLAGS) \
|
||||
$(READLINE_CFLAGS) $(JACK_CFLAGS) $(ALSA_CFLAGS) $(PULSE_CFLAGS) $(PORTAUDIO_CFLAGS)
|
||||
$(READLINE_CFLAGS) $(JACK_CFLAGS) $(ALSA_CFLAGS) $(PULSE_CFLAGS) \
|
||||
$(PORTAUDIO_CFLAGS) $(DART_CFLAGS)
|
||||
|
||||
libfluidsynth_la_LIBADD = $(LIBFLUID_LIBS) $(LASH_LIBS) $(LADCCA_LIBS) \
|
||||
$(READLINE_LIBS) $(COREAUDIO_LIBS) $(COREMIDI_LIBS) $(JACK_LIBS) \
|
||||
$(ALSA_LIBS) $(PULSE_LIBS) $(PORTAUDIO_LIBS)
|
||||
$(ALSA_LIBS) $(PULSE_LIBS) $(PORTAUDIO_LIBS) $(DART_LIBS)
|
||||
|
||||
libfluidsynth_la_LDFLAGS = \
|
||||
-version-info @LT_VERSION_INFO@ \
|
||||
-export-dynamic $(LIBFLUID_LDFLAGS)
|
||||
|
||||
libfluidsynth_la_CPPFLAGS = $(LIBFLUID_CPPFLAGS)
|
||||
|
||||
fluidsynth_SOURCES = fluidsynth.c
|
||||
fluidsynth_LDADD = libfluidsynth.la
|
||||
fluidsynth_CPPFLAGS = $(FLUIDSYNTH_CPPFLAGS)
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
/* whether or not we are supporting CoreMIDI */
|
||||
#undef COREMIDI_SUPPORT
|
||||
|
||||
/* whether or not we are supporting DART */
|
||||
#undef DART_SUPPORT
|
||||
|
||||
/* Define if building for Mac OS X Darwin */
|
||||
#undef DARWIN
|
||||
|
||||
|
|
|
@ -105,6 +105,13 @@ fluid_audio_driver_t* new_fluid_sndmgr_audio_driver2(fluid_settings_t* settings,
|
|||
int delete_fluid_sndmgr_audio_driver(fluid_audio_driver_t* p);
|
||||
#endif
|
||||
|
||||
#if DART_SUPPORT
|
||||
fluid_audio_driver_t* new_fluid_dart_audio_driver(fluid_settings_t* settings,
|
||||
fluid_synth_t* synth);
|
||||
int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p);
|
||||
void fluid_dart_audio_driver_settings(fluid_settings_t* settings);
|
||||
#endif
|
||||
|
||||
#define AUFILE_SUPPORT 1
|
||||
#if AUFILE_SUPPORT
|
||||
fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings,
|
||||
|
@ -171,6 +178,13 @@ fluid_audriver_definition_t fluid_audio_drivers[] = {
|
|||
delete_fluid_sndmgr_audio_driver,
|
||||
NULL },
|
||||
#endif
|
||||
#if DART_SUPPORT
|
||||
{ "dart",
|
||||
new_fluid_dart_audio_driver,
|
||||
NULL,
|
||||
delete_fluid_dart_audio_driver,
|
||||
fluid_dart_audio_driver_settings },
|
||||
#endif
|
||||
#if AUFILE_SUPPORT
|
||||
{ "file",
|
||||
new_fluid_file_audio_driver,
|
||||
|
@ -224,6 +238,8 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||
fluid_settings_register_str(settings, "audio.driver", "portaudio", 0, NULL, NULL);
|
||||
#elif JACK_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "jack", 0, NULL, NULL);
|
||||
#elif DART_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "dart", 0, NULL, NULL);
|
||||
#elif AUFILE_SUPPORT
|
||||
fluid_settings_register_str(settings, "audio.driver", "file", 0, NULL, NULL);
|
||||
#else
|
||||
|
@ -255,6 +271,9 @@ void fluid_audio_driver_settings(fluid_settings_t* settings)
|
|||
#if JACK_SUPPORT
|
||||
fluid_settings_add_option(settings, "audio.driver", "jack");
|
||||
#endif
|
||||
#if DART_SUPPORT
|
||||
fluid_settings_add_option(settings, "audio.driver", "dart");
|
||||
#endif
|
||||
#if AUFILE_SUPPORT
|
||||
fluid_settings_add_option(settings, "audio.driver", "file");
|
||||
#endif
|
||||
|
|
264
fluidsynth/src/fluid_dart.c
Normal file
264
fluidsynth/src/fluid_dart.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/* FluidSynth - A Software Synthesizer
|
||||
*
|
||||
* Copyright (C) 2003 Peter Hanappe and others.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* fluid_dart.c
|
||||
*
|
||||
* Driver for OS/2 DART
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fluid_adriver.h"
|
||||
#include "fluid_settings.h"
|
||||
#include "fluid_sys.h"
|
||||
|
||||
#if DART_SUPPORT
|
||||
|
||||
/* To avoid name conflict */
|
||||
#undef VERSION
|
||||
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
|
||||
#define INCL_OS2MM
|
||||
#include <os2me.h>
|
||||
|
||||
#define NUM_MIX_BUFS 2
|
||||
|
||||
/** fluid_dart_audio_driver_t
|
||||
*
|
||||
* This structure should not be accessed directly. Use audio port
|
||||
* functions instead.
|
||||
*/
|
||||
typedef struct {
|
||||
fluid_audio_driver_t driver;
|
||||
fluid_synth_t* synth;
|
||||
int frame_size;
|
||||
USHORT usDeviceID; /* Amp Mixer device id */
|
||||
MCI_MIX_BUFFER MixBuffers[NUM_MIX_BUFS]; /* Device buffers */
|
||||
MCI_MIXSETUP_PARMS MixSetupParms; /* Mixer parameters */
|
||||
MCI_BUFFER_PARMS BufferParms; /* Device buffer parms */
|
||||
} fluid_dart_audio_driver_t;
|
||||
|
||||
static fluid_dart_audio_driver_t* m_dev;
|
||||
static HMODULE m_hmodMDM = NULLHANDLE;
|
||||
static ULONG (APIENTRY *m_pfnmciSendCommand)(USHORT, USHORT, ULONG, PVOID, USHORT) = NULL;
|
||||
|
||||
fluid_audio_driver_t* new_fluid_dart_audio_driver(fluid_settings_t* settings,
|
||||
fluid_synth_t* synth);
|
||||
|
||||
int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p);
|
||||
void fluid_dart_audio_driver_settings(fluid_settings_t* settings);
|
||||
|
||||
static LONG APIENTRY fluid_dart_audio_run( ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags );
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* DART audio driver
|
||||
*
|
||||
*/
|
||||
|
||||
void fluid_dart_audio_driver_settings(fluid_settings_t* settings)
|
||||
{
|
||||
fluid_settings_register_str(settings, "audio.dart.device", "default", 0, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
fluid_audio_driver_t*
|
||||
new_fluid_dart_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth)
|
||||
{
|
||||
fluid_dart_audio_driver_t* dev;
|
||||
double sample_rate;
|
||||
int periods, period_size;
|
||||
UCHAR szFailedName[ 256 ];
|
||||
MCI_AMP_OPEN_PARMS AmpOpenParms;
|
||||
int i;
|
||||
ULONG rc;
|
||||
|
||||
dev = FLUID_NEW(fluid_dart_audio_driver_t);
|
||||
if (dev == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
FLUID_MEMSET(dev, 0, sizeof(fluid_dart_audio_driver_t));
|
||||
|
||||
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
|
||||
fluid_settings_getint(settings, "audio.periods", &periods);
|
||||
fluid_settings_getint(settings, "audio.period-size", &period_size);
|
||||
|
||||
/* check the format */
|
||||
if (!fluid_settings_str_equal(settings, "audio.sample-format", "16bits")) {
|
||||
FLUID_LOG(FLUID_ERR, "Unhandled sample format");
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
dev->synth = synth;
|
||||
dev->frame_size = 2 * sizeof(short);
|
||||
|
||||
/* Load only once
|
||||
*/
|
||||
if( m_hmodMDM == NULLHANDLE )
|
||||
{
|
||||
rc = DosLoadModule(szFailedName, sizeof(szFailedName), "MDM.DLL", &m_hmodMDM);
|
||||
|
||||
if (rc != 0 ) {
|
||||
FLUID_LOG(FLUID_ERR, "Cannot load MDM.DLL for DART due to %s", szFailedName);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
rc = DosQueryProcAddr(m_hmodMDM, 1, NULL, (PFN *)&m_pfnmciSendCommand);
|
||||
|
||||
if (rc != 0 ) {
|
||||
FLUID_LOG(FLUID_ERR, "Cannot find mciSendCommand() in MDM.DLL");
|
||||
DosFreeModule(m_hmodMDM);
|
||||
m_hmodMDM = NULLHANDLE;
|
||||
goto error_recovery;
|
||||
}
|
||||
}
|
||||
|
||||
/* open the mixer device
|
||||
*/
|
||||
FLUID_MEMSET(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
|
||||
AmpOpenParms.usDeviceID = (USHORT)0;
|
||||
AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||
|
||||
rc = m_pfnmciSendCommand(0, MCI_OPEN,
|
||||
MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,
|
||||
(PVOID)&AmpOpenParms, 0);
|
||||
|
||||
if (rc != MCIERR_SUCCESS) {
|
||||
FLUID_LOG(FLUID_ERR, "Cannot open DART, rc = %lu", rc);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
dev->usDeviceID = AmpOpenParms.usDeviceID;
|
||||
|
||||
/* Set the m_MixSetupParms data structure to match the requirements.
|
||||
* This is a global that is used to setup the mixer.
|
||||
*/
|
||||
dev->MixSetupParms.ulBitsPerSample = BPS_16;
|
||||
dev->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM;
|
||||
dev->MixSetupParms.ulSamplesPerSec = sample_rate;
|
||||
dev->MixSetupParms.ulChannels = 2;
|
||||
|
||||
/* Setup the mixer for playback of wave data
|
||||
*/
|
||||
dev->MixSetupParms.ulFormatMode = MCI_PLAY;
|
||||
dev->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
|
||||
dev->MixSetupParms.pmixEvent = fluid_dart_audio_run;
|
||||
|
||||
rc = m_pfnmciSendCommand(dev->usDeviceID, MCI_MIXSETUP,
|
||||
MCI_WAIT | MCI_MIXSETUP_INIT,
|
||||
(PVOID)&dev->MixSetupParms, 0);
|
||||
|
||||
if (rc != MCIERR_SUCCESS) {
|
||||
FLUID_LOG(FLUID_ERR, "Cannot setup DART, rc = %lu", rc);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Set up the m_BufferParms data structure and allocate
|
||||
* device buffers from the Amp-Mixer
|
||||
*/
|
||||
dev->BufferParms.ulNumBuffers = NUM_MIX_BUFS;
|
||||
dev->BufferParms.ulBufferSize = periods * period_size * dev->frame_size;
|
||||
dev->BufferParms.pBufList = dev->MixBuffers;
|
||||
|
||||
rc = m_pfnmciSendCommand(dev->usDeviceID, MCI_BUFFER,
|
||||
MCI_WAIT | MCI_ALLOCATE_MEMORY,
|
||||
(PVOID)&dev->BufferParms, 0);
|
||||
|
||||
if ((USHORT)rc != MCIERR_SUCCESS) {
|
||||
FLUID_LOG(FLUID_ERR, "Cannot allocate memory for DART, rc = %lu", rc);
|
||||
goto error_recovery;
|
||||
}
|
||||
|
||||
/* Initialize all device buffers.
|
||||
*/
|
||||
for (i = 0; i < NUM_MIX_BUFS; i++) {
|
||||
FLUID_MEMSET(dev->MixBuffers[i].pBuffer, 0, dev->BufferParms.ulBufferSize);
|
||||
dev->MixBuffers[i].ulBufferLength = dev->BufferParms.ulBufferSize;
|
||||
dev->MixBuffers[i].ulFlags = 0;
|
||||
fluid_synth_write_s16(dev->synth, dev->MixBuffers[i].ulBufferLength / dev->frame_size,
|
||||
dev->MixBuffers[i].pBuffer, 0, 2, dev->MixBuffers[i].pBuffer, 1, 2 );
|
||||
}
|
||||
|
||||
/* Write buffers to kick off the amp mixer.
|
||||
*/
|
||||
dev->MixSetupParms.pmixWrite(dev->MixSetupParms.ulMixHandle,
|
||||
dev->MixBuffers,
|
||||
NUM_MIX_BUFS);
|
||||
|
||||
m_dev = dev;
|
||||
|
||||
return (fluid_audio_driver_t*) dev;
|
||||
|
||||
error_recovery:
|
||||
|
||||
delete_fluid_dart_audio_driver((fluid_audio_driver_t*) dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int delete_fluid_dart_audio_driver(fluid_audio_driver_t* p)
|
||||
{
|
||||
fluid_dart_audio_driver_t* dev = (fluid_dart_audio_driver_t*) p;
|
||||
|
||||
if (dev == NULL) {
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
if (dev->usDeviceID != 0) {
|
||||
MCI_GENERIC_PARMS GenericParms;
|
||||
|
||||
/* Send message to stop the audio device
|
||||
*/
|
||||
m_pfnmciSendCommand(dev->usDeviceID, MCI_STOP, MCI_WAIT,
|
||||
(PVOID)&GenericParms, 0);
|
||||
|
||||
/* Deallocate device buffers
|
||||
*/
|
||||
m_pfnmciSendCommand(dev->usDeviceID, MCI_BUFFER,
|
||||
MCI_WAIT | MCI_DEALLOCATE_MEMORY,
|
||||
(PVOID)&dev->BufferParms, 0);
|
||||
|
||||
/* Close device the mixer device
|
||||
*/
|
||||
m_pfnmciSendCommand(dev->usDeviceID, MCI_CLOSE, MCI_WAIT,
|
||||
(PVOID)&GenericParms, 0);
|
||||
}
|
||||
|
||||
FLUID_FREE(dev);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
static LONG APIENTRY fluid_dart_audio_run( ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags )
|
||||
{
|
||||
switch( ulFlags ) {
|
||||
case MIX_STREAM_ERROR | MIX_WRITE_COMPLETE: /* error occur in device */
|
||||
case MIX_WRITE_COMPLETE: /* for playback */
|
||||
FLUID_MEMSET(pBuffer->pBuffer, 0, pBuffer->ulBufferLength);
|
||||
fluid_synth_write_s16(m_dev->synth, pBuffer->ulBufferLength / m_dev->frame_size,
|
||||
pBuffer->pBuffer, 0, 2, pBuffer->pBuffer, 1, 2 );
|
||||
m_dev->MixSetupParms.pmixWrite(m_dev->MixSetupParms.ulMixHandle, pBuffer, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* #if DART_SUPPORT */
|
|
@ -636,6 +636,186 @@ unsigned int fluid_curtime()
|
|||
|
||||
|
||||
|
||||
#elif defined(__OS2__)
|
||||
/*=============================================================*/
|
||||
/* */
|
||||
/* OS2 */
|
||||
/* */
|
||||
/*=============================================================*/
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Timer
|
||||
*
|
||||
*/
|
||||
|
||||
struct _fluid_timer_t
|
||||
{
|
||||
long msec;
|
||||
fluid_timer_callback_t callback;
|
||||
void* data;
|
||||
int thread_id;
|
||||
int cont;
|
||||
int auto_destroy;
|
||||
};
|
||||
|
||||
static int fluid_timer_count = 0;
|
||||
void fluid_timer_run(void *data);
|
||||
|
||||
fluid_timer_t*
|
||||
new_fluid_timer(int msec, fluid_timer_callback_t callback, void* data,
|
||||
int new_thread, int auto_destroy)
|
||||
{
|
||||
fluid_timer_t* timer = FLUID_NEW(fluid_timer_t);
|
||||
if (timer == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timer->cont = 1;
|
||||
timer->msec = msec;
|
||||
timer->callback = callback;
|
||||
timer->data = data;
|
||||
timer->thread_id =-1;
|
||||
timer->auto_destroy = auto_destroy;
|
||||
|
||||
if (new_thread) {
|
||||
timer->thread_id = _beginthread( fluid_timer_run, NULL, 256 * 1024, ( void * )timer );
|
||||
if (timer->thread_id == -1) {
|
||||
FLUID_LOG(FLUID_ERR, "Couldn't create timer thread");
|
||||
FLUID_FREE(timer);
|
||||
return NULL;
|
||||
}
|
||||
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, timer->thread_id);
|
||||
} else {
|
||||
fluid_timer_run(( void * )timer);
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
void
|
||||
fluid_timer_run(void *data)
|
||||
{
|
||||
int count = 0;
|
||||
int cont = 1;
|
||||
long start;
|
||||
long delay;
|
||||
fluid_timer_t* timer;
|
||||
timer = (fluid_timer_t*) data;
|
||||
|
||||
if ((timer == NULL) || (timer->callback == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0 );
|
||||
|
||||
/* keep track of the start time for absolute positioning */
|
||||
start = fluid_curtime();
|
||||
|
||||
while (cont) {
|
||||
|
||||
/* do whatever we have to do */
|
||||
cont = (*timer->callback)(timer->data, fluid_curtime() - start);
|
||||
|
||||
count++;
|
||||
|
||||
/* to avoid incremental time errors, I calculate the delay between
|
||||
two callbacks bringing in the "absolute" time (count *
|
||||
timer->msec) */
|
||||
delay = (count * timer->msec) - (fluid_curtime() - start);
|
||||
if (delay > 0) {
|
||||
DosSleep(delay);
|
||||
}
|
||||
|
||||
cont &= timer->cont;
|
||||
}
|
||||
|
||||
FLUID_LOG(FLUID_DBG, "Timer thread finished");
|
||||
|
||||
if (timer->auto_destroy) {
|
||||
FLUID_FREE(timer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
delete_fluid_timer(fluid_timer_t* timer)
|
||||
{
|
||||
timer->cont = 0;
|
||||
fluid_timer_join(timer);
|
||||
FLUID_FREE(timer);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int
|
||||
fluid_timer_join(fluid_timer_t* timer)
|
||||
{
|
||||
ULONG wait_result;
|
||||
if (timer->thread_id == -1) {
|
||||
return FLUID_OK;
|
||||
}
|
||||
wait_result = DosWaitThread(&timer->thread_id, DCWW_WAIT);
|
||||
return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Time
|
||||
*/
|
||||
|
||||
double rdtsc(void);
|
||||
double fluid_estimate_cpu_frequency(void);
|
||||
|
||||
static double fluid_cpu_frequency = -1.0;
|
||||
|
||||
void fluid_time_config(void)
|
||||
{
|
||||
if (fluid_cpu_frequency < 0.0) {
|
||||
fluid_cpu_frequency = fluid_estimate_cpu_frequency() / 1000000.0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int fluid_curtime(void)
|
||||
{
|
||||
ULONG ulMS;
|
||||
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulMS, sizeof( ULONG ));
|
||||
return ulMS;
|
||||
}
|
||||
|
||||
double fluid_utime(void)
|
||||
{
|
||||
return (rdtsc() / fluid_cpu_frequency);
|
||||
}
|
||||
|
||||
#define Q2ULL( q ) (*(unsigned long long *)&q)
|
||||
|
||||
double rdtsc(void)
|
||||
{
|
||||
QWORD t;
|
||||
DosTmrQueryTime(&t);
|
||||
return (double)Q2ULL(t);
|
||||
}
|
||||
|
||||
double fluid_estimate_cpu_frequency(void)
|
||||
{
|
||||
unsigned int before, after;
|
||||
QWORD start, stop;
|
||||
|
||||
before = fluid_curtime();
|
||||
DosTmrQueryTime(&start);
|
||||
|
||||
DosSleep(1000);
|
||||
|
||||
after = fluid_curtime();
|
||||
DosTmrQueryTime(&stop);
|
||||
|
||||
return (double) 1000 * (Q2ULL(stop) - Q2ULL(start)) / (after - before);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*=============================================================*/
|
||||
|
@ -1062,6 +1242,75 @@ int fluid_thread_join(fluid_thread_t* thread)
|
|||
return (wait_result == WAIT_OBJECT_0)? FLUID_OK : FLUID_FAILED;
|
||||
}
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
struct _fluid_thread_t {
|
||||
int thread_id;
|
||||
fluid_thread_func_t func;
|
||||
void* data;
|
||||
int detached;
|
||||
};
|
||||
|
||||
static void fluid_thread_start(void *data)
|
||||
{
|
||||
fluid_thread_t* thread = (fluid_thread_t*) data;
|
||||
|
||||
thread->func(thread->data);
|
||||
|
||||
if (thread->detached) {
|
||||
FLUID_FREE(thread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
fluid_thread_t* new_fluid_thread(fluid_thread_func_t func, void* data, int detach)
|
||||
{
|
||||
fluid_thread_t* thread;
|
||||
|
||||
if (func == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Invalid thread function");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thread = FLUID_NEW(fluid_thread_t);
|
||||
if (thread == NULL) {
|
||||
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
thread->data = data;
|
||||
thread->func = func;
|
||||
thread->detached = detach;
|
||||
|
||||
thread->thread_id = _beginthread(fluid_thread_start, NULL, 256 * 1024, (void *) thread);
|
||||
if (thread->thread_id == -1) {
|
||||
FLUID_LOG(FLUID_ERR, "Couldn't create the thread");
|
||||
FLUID_FREE(thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
int delete_fluid_thread(fluid_thread_t* thread)
|
||||
{
|
||||
FLUID_FREE(thread);
|
||||
return FLUID_OK;
|
||||
}
|
||||
|
||||
|
||||
int fluid_thread_join(fluid_thread_t* thread)
|
||||
{
|
||||
ULONG wait_result;
|
||||
if (thread->thread_id == -1) {
|
||||
return FLUID_OK;
|
||||
}
|
||||
wait_result = DosWaitThread(&thread->thread_id, DCWW_WAIT);
|
||||
return (wait_result == 0)? FLUID_OK : FLUID_FAILED;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
|
|
@ -90,6 +90,15 @@ double fluid_utime(void);
|
|||
unsigned int fluid_curtime();
|
||||
#define fluid_utime() 0.0
|
||||
|
||||
#elif defined(__OS2__)
|
||||
#define INCL_DOS
|
||||
#include <os2.h>
|
||||
|
||||
typedef int socklen_t;
|
||||
|
||||
unsigned int fluid_curtime(void);
|
||||
double fluid_utime(void);
|
||||
|
||||
#else
|
||||
|
||||
unsigned int fluid_curtime(void);
|
||||
|
@ -137,6 +146,13 @@ typedef HANDLE fluid_mutex_t;
|
|||
#define fluid_mutex_lock(_m) WaitForSingleObject(_m, INFINITE)
|
||||
#define fluid_mutex_unlock(_m) ReleaseMutex(_m)
|
||||
|
||||
#elif defined(__OS2__)
|
||||
typedef HMTX fluid_mutex_t;
|
||||
#define fluid_mutex_init(_m) { (_m) = 0; DosCreateMutexSem( NULL, &(_m), 0, FALSE ); }
|
||||
#define fluid_mutex_destroy(_m) if (_m) { DosCloseMutexSem(_m); }
|
||||
#define fluid_mutex_lock(_m) DosRequestMutexSem(_m, -1L)
|
||||
#define fluid_mutex_unlock(_m) DosReleaseMutexSem(_m)
|
||||
|
||||
#else
|
||||
typedef pthread_mutex_t fluid_mutex_t;
|
||||
#define fluid_mutex_init(_m) pthread_mutex_init(&(_m), NULL)
|
||||
|
@ -268,7 +284,7 @@ extern fluid_profile_data_t fluid_profile_data[];
|
|||
sample data.
|
||||
*/
|
||||
|
||||
#if HAVE_SYS_MMAN_H
|
||||
#if defined(HAVE_SYS_MMAN_H) && !defined(__OS2__)
|
||||
#define fluid_mlock(_p,_n) mlock(_p, _n)
|
||||
#define fluid_munlock(_p,_n) munlock(_p,_n)
|
||||
#else
|
||||
|
|
Loading…
Reference in a new issue