Further audiolib work... I think this is almost done!

git-svn-id: https://svn.eduke32.com/eduke32@8219 1a8010ca-5511-0410-912e-c29ae57300e0

# Conflicts:
#	GNUmakefile
#	platform/Windows/audiolib.vcxproj
#	platform/Windows/audiolib.vcxproj.filters
#	platform/Windows/build.vcxproj
#	platform/Windows/build.vcxproj.filters
#	source/audiolib/include/al_midi.h
#	source/audiolib/src/_al_midi.h
#	source/duke3d/src/osdcmds.cpp
#	source/duke3d/src/sounds.cpp
This commit is contained in:
terminx 2019-10-19 23:48:20 +00:00 committed by Christoph Oelckers
parent 8a1681fb5a
commit 8eb5233232
21 changed files with 1087 additions and 264 deletions

View file

@ -25,8 +25,8 @@
#include "midifuncs.h" #include "midifuncs.h"
extern int ASS_PCMSoundDriver; extern int ASS_PCMSoundDriver;
extern int ASS_CDSoundDriver;
extern int ASS_MIDISoundDriver; extern int ASS_MIDISoundDriver;
extern int ASS_EMIDICard;
int SoundDriver_IsPCMSupported(int driver); int SoundDriver_IsPCMSupported(int driver);
int SoundDriver_IsMIDISupported(int driver); int SoundDriver_IsMIDISupported(int driver);

View file

@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define FX_MAN_H_ #define FX_MAN_H_
#include "drivers.h" #include "drivers.h"
#include "inttypes.h" #include <inttypes.h>
#include "limits.h" #include "limits.h"
#include "multivoc.h" #include "multivoc.h"

View file

@ -61,7 +61,7 @@ typedef struct
extern const char *MUSIC_ErrorString(int ErrorNumber); extern const char *MUSIC_ErrorString(int ErrorNumber);
int MUSIC_Init(int SoundCard); int MUSIC_Init(int SoundCard, int ForceEMIDI = -1);
int MUSIC_Shutdown(void); int MUSIC_Shutdown(void);
void MUSIC_SetVolume(int volume); void MUSIC_SetVolume(int volume);
int MUSIC_GetVolume(void); int MUSIC_GetVolume(void);

View file

@ -36,8 +36,8 @@ typedef enum
ASS_NoSound, ASS_NoSound,
ASS_SDL, ASS_SDL,
ASS_DirectSound, ASS_DirectSound,
ASS_WinMM,
ASS_OPL3, ASS_OPL3,
ASS_WinMM,
ASS_NumSoundCards, ASS_NumSoundCards,
ASS_AutoDetect = -2 ASS_AutoDetect = -2
} soundcardnames; } soundcardnames;

View file

@ -25,11 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define ___MIDI_H #define ___MIDI_H
#include "compat.h" #include "compat.h"
#ifdef OPL_MIDI_HEADER #define RELATIVE_BEAT(measure, beat, tick) ((tick) + ((beat) << 9) + ((measure) << 16))
namespace OPLMusic {
#endif
#define RELATIVE_BEAT( measure, beat, tick ) \
( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
//Bobby Prince thinks this may be 100 //Bobby Prince thinks this may be 100
//#define GENMIDI_DefaultVolume 100 //#define GENMIDI_DefaultVolume 100
@ -105,7 +101,7 @@ namespace OPLMusic {
#define EMIDI_GeneralMIDI 0 #define EMIDI_GeneralMIDI 0
#define EMIDI_SoundBlaster 4 #define EMIDI_SoundBlaster 4
#define EMIDI_Adlib 7 #define EMIDI_AdLib 7
#define EMIDI_AffectsCurrentCard(c, type) (((c) == EMIDI_ALL_CARDS) || ((c) == (type))) #define EMIDI_AffectsCurrentCard(c, type) (((c) == EMIDI_ALL_CARDS) || ((c) == (type)))
#define EMIDI_NUM_CONTEXTS 7 #define EMIDI_NUM_CONTEXTS 7
@ -157,7 +153,4 @@ static void _MIDI_SetChannelVolume(int channel, int volume);
static void _MIDI_SendChannelVolumes(void); static void _MIDI_SendChannelVolumes(void);
static void _MIDI_InitEMIDI(void); static void _MIDI_InitEMIDI(void);
#ifdef OPL_MIDI_HEADER
}
#endif
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -18,15 +18,16 @@
*/ */
#include "al_midi.h"
#include "midifuncs.h" #include "midifuncs.h"
#include "opl3.h"
int AdlibDrv_GetError(void); int AdLibDrv_GetError(void);
const char *AdlibDrv_ErrorString( int ErrorNumber ); const char *AdLibDrv_ErrorString(int ErrorNumber);
int AdLibDrv_MIDI_Init(midifuncs *);
void AdLibDrv_MIDI_Shutdown(void);
int AdLibDrv_MIDI_StartPlayback(void (*service)(void));
void AdLibDrv_MIDI_HaltPlayback(void);
void AdLibDrv_MIDI_SetTempo(int tempo, int division);
int AdlibDrv_MIDI_Init(midifuncs *);
void AdlibDrv_MIDI_Shutdown(void);
int AdlibDrv_MIDI_StartPlayback(void (*service)(void));
void AdlibDrv_MIDI_HaltPlayback(void);
void AdlibDrv_MIDI_SetTempo(int tempo, int division);
void AdlibDrv_MIDI_Lock(void);
void AdlibDrv_MIDI_Unlock(void);

View file

@ -18,7 +18,7 @@
*/ */
#include "inttypes.h" #include <inttypes.h>
enum enum
{ {

View file

@ -98,7 +98,7 @@ int SDLDrv_GetError(void)
return ErrorCode; return ErrorCode;
} }
const char *SDLDrv_ErrorString( int ErrorNumber ) const char *SDLDrv_ErrorString(int ErrorNumber)
{ {
const char *ErrorString; const char *ErrorString;
@ -173,7 +173,7 @@ int SDLDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata)
#if (SDL_MAJOR_VERSION == 1) #if (SDL_MAJOR_VERSION == 1)
err = !SDL_OpenAudio(&spec, &actual); err = !SDL_OpenAudio(&spec, &actual);
#else #else
audio_dev = err = SDL_OpenAudioDevice(NULL, 0, &spec, &actual, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); audio_dev = err = SDL_OpenAudioDevice(nullptr, 0, &spec, &actual, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
#endif #endif
if (err == 0) { if (err == 0) {
@ -186,12 +186,25 @@ int SDLDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata)
SDL_AudioDriverName(drivername, sizeof(drivername)); SDL_AudioDriverName(drivername, sizeof(drivername));
MV_Printf("SDL %s driver\n", drivername); MV_Printf("SDL %s driver\n", drivername);
#else #else
char *drivername = Xstrdup(SDL_GetCurrentAudioDriver()); auto drivername = Xstrdup(SDL_GetCurrentAudioDriver());
for (int i=0;drivername[i] != 0;++i) for (int i=0;drivername[i] != 0;++i)
drivername[i] = toupperlookup[drivername[i]]; drivername[i] = toupperlookup[drivername[i]];
MV_Printf("SDL %s driver on %s\n", drivername ? drivername : "(error)", SDL_GetAudioDeviceName(0, 0)); auto devname = Xstrdup(SDL_GetAudioDeviceName(0, 0));
auto pdevname = Bstrchr(devname, '(');
if (pdevname)
{
auto rt = Bstrchr(pdevname++, ')');
if (rt != nullptr) *rt = '\0';
}
else
pdevname = devname;
MV_Printf("SDL %s driver on %s\n", drivername, pdevname);
Xfree(devname);
Xfree(drivername); Xfree(drivername);
#endif #endif

View file

@ -649,7 +649,7 @@ static DWORD WINAPI midiDataThread(LPVOID lpParameter)
DWORD sequenceTime; DWORD sequenceTime;
DWORD sleepAmount = 100 / THREAD_QUEUE_INTERVAL; DWORD sleepAmount = 100 / THREAD_QUEUE_INTERVAL;
MV_Printf("WinMM midiDataThread: started\n"); // MV_Printf("WinMM midiDataThread: started\n");
midiThreadTimer = midi_get_tick(); midiThreadTimer = midi_get_tick();
midiLastEventTime = midiThreadTimer; midiLastEventTime = midiThreadTimer;
@ -669,7 +669,7 @@ static DWORD WINAPI midiDataThread(LPVOID lpParameter)
do { do {
waitret = WaitForSingleObject(midiThreadQuitEvent, sleepAmount); waitret = WaitForSingleObject(midiThreadQuitEvent, sleepAmount);
if (waitret == WAIT_OBJECT_0) { if (waitret == WAIT_OBJECT_0) {
MV_Printf("WinMM midiDataThread: exiting\n"); // MV_Printf("WinMM midiDataThread: exiting\n");
break; break;
} else if (waitret == WAIT_TIMEOUT) { } else if (waitret == WAIT_TIMEOUT) {
// queue a tick // queue a tick
@ -712,7 +712,7 @@ int WinMMDrv_MIDI_StartPlayback(void (*service)(void))
midiThreadService = service; midiThreadService = service;
midiThreadQuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); midiThreadQuitEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
if (!midiThreadQuitEvent) { if (!midiThreadQuitEvent) {
ErrorCode = WinMMErr_MIDICreateEvent; ErrorCode = WinMMErr_MIDICreateEvent;
return WinMMErr_Error; return WinMMErr_Error;
@ -730,7 +730,7 @@ int WinMMDrv_MIDI_StartPlayback(void (*service)(void))
midiStreamRunning = TRUE; midiStreamRunning = TRUE;
} }
midiThread = CreateThread(NULL, 0, midiDataThread, 0, 0, 0); midiThread = CreateThread(nullptr, 0, midiDataThread, 0, 0, 0);
if (!midiThread) { if (!midiThread) {
WinMMDrv_MIDI_HaltPlayback(); WinMMDrv_MIDI_HaltPlayback();
ErrorCode = WinMMErr_MIDIPlayThread; ErrorCode = WinMMErr_MIDIPlayThread;
@ -748,7 +748,7 @@ void WinMMDrv_MIDI_HaltPlayback(void)
SetEvent(midiThreadQuitEvent); SetEvent(midiThreadQuitEvent);
WaitForSingleObject(midiThread, INFINITE); WaitForSingleObject(midiThread, INFINITE);
MV_Printf("WinMM MIDI_HaltPlayback synched\n"); // MV_Printf("WinMM MIDI_HaltPlayback synched\n");
CloseHandle(midiThread); CloseHandle(midiThread);
} }
@ -758,12 +758,12 @@ void WinMMDrv_MIDI_HaltPlayback(void)
} }
if (midiStreamRunning) { if (midiStreamRunning) {
MV_Printf("stopping stream\n"); // MV_Printf("stopping stream\n");
rv = midiStreamStop(midiStream); rv = midiStreamStop(midiStream);
if (rv != MMSYSERR_NOERROR) { if (rv != MMSYSERR_NOERROR) {
midi_error(rv, "WinMM MIDI_HaltPlayback midiStreamStop"); midi_error(rv, "WinMM MIDI_HaltPlayback midiStreamStop");
} }
MV_Printf("stream stopped\n"); // MV_Printf("stream stopped\n");
midiStreamRunning = FALSE; midiStreamRunning = FALSE;
} }

View file

@ -39,6 +39,7 @@
int ASS_PCMSoundDriver = ASS_AutoDetect; int ASS_PCMSoundDriver = ASS_AutoDetect;
int ASS_MIDISoundDriver = ASS_AutoDetect; int ASS_MIDISoundDriver = ASS_AutoDetect;
int ASS_EMIDICard = -1;
#define UNSUPPORTED_PCM 0,0,0,0,0,0 #define UNSUPPORTED_PCM 0,0,0,0,0,0
#define UNSUPPORTED_MIDI 0,0,0,0,0,0,0 #define UNSUPPORTED_MIDI 0,0,0,0,0,0,0
@ -68,7 +69,7 @@ static struct {
// Everyone gets the "no sound" driver // Everyone gets the "no sound" driver
{ {
"No Sound", "null sound device",
NoSoundDrv_GetError, NoSoundDrv_GetError,
NoSoundDrv_ErrorString, NoSoundDrv_ErrorString,
NoSoundDrv_PCM_Init, NoSoundDrv_PCM_Init,
@ -105,7 +106,7 @@ static struct {
#endif #endif
// Windows DirectSound // Windows DirectSound
#ifdef _WIN32 #ifdef RENDERTYPEWIN
{ {
"DirectSound", "DirectSound",
DirectSoundDrv_GetError, DirectSoundDrv_GetError,
@ -122,6 +123,23 @@ static struct {
UNSUPPORTED_COMPLETELY UNSUPPORTED_COMPLETELY
#endif #endif
// OPL3 emulation
{
"Nuked OPL3 AdLib emulator",
AdLibDrv_GetError,
AdLibDrv_ErrorString,
UNSUPPORTED_PCM,
AdLibDrv_MIDI_Init,
AdLibDrv_MIDI_Shutdown,
AdLibDrv_MIDI_StartPlayback,
AdLibDrv_MIDI_HaltPlayback,
AdLibDrv_MIDI_SetTempo,
nullptr,
nullptr,
},
// Windows MultiMedia system // Windows MultiMedia system
#ifdef _WIN32 #ifdef _WIN32
{ {
@ -142,23 +160,6 @@ static struct {
#else #else
UNSUPPORTED_COMPLETELY UNSUPPORTED_COMPLETELY
#endif #endif
// OPL3 emulation
{
"Nuked OPL3",
AdlibDrv_GetError,
AdlibDrv_ErrorString,
UNSUPPORTED_PCM,
AdlibDrv_MIDI_Init,
AdlibDrv_MIDI_Shutdown,
AdlibDrv_MIDI_StartPlayback,
AdlibDrv_MIDI_HaltPlayback,
AdlibDrv_MIDI_SetTempo,
AdlibDrv_MIDI_Lock,
AdlibDrv_MIDI_Unlock,
},
}; };
@ -223,7 +224,7 @@ int SoundDriver_MIDI_StartPlayback(void (*service)(void)) { return SoundDrivers
void SoundDriver_MIDI_Shutdown(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown(); } void SoundDriver_MIDI_Shutdown(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown(); }
void SoundDriver_MIDI_HaltPlayback(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback(); } void SoundDriver_MIDI_HaltPlayback(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback(); }
void SoundDriver_MIDI_SetTempo(int tempo, int division) { SoundDrivers[ASS_MIDISoundDriver].MIDI_SetTempo(tempo, division); } void SoundDriver_MIDI_SetTempo(int tempo, int division) { SoundDrivers[ASS_MIDISoundDriver].MIDI_SetTempo(tempo, division); }
void SoundDriver_MIDI_Lock(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock(); } void SoundDriver_MIDI_Lock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock(); }
void SoundDriver_MIDI_Unlock(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock(); } void SoundDriver_MIDI_Unlock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock(); }
// vim:ts=4:sw=4:expandtab: // vim:ts=4:sw=4:expandtab:

View file

@ -54,7 +54,7 @@ int FX_Init(int numvoices, int numchannels, unsigned mixrate, void *initdata)
if (SoundCard == ASS_AutoDetect) { if (SoundCard == ASS_AutoDetect) {
#if defined RENDERTYPESDL #if defined RENDERTYPESDL
SoundCard = ASS_SDL; SoundCard = ASS_SDL;
#elif defined _WIN32 #elif defined RENDERTYPEWIN
SoundCard = ASS_DirectSound; SoundCard = ASS_DirectSound;
#else #else
SoundCard = ASS_NoSound; SoundCard = ASS_NoSound;

View file

@ -19,22 +19,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <inttypes.h> #include <inttypes.h>
#include "_al_midi.h"
namespace OPLMusic { AdLibTimbre ADLIB_TimbreBank[256] =
typedef struct
{
uint8_t SAVEK[ 2 ];
uint8_t Level[ 2 ];
uint8_t Env1[ 2 ];
uint8_t Env2[ 2 ];
uint8_t Wave[ 2 ];
uint8_t Feedback;
int8_t Transpose;
int8_t Velocity;
} TIMBRE;
TIMBRE ADLIB_TimbreBank[ 256 ] =
{ {
{ { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0, 0 }, { { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0, 0 },
{ { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0, 0 }, { { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0, 0 },
@ -293,5 +280,3 @@ TIMBRE ADLIB_TimbreBank[ 256 ] =
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 },
{ { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 } { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }
}; };
}

View file

@ -38,12 +38,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "_midi.h" #include "_midi.h"
#include "_multivc.h" #include "_multivc.h"
#include "al_midi.h"
#include "compat.h" #include "compat.h"
#include "multivoc.h" #include "multivoc.h"
#include "music.h" #include "music.h"
#include "pragmas.h" #include "pragmas.h"
#include "sndcards.h" #include "sndcards.h"
#include "driver_adlib.h"
extern int MV_MixRate; extern int MV_MixRate;
extern int ASS_MIDISoundDriver; extern int ASS_MIDISoundDriver;
@ -86,8 +86,6 @@ static midifuncs *_MIDI_Funcs;
static int _MIDI_Reset; static int _MIDI_Reset;
static int MIDI_Tempo = 120;
int MV_MIDIRenderTempo = -1; int MV_MIDIRenderTempo = -1;
int MV_MIDIRenderTimer; int MV_MIDIRenderTimer;
@ -270,7 +268,7 @@ static int _MIDI_InterpretControllerInfo(track *Track, int TimeSet, int channel,
case EMIDI_CONTEXT_END : case EMIDI_CONTEXT_END :
if ((Track->currentcontext == _MIDI_Context) || (_MIDI_Context < 0) || if ((Track->currentcontext == _MIDI_Context) || (_MIDI_Context < 0) ||
(Track->context[_MIDI_Context].pos == NULL)) (Track->context[_MIDI_Context].pos == nullptr))
break; break;
Track->currentcontext = _MIDI_Context; Track->currentcontext = _MIDI_Context;
@ -333,7 +331,7 @@ static int _MIDI_InterpretControllerInfo(track *Track, int TimeSet, int channel,
case EMIDI_LOOP_END : case EMIDI_LOOP_END :
case EMIDI_SONG_LOOP_END : case EMIDI_SONG_LOOP_END :
if ((c2 != EMIDI_END_LOOP_VALUE) || (Track->context[0].loopstart == NULL) || (Track->context[0].loopcount == 0)) if ((c2 != EMIDI_END_LOOP_VALUE) || (Track->context[0].loopstart == nullptr) || (Track->context[0].loopcount == 0))
break; break;
if (c1 == EMIDI_SONG_LOOP_END) if (c1 == EMIDI_SONG_LOOP_END)
@ -507,9 +505,30 @@ static void _MIDI_ServiceRoutine(void)
_MIDI_GlobalPositionInTicks++; _MIDI_GlobalPositionInTicks++;
} }
static void _MIDI_ServiceMultivoc(void)
{
int16_t * buffer16 = (int16_t *)MV_MusicBuffer;
int const samples = MV_BufferSize >> 2;
for (int i = 0; i < samples; i++)
{
Bit16s buf[2];
while (MV_MIDIRenderTimer >= MV_MixRate)
{
if (MV_MIDIRenderTempo >= 0)
_MIDI_ServiceRoutine();
MV_MIDIRenderTimer -= MV_MixRate;
}
if (MV_MIDIRenderTempo >= 0) MV_MIDIRenderTimer += MV_MIDIRenderTempo;
OPL3_GenerateResampled(AL_GetChip(), buf);
*buffer16++ = clamp(buf[0]<<1, INT16_MIN, INT16_MAX);
*buffer16++ = clamp(buf[1]<<1, INT16_MIN, INT16_MAX);
}
}
static int _MIDI_SendControlChange(int channel, int c1, int c2) static int _MIDI_SendControlChange(int channel, int c1, int c2)
{ {
if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) if (_MIDI_Funcs == nullptr || _MIDI_Funcs->ControlChange == nullptr)
return MIDI_Error; return MIDI_Error;
_MIDI_Funcs->ControlChange(channel, c1, c2); _MIDI_Funcs->ControlChange(channel, c1, c2);
@ -517,6 +536,16 @@ static int _MIDI_SendControlChange(int channel, int c1, int c2)
return MIDI_Ok; return MIDI_Ok;
} }
static int _MIDI_SendProgramChange(int channel, int c1)
{
if (_MIDI_Funcs == nullptr || _MIDI_Funcs->ProgramChange == nullptr)
return MIDI_Error;
_MIDI_Funcs->ProgramChange(channel, c1);
return MIDI_Ok;
}
int MIDI_AllNotesOff(void) int MIDI_AllNotesOff(void)
{ {
SoundDriver_MIDI_Lock(); SoundDriver_MIDI_Lock();
@ -536,9 +565,9 @@ int MIDI_AllNotesOff(void)
static void _MIDI_SetChannelVolume(int channel, int volume) static void _MIDI_SetChannelVolume(int channel, int volume)
{ {
_MIDI_ChannelVolume[ channel ] = volume; _MIDI_ChannelVolume[channel] = volume;
if (_MIDI_Funcs == NULL || _MIDI_Funcs->ControlChange == NULL) if (_MIDI_Funcs == nullptr || _MIDI_Funcs->ControlChange == nullptr)
return; return;
volume *= _MIDI_TotalVolume; volume *= _MIDI_TotalVolume;
@ -566,7 +595,13 @@ int MIDI_Reset(void)
_MIDI_SendControlChange(channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB); _MIDI_SendControlChange(channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB);
_MIDI_SendControlChange(channel, MIDI_DATAENTRY_MSB, 2); /* Pitch Bend Sensitivity MSB */ _MIDI_SendControlChange(channel, MIDI_DATAENTRY_MSB, 2); /* Pitch Bend Sensitivity MSB */
_MIDI_SendControlChange(channel, MIDI_DATAENTRY_LSB, 0); /* Pitch Bend Sensitivity LSB */ _MIDI_SendControlChange(channel, MIDI_DATAENTRY_LSB, 0); /* Pitch Bend Sensitivity LSB */
_MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume; _MIDI_ChannelVolume[channel] = GENMIDI_DefaultVolume;
_MIDI_SendControlChange(channel, MIDI_PAN, 64); // begin TURRICAN's recommendation
_MIDI_SendControlChange(channel, MIDI_REVERB, 40);
_MIDI_SendControlChange(channel, MIDI_CHORUS, 0);
_MIDI_SendControlChange(channel, MIDI_BANK_SELECT_MSB, 0);
_MIDI_SendControlChange(channel, MIDI_BANK_SELECT_LSB, 0);
_MIDI_SendProgramChange(channel, 0); // end TURRICAN's recommendation
} }
_MIDI_SendChannelVolumes(); _MIDI_SendChannelVolumes();
@ -581,7 +616,7 @@ int MIDI_Reset(void)
int MIDI_SetVolume(int volume) int MIDI_SetVolume(int volume)
{ {
if (_MIDI_Funcs == NULL) if (_MIDI_Funcs == nullptr)
return MIDI_NullMidiModule; return MIDI_NullMidiModule;
volume = min(MIDI_MaxVolume, volume); volume = min(MIDI_MaxVolume, volume);
@ -604,7 +639,7 @@ int MIDI_SetVolume(int volume)
int MIDI_GetVolume(void) int MIDI_GetVolume(void)
{ {
if (_MIDI_Funcs == NULL) if (_MIDI_Funcs == nullptr)
return MIDI_NullMidiModule; return MIDI_NullMidiModule;
SoundDriver_MIDI_Lock(); SoundDriver_MIDI_Lock();
@ -668,7 +703,7 @@ int MIDI_PlaySong(char *song, int loopflag)
track *CurrentTrack; track *CurrentTrack;
char *ptr; char *ptr;
if (_MIDI_Funcs == NULL) if (_MIDI_Funcs == nullptr)
return MIDI_NullMidiModule; return MIDI_NullMidiModule;
if (B_UNBUF32(song) != MIDI_HEADER_SIGNATURE) if (B_UNBUF32(song) != MIDI_HEADER_SIGNATURE)
@ -723,7 +758,6 @@ int MIDI_PlaySong(char *song, int loopflag)
if (_MIDI_SongLoaded) if (_MIDI_SongLoaded)
MIDI_StopSong(); MIDI_StopSong();
_MIDI_Loop = loopflag; _MIDI_Loop = loopflag;
_MIDI_NumTracks = My_MIDI_NumTracks; _MIDI_NumTracks = My_MIDI_NumTracks;
_MIDI_Division = My_MIDI_Division; _MIDI_Division = My_MIDI_Division;
@ -738,15 +772,10 @@ int MIDI_PlaySong(char *song, int loopflag)
_MIDI_Reset = FALSE; _MIDI_Reset = FALSE;
if (ASS_MIDISoundDriver == ASS_OPL3)
{
MV_MIDIRenderTempo = 100;
MV_MIDIRenderTimer = 0;
}
MIDI_SetTempo(120); MIDI_SetTempo(120);
if (SoundDriver_MIDI_StartPlayback(ASS_MIDISoundDriver == ASS_OPL3 ? MV_RenderMIDI : _MIDI_ServiceRoutine) != MIDI_Ok) // this can either stay like this, or I can add another field to the MIDI driver spec that holds the service callback
if (SoundDriver_MIDI_StartPlayback(ASS_MIDISoundDriver == ASS_OPL3 ? _MIDI_ServiceMultivoc : _MIDI_ServiceRoutine) != MIDI_Ok)
return MIDI_DriverError; return MIDI_DriverError;
_MIDI_SongLoaded = TRUE; _MIDI_SongLoaded = TRUE;
@ -757,19 +786,11 @@ int MIDI_PlaySong(char *song, int loopflag)
void MIDI_SetTempo(int tempo) void MIDI_SetTempo(int tempo)
{ {
MIDI_Tempo = tempo;
SoundDriver_MIDI_SetTempo(tempo, _MIDI_Division); SoundDriver_MIDI_SetTempo(tempo, _MIDI_Division);
int const tickspersecond = tempo * _MIDI_Division / 60; int const tickspersecond = tempo * _MIDI_Division / 60;
_MIDI_FPSecondsPerTick = tabledivide32_noinline(1 << TIME_PRECISION, tickspersecond); _MIDI_FPSecondsPerTick = tabledivide32_noinline(1 << TIME_PRECISION, tickspersecond);
} }
void MIDI_SetDivision(int division)
{
UNREFERENCED_PARAMETER(division);
}
int MIDI_GetTempo(void) { return MIDI_Tempo; }
static void _MIDI_InitEMIDI(void) static void _MIDI_InitEMIDI(void)
{ {
int type = EMIDI_GeneralMIDI; int type = EMIDI_GeneralMIDI;
@ -777,10 +798,13 @@ static void _MIDI_InitEMIDI(void)
switch (ASS_MIDISoundDriver) switch (ASS_MIDISoundDriver)
{ {
case ASS_OPL3: case ASS_OPL3:
type = EMIDI_Adlib; type = EMIDI_SoundBlaster;
break; break;
} }
if (ASS_EMIDICard != -1)
type = ASS_EMIDICard;
_MIDI_ResetTracks(); _MIDI_ResetTracks();
_MIDI_TotalTime = 0; _MIDI_TotalTime = 0;
@ -791,7 +815,7 @@ static void _MIDI_InitEMIDI(void)
track *Track = _MIDI_TrackPtr; track *Track = _MIDI_TrackPtr;
int tracknum = 0; int tracknum = 0;
while ((tracknum < _MIDI_NumTracks) && (Track != NULL)) while ((tracknum < _MIDI_NumTracks) && (Track != nullptr))
{ {
_MIDI_Tick = 0; _MIDI_Tick = 0;
_MIDI_Beat = 1; _MIDI_Beat = 1;
@ -894,7 +918,7 @@ static void _MIDI_InitEMIDI(void)
case EMIDI_SONG_LOOP_END : case EMIDI_SONG_LOOP_END :
if (c2 == EMIDI_END_LOOP_VALUE) if (c2 == EMIDI_END_LOOP_VALUE)
{ {
Track->context[ 0 ].loopstart = NULL; Track->context[ 0 ].loopstart = nullptr;
Track->context[ 0 ].loopcount = 0; Track->context[ 0 ].loopcount = 0;
} }
break; break;
@ -983,30 +1007,3 @@ static void _MIDI_InitEMIDI(void)
_MIDI_ResetTracks(); _MIDI_ResetTracks();
} }
void MV_RenderMIDI(void)
{
int16_t * buffer16 = (int16_t *)MV_MusicBuffer;
int const samples = MV_BufferSize >> 2;
for (int i = 0; i < samples; i++)
{
Bit16s buf[2];
while (MV_MIDIRenderTimer >= MV_MixRate)
{
if (MV_MIDIRenderTempo >= 0)
_MIDI_ServiceRoutine();
MV_MIDIRenderTimer -= MV_MixRate;
}
if (MV_MIDIRenderTempo >= 0) MV_MIDIRenderTimer += MV_MIDIRenderTempo;
OPL3_GenerateResampled(&OPLMusic::chip, buf);
*buffer16++ = clamp(buf[0]<<1, INT16_MIN, INT16_MAX);
*buffer16++ = clamp(buf[1]<<1, INT16_MIN, INT16_MAX);
}
}
void MIDI_UpdateMusic(void)
{
}

View file

@ -65,9 +65,5 @@ void MIDI_PauseSong(void);
void MIDI_StopSong(void); void MIDI_StopSong(void);
int MIDI_PlaySong(char *song, int loopflag); int MIDI_PlaySong(char *song, int loopflag);
void MIDI_SetTempo(int tempo); void MIDI_SetTempo(int tempo);
int MIDI_GetTempo(void);
void MV_RenderMIDI(void);
void MIDI_UpdateMusic(void);
void MIDI_SetDivision(int division);
#endif #endif

View file

@ -909,7 +909,7 @@ void MV_UnhookMusicRoutine(void)
if (MV_MusicCallback) if (MV_MusicCallback)
{ {
MV_Lock(); MV_Lock();
MV_MusicCallback = NULL; MV_MusicCallback = nullptr;
MV_MixMusic = FALSE; MV_MixMusic = FALSE;
MV_Unlock(); MV_Unlock();
} }

View file

@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "music.h" #include "music.h"
#include "al_midi.h"
#include "compat.h" #include "compat.h"
#include "drivers.h" #include "drivers.h"
#include "midi.h" #include "midi.h"
@ -55,7 +54,7 @@ const char *MUSIC_ErrorString(int ErrorNumber)
} }
int MUSIC_Init(int SoundCard) int MUSIC_Init(int SoundCard, int EMIDICard /*= -1*/)
{ {
int detected = 0; int detected = 0;
@ -63,14 +62,7 @@ int MUSIC_Init(int SoundCard)
{ {
redetect: redetect:
detected++; detected++;
SoundCard = ASS_OPL3;
#if defined _WIN32
SoundCard = ASS_WinMM;
#elif RENDERTYPESDL
SoundCard = ASS_SDL;
#else
SoundCard = ASS_NoSound;
#endif
} }
if (SoundCard < 0 || SoundCard >= ASS_NumSoundCards) if (SoundCard < 0 || SoundCard >= ASS_NumSoundCards)
@ -92,6 +84,7 @@ failed:
} }
ASS_MIDISoundDriver = SoundCard; ASS_MIDISoundDriver = SoundCard;
ASS_EMIDICard = EMIDICard;
int status = SoundDriver_MIDI_Init(&MUSIC_MidiFunctions); int status = SoundDriver_MIDI_Init(&MUSIC_MidiFunctions);
@ -103,7 +96,7 @@ failed:
goto failed; goto failed;
} }
MV_Printf("successfully initialized %s!\n", SoundDriver_GetName(SoundCard)); MV_Printf("%s\n", SoundDriver_GetName(SoundCard));
MIDI_SetMidiFuncs(&MUSIC_MidiFunctions); MIDI_SetMidiFuncs(&MUSIC_MidiFunctions);
@ -154,5 +147,4 @@ int MUSIC_PlaySong(char *song, int songsize, int loopflag, const char *fn /*= nu
void MUSIC_Update(void) void MUSIC_Update(void)
{ {
MIDI_UpdateMusic();
} }

View file

@ -58,7 +58,6 @@ int MUSIC_Init(int SoundCard)
g_musicPlayerCommandLine = getenv("EDUKE32_MUSIC_CMD"); g_musicPlayerCommandLine = getenv("EDUKE32_MUSIC_CMD");
UNREFERENCED_PARAMETER(SoundCard); UNREFERENCED_PARAMETER(SoundCard);
UNREFERENCED_PARAMETER(Address);
if (g_musicPlayerReady) if (g_musicPlayerReady)
{ {
@ -126,7 +125,7 @@ int MUSIC_Init(int SoundCard)
} }
g_musicFileNameArgvPos = numargs; g_musicFileNameArgvPos = numargs;
g_musicPlayerArgv[numargs] = g_musicFileName; g_musicPlayerArgv[numargs] = g_musicFileName;
g_musicPlayerArgv[numargs+1] = NULL; g_musicPlayerArgv[numargs+1] = nullptr;
#if 0 #if 0
if (mprotect(g_musicPlayerArgv, sz, PROT_READ)==-1) // make argv and command string read-only if (mprotect(g_musicPlayerArgv, sz, PROT_READ)==-1) // make argv and command string read-only
@ -151,44 +150,6 @@ int MUSIC_Shutdown(void)
return MUSIC_Ok; return MUSIC_Ok;
} // MUSIC_Shutdown } // MUSIC_Shutdown
void MUSIC_SetMaxFMMidiChannel(int channel)
{
UNREFERENCED_PARAMETER(channel);
} // MUSIC_SetMaxFMMidiChannel
int MUSIC_Volume;
void MUSIC_SetVolume(int volume)
{
volume = max(0, volume);
volume = min(volume, 255);
MUSIC_Volume = volume;
} // MUSIC_SetVolume
int MUSIC_GetVolume(void)
{
return MUSIC_Volume;
} // MUSIC_GetVolume
void MUSIC_SetLoopFlag(int loopflag)
{
UNREFERENCED_PARAMETER(loopflag);
} // MUSIC_SetLoopFlag
void MUSIC_Continue(void)
{
} // MUSIC_Continue
void MUSIC_Pause(void)
{
} // MUSIC_Pause
int MUSIC_StopSong(void) int MUSIC_StopSong(void)
{ {
if (!g_musicPlayerEnabled) if (!g_musicPlayerEnabled)
@ -205,9 +166,9 @@ int MUSIC_StopSong(void)
ts.tv_nsec = 5000000; // sleep 5ms at most ts.tv_nsec = 5000000; // sleep 5ms at most
kill(g_musicPlayerHandle, SIGTERM); kill(g_musicPlayerHandle, SIGTERM);
nanosleep(&ts, NULL); nanosleep(&ts, nullptr);
if (int ret = waitpid(g_musicPlayerHandle, NULL, WNOHANG|WUNTRACED) != g_musicPlayerHandle) if (int ret = waitpid(g_musicPlayerHandle, nullptr, WNOHANG|WUNTRACED) != g_musicPlayerHandle)
{ {
if (ret==-1) if (ret==-1)
initprintf("%s: waitpid: %s\n", __func__, strerror(errno)); initprintf("%s: waitpid: %s\n", __func__, strerror(errno));
@ -218,7 +179,7 @@ int MUSIC_StopSong(void)
initprintf("%s: SIGTERM timed out--trying SIGKILL\n", __func__); initprintf("%s: SIGTERM timed out--trying SIGKILL\n", __func__);
if (waitpid(g_musicPlayerHandle, NULL, WUNTRACED)==-1) if (waitpid(g_musicPlayerHandle, nullptr, WUNTRACED)==-1)
initprintf("%s: waitpid: %s\n", __func__, strerror(errno)); initprintf("%s: waitpid: %s\n", __func__, strerror(errno));
} }
} }
@ -241,7 +202,7 @@ static int MUSIC_PlayExternal()
ZeroMemory(&pi,sizeof(pi)); ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si); si.cb = sizeof(si);
if (!CreateProcess(NULL,g_musicPlayerCommandLine,NULL,NULL,0,0,NULL,NULL,&si,&pi)) if (!CreateProcess(nullptr,g_musicPlayerCommandLine,nullptr,nullptr,0,0,nullptr,nullptr,&si,&pi))
{ {
MV_Printf("%s: CreateProcess: %s\n", __func__, windowsGetErrorMessage(GetLastError())); MV_Printf("%s: CreateProcess: %s\n", __func__, windowsGetErrorMessage(GetLastError()));
return MUSIC_Error; return MUSIC_Error;
@ -310,7 +271,7 @@ int MUSIC_PlaySong(char *song, int songsize, int loopflag, const char *fn /*= nu
sa.sa_flags=0; sa.sa_flags=0;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
if (sigaction(SIGCHLD, &sa, NULL)==-1) if (sigaction(SIGCHLD, &sa, nullptr)==-1)
initprintf("%s: sigaction: %s\n", __func__, strerror(errno)); initprintf("%s: sigaction: %s\n", __func__, strerror(errno));
sigchld_handler_set = 1; sigchld_handler_set = 1;

View file

@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef PITCH_H_ #ifndef PITCH_H_
#define PITCH_H_ #define PITCH_H_
#include "inttypes.h" #include <inttypes.h>
uint32_t PITCH_GetScale(int pitchoffset); uint32_t PITCH_GetScale(int pitchoffset);
#endif #endif

View file

@ -1166,16 +1166,16 @@ static MenuEntry_t ME_SOUND_NUMVOICES = MAKE_MENUENTRY( "Voices:", &MF_Redfont,
#endif #endif
static char const *MEOSN_SOUND_MUSICDEVICE[] = { static char const *MEOSN_SOUND_MUSICDEVICE[] = {
"OPL3",
#ifdef _WIN32 #ifdef _WIN32
"Windows", "Windows",
#endif #endif
"OPL3",
}; };
static int32_t MEOSV_SOUND_MUSICDEVICE[] = { static int32_t MEOSV_SOUND_MUSICDEVICE[] = {
ASS_OPL3,
#ifdef _WIN32 #ifdef _WIN32
ASS_WinMM, ASS_WinMM,
#endif #endif
ASS_OPL3,
}; };
static MenuOptionSet_t MEOS_SOUND_MUSICDEVICE = MAKE_MENUOPTIONSET( MEOSN_SOUND_MUSICDEVICE, MEOSV_SOUND_MUSICDEVICE, 0x2 ); static MenuOptionSet_t MEOS_SOUND_MUSICDEVICE = MAKE_MENUOPTIONSET( MEOSN_SOUND_MUSICDEVICE, MEOSV_SOUND_MUSICDEVICE, 0x2 );

View file

@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "duke3d.h" #include "duke3d.h"
#include "renderlayer.h" // for win_gethwnd() #include "renderlayer.h" // for win_gethwnd()
#include "al_midi.h"
#include <atomic> #include <atomic>
#include "vfs.h" #include "vfs.h"
@ -117,6 +118,19 @@ void S_MusicStartup(void)
if (MUSIC_Init(ud.config.MusicDevice) == MUSIC_Ok || MUSIC_Init(0) == MUSIC_Ok || MUSIC_Init(1) == MUSIC_Ok) if (MUSIC_Init(ud.config.MusicDevice) == MUSIC_Ok || MUSIC_Init(0) == MUSIC_Ok || MUSIC_Init(1) == MUSIC_Ok)
{ {
MUSIC_SetVolume(mus_volume); MUSIC_SetVolume(mus_volume);
// TODO: figure out why this produces garbage output
#if 0
if (auto fil = kopen4load("d3dtimbr.tmb", 0) != -1)
{
int l = kfilelength(fil);
auto tmb = (uint8_t *)Xmalloc(l);
kread(fil, tmb, l);
OPLMusic::AL_RegisterTimbreBank(tmb);
Xfree(tmb);
kclose(fil);
}
#endif
return; return;
} }