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

This commit is contained in:
terminx 2009-07-27 05:45:14 +00:00
parent f80a415898
commit 039f004fb4
43 changed files with 0 additions and 16485 deletions

View file

@ -1,282 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: _MIDI.H
author: James R. Dose
date: May 25, 1994
Private header for MIDI.C. Midi song file playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___MIDI_H
#define ___MIDI_H
#include "compat.h"
#define RELATIVE_BEAT( measure, beat, tick ) \
( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
//Bobby Prince thinks this may be 100
//#define GENMIDI_DefaultVolume 100
#define GENMIDI_DefaultVolume 90
#define MAX_FORMAT 1
#define NUM_MIDI_CHANNELS 16
#define TIME_PRECISION 16
#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd"
#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk"
#define MIDI_VOLUME 7
#define MIDI_PAN 10
#define MIDI_DETUNE 94
#define MIDI_RHYTHM_CHANNEL 9
#define MIDI_RPN_MSB 100
#define MIDI_RPN_LSB 101
#define MIDI_DATAENTRY_MSB 6
#define MIDI_DATAENTRY_LSB 38
#define MIDI_PITCHBEND_MSB 0
#define MIDI_PITCHBEND_LSB 0
#define MIDI_RUNNING_STATUS 0x80
#define MIDI_NOTE_OFF 0x8
#define MIDI_NOTE_ON 0x9
#define MIDI_POLY_AFTER_TCH 0xA
#define MIDI_CONTROL_CHANGE 0xB
#define MIDI_PROGRAM_CHANGE 0xC
#define MIDI_AFTER_TOUCH 0xD
#define MIDI_PITCH_BEND 0xE
#define MIDI_SPECIAL 0xF
#define MIDI_SYSEX 0xF0
#define MIDI_SYSEX_CONTINUE 0xF7
#define MIDI_META_EVENT 0xFF
#define MIDI_END_OF_TRACK 0x2F
#define MIDI_TEMPO_CHANGE 0x51
#define MIDI_TIME_SIGNATURE 0x58
#define MIDI_RESET_ALL_CONTROLLERS 0x79
#define MIDI_ALL_NOTES_OFF 0x7b
#define MIDI_MONO_MODE_ON 0x7E
#define MIDI_SYSTEM_RESET 0xFF
#define GET_NEXT_EVENT( track, data ) \
( data ) = *( track )->pos; \
( track )->pos += 1
#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf )
#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 )
#define EMIDI_INFINITE -1
#define EMIDI_END_LOOP_VALUE 127
#define EMIDI_ALL_CARDS 127
#define EMIDI_INCLUDE_TRACK 110
#define EMIDI_EXCLUDE_TRACK 111
#define EMIDI_PROGRAM_CHANGE 112
#define EMIDI_VOLUME_CHANGE 113
#define EMIDI_CONTEXT_START 114
#define EMIDI_CONTEXT_END 115
#define EMIDI_LOOP_START 116
#define EMIDI_LOOP_END 117
#define EMIDI_SONG_LOOP_START 118
#define EMIDI_SONG_LOOP_END 119
#define EMIDI_GeneralMIDI 0
#define EMIDI_AffectsCurrentCard( c, type ) \
( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
#define EMIDI_NUM_CONTEXTS 7
typedef struct
{
char *pos;
char *loopstart;
int16_t loopcount;
int16_t RunningStatus;
uint32_t time;
int32_t FPSecondsPerTick;
int16_t tick;
int16_t beat;
int16_t measure;
int16_t BeatsPerMeasure;
int16_t TicksPerBeat;
int16_t TimeBase;
int32_t delay;
int16_t active;
} songcontext;
typedef struct
{
char *start;
char *pos;
int32_t delay;
int16_t active;
int16_t RunningStatus;
int16_t currentcontext;
songcontext context[ EMIDI_NUM_CONTEXTS ];
char EMIDI_IncludeTrack;
char EMIDI_ProgramChange;
char EMIDI_VolumeChange;
} track;
static int32_t _MIDI_ReadNumber( void *from, size_t size );
static int32_t _MIDI_ReadDelta( track *ptr );
static void _MIDI_ResetTracks( void );
static void _MIDI_AdvanceTick( void );
static void _MIDI_MetaEvent( track *Track );
static void _MIDI_SysEx( track *Track );
static int32_t _MIDI_InterpretControllerInfo( track *Track, int32_t TimeSet,
int32_t channel, int32_t c1, int32_t c2 );
static int32_t _MIDI_SendControlChange( int32_t channel, int32_t c1, int32_t c2 );
static void _MIDI_SetChannelVolume( int32_t channel, int32_t volume );
static void _MIDI_SendChannelVolumes( void );
static int32_t _MIDI_ProcessNextTick( void );
static void _MIDI_InitEMIDI( void );
/*
if ( c1 == EMIDI_LOOP_START )
{
if ( c2 == 0 )
{
Track->context[ 0 ].loopcount = EMIDI_INFINITE;
}
else
{
Track->context[ 0 ].loopcount = c2;
}
Track->context[ 0 ].pos = Track->pos;
Track->context[ 0 ].loopstart = Track->pos;
Track->context[ 0 ].RunningStatus = Track->RunningStatus;
Track->context[ 0 ].time = _MIDI_Time;
Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
Track->context[ 0 ].tick = _MIDI_Tick;
Track->context[ 0 ].beat = _MIDI_Beat;
Track->context[ 0 ].measure = _MIDI_Measure;
Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
Track->context[ 0 ].TimeBase = _MIDI_TimeBase;
break;
}
if ( ( c1 == EMIDI_LOOP_END ) &&
( c2 == EMIDI_END_LOOP_VALUE ) )
{
if ( ( Track->context[ 0 ].loopstart != NULL ) &&
( Track->context[ 0 ].loopcount != 0 ) )
{
if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
{
Track->context[ 0 ].loopcount--;
}
Track->pos = Track->context[ 0 ].loopstart;
Track->RunningStatus = Track->context[ 0 ].RunningStatus;
if ( !TimeSet )
{
_MIDI_Time = Track->context[ 0 ].time;
_MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
_MIDI_Tick = Track->context[ 0 ].tick;
_MIDI_Beat = Track->context[ 0 ].beat;
_MIDI_Measure = Track->context[ 0 ].measure;
_MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure;
_MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat;
_MIDI_TimeBase = Track->context[ 0 ].TimeBase;
TimeSet = TRUE;
}
}
break;
}
if ( c1 == MIDI_MONO_MODE_ON )
{
Track->pos++;
}
if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
{
_MIDI_SetChannelVolume( channel, c2 );
break;
}
else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
( Track->EMIDI_VolumeChange ) )
{
_MIDI_SetChannelVolume( channel, c2 );
break;
}
if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
( Track->EMIDI_ProgramChange ) )
{
_MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
break;
}
if ( c1 == EMIDI_CONTEXT_START )
{
break;
}
if ( c1 == EMIDI_CONTEXT_END )
{
if ( ( Track->currentcontext != _MIDI_Context ) ||
( Track->context[ _MIDI_Context ].pos == NULL )
{
break;
}
Track->currentcontext = _MIDI_Context;
Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
Track->pos = Track->context[ _MIDI_Context ].pos;
Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
if ( TimeSet )
{
break;
}
_MIDI_Time = Track->context[ _MIDI_Context ].time;
_MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
_MIDI_Tick = Track->context[ _MIDI_Context ].tick;
_MIDI_Beat = Track->context[ _MIDI_Context ].beat;
_MIDI_Measure = Track->context[ _MIDI_Context ].measure;
_MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure;
_MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat;
_MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase;
TimeSet = TRUE;
break;
}
if ( _MIDI_Funcs->ControlChange )
{
_MIDI_Funcs->ControlChange( channel, c1, c2 );
}
*/
#endif

View file

@ -1,277 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
file: _MULTIVC.H
author: James R. Dose
date: December 20, 1993
Private header for MULTIVOC.C
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef ___MULTIVC_H
#define ___MULTIVC_H
#include "openal.h"
#ifndef TRUE
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#endif
#define VOC_8BIT 0x0
#define VOC_CT4_ADPCM 0x1
#define VOC_CT3_ADPCM 0x2
#define VOC_CT2_ADPCM 0x3
#define VOC_16BIT 0x4
#define VOC_ALAW 0x6
#define VOC_MULAW 0x7
#define VOC_CREATIVE_ADPCM 0x200
#define T_SIXTEENBIT_STEREO 0
#define T_8BITS 1
#define T_MONO 2
#define T_16BITSOURCE 4
#define T_LEFTQUIET 8
#define T_RIGHTQUIET 16
#define T_DEFAULT T_SIXTEENBIT_STEREO
#define MV_MaxPanPosition 127
#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
#define MV_MaxTotalVolume 255
//#define MV_MaxVolume 63
#define MV_NumVoices 8
#define MIX_VOLUME( volume ) \
( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
// ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 )
//#define SILENCE_16BIT 0x80008000
#define SILENCE_16BIT 0
#define SILENCE_8BIT 0x80808080
//#define SILENCE_16BIT_PAS 0
#if defined(_WIN32)
#define MixBufferSize (MV_GetBufferSize(MV_RequestedMixRate))
#else
#define MixBufferSize (512)
#endif
#define NumberOfBuffers 16
#define TotalBufferSize ( MixBufferSize * NumberOfBuffers )
#define PI 3.14159265358979323
typedef enum
{
Raw,
VOC,
DemandFeed,
WAV,
OGG
} wavedata;
typedef enum
{
NoMoreData,
KeepPlaying
} playbackstatus;
typedef struct VoiceNode
{
struct VoiceNode *next;
struct VoiceNode *prev;
wavedata wavetype;
char bits;
playbackstatus(*GetSound)(struct VoiceNode *voice);
void (*mix)(uint32_t position, uint32_t rate,
char *start, uint32_t length);
char *NextBlock;
char *LoopStart;
char *LoopEnd;
uint32_t LoopCount;
uint32_t LoopSize;
uint32_t BlockLength;
uint32_t PitchScale;
uint32_t FixedPointBufferSize;
char *sound;
uint32_t length;
uint32_t SamplingRate;
uint32_t RateScale;
uint32_t position;
int32_t Playing;
int32_t handle;
int32_t priority;
void (*DemandFeed)(char **ptr, uint32_t *length);
sounddef OGGstream;
// char *bufsnd;
char bufsnd[0x8000*4];
int32_t downsample;
int16_t *LeftVolume;
int16_t *RightVolume;
uint32_t callbackval;
} VoiceNode;
typedef struct
{
VoiceNode *start;
VoiceNode *end;
} VList;
typedef struct
{
char left;
char right;
} Pan;
typedef struct
{
MONO16 left;
MONO16 right;
} STEREO16;
typedef struct
{
MONO16 left;
MONO16 right;
} SIGNEDSTEREO16;
typedef struct
{
char left;
char right;
} STEREO8;
typedef struct
{
char RIFF[ 4 ];
uint32_t file_size;
char WAVE[ 4 ];
char fmt[ 4 ];
uint32_t format_size;
} riff_header;
typedef struct
{
uint16_t wFormatTag;
uint16_t nChannels;
uint32_t nSamplesPerSec;
uint32_t nAvgBytesPerSec;
uint16_t nBlockAlign;
uint16_t nBitsPerSample;
} format_header;
typedef struct
{
char DATA[ 4 ];
uint32_t size;
} data_header;
typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
#if defined(_WIN32)
static uint32_t MV_GetBufferSize(uint32_t);
#endif
static void MV_Mix(VoiceNode *voice, int32_t buffer);
static void MV_PlayVoice(VoiceNode *voice);
static void MV_StopVoice(VoiceNode *voice);
static int32_t MV_ServiceVoc(int32_t);
static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice);
static playbackstatus MV_GetNextDemandFeedBlock(VoiceNode *voice);
static playbackstatus MV_GetNextRawBlock(VoiceNode *voice);
static playbackstatus MV_GetNextWAVBlock(VoiceNode *voice);
// static void MV_ServiceRecord( void );
static VoiceNode *MV_GetVoice(int32_t handle);
static VoiceNode *MV_AllocVoice(int32_t priority);
static int16_t *MV_GetVolumeTable(int32_t vol);
static void MV_SetVoiceMixMode(VoiceNode *voice);
static void MV_SetVoicePitch(VoiceNode *voice, uint32_t rate, int32_t pitchoffset);
static void MV_CalcVolume(int32_t MaxLevel);
static void MV_CalcPanTable(void);
static void ClearBuffer_DW(void *ptr, int32_t data, int32_t length);
#if defined(_MSC_VER)
#define CDEC _cdecl
#elif defined(_WIN32)
#define CDEC __cdecl
#else
#define CDEC
#endif
void CDEC MV_Mix8BitMono(uint32_t position, uint32_t rate,
char *start, uint32_t length);
void CDEC MV_Mix8BitStereo(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_Mix16BitMono(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_Mix16BitStereo(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_Mix16BitMono16(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_Mix8BitMono16(uint32_t position, uint32_t rate,
char *start, uint32_t length);
void CDEC MV_Mix8BitStereo16(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_Mix16BitStereo16(uint32_t position,
uint32_t rate, char *start, uint32_t length);
void CDEC MV_16BitReverb(char *src, char *dest, VOLUME16 *volume, int32_t count);
void CDEC MV_8BitReverb(char *src, char *dest, VOLUME16 *volume, int32_t count);
void CDEC MV_16BitReverbFast(char *src, char *dest, int32_t count, int32_t shift);
void CDEC MV_8BitReverbFast(char *src, char *dest, int32_t count, int32_t shift);
#undef CDEC
#endif

View file

@ -1,393 +0,0 @@
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Dummy AudioLib stub implementation by Jonathon Fowler (jonof@edgenetwk.com)
*/
//-------------------------------------------------------------------------
#include "fx_man.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
int32_t FX_ErrorCode = FX_Ok;
#define FX_SetErrorCode( status ) \
FX_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: FX_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *FX_ErrorString
(
int32_t ErrorNumber
)
{
char *ErrorString;
switch (ErrorNumber)
{
case FX_Warning :
case FX_Error :
ErrorString = FX_ErrorString(FX_ErrorCode);
break;
case FX_Ok :
ErrorString = "Fx ok.";
break;
case FX_ASSVersion :
ErrorString = "Apogee Sound System Version 0 "
"Programmed by Jim Dose\n"
"(c) Copyright 1995 James R. Dose. All Rights Reserved.\n";
break;
default :
ErrorString = "Unknown Fx error code.";
break;
}
return(ErrorString);
}
/*---------------------------------------------------------------------
Function: FX_Init
Selects which sound device to use.
---------------------------------------------------------------------*/
int32_t FX_Init
(
int32_t SoundCard,
int32_t numvoices,
int32_t numchannels,
int32_t samplebits,
uint32_t mixrate
)
{
return(FX_Ok);
}
/*---------------------------------------------------------------------
Function: FX_Shutdown
Terminates use of sound device.
---------------------------------------------------------------------*/
int32_t FX_Shutdown
(
void
)
{
return(FX_Ok);
}
/*---------------------------------------------------------------------
Function: FX_SetCallback
Sets the function to call when a voice is done.
---------------------------------------------------------------------*/
int32_t FX_SetCallBack
(
void(*function)(uint32_t)
)
{
return(FX_Ok);
}
/*---------------------------------------------------------------------
Function: FX_SetVolume
Sets the volume of the current sound device.
---------------------------------------------------------------------*/
void FX_SetVolume
(
int32_t volume
)
{}
/*---------------------------------------------------------------------
Function: FX_SetReverseStereo
Set the orientation of the left and right channels.
---------------------------------------------------------------------*/
void FX_SetReverseStereo
(
int32_t setting
)
{}
/*---------------------------------------------------------------------
Function: FX_GetReverseStereo
Returns the orientation of the left and right channels.
---------------------------------------------------------------------*/
int32_t FX_GetReverseStereo
(
void
)
{
return 0;
}
/*---------------------------------------------------------------------
Function: FX_SetReverb
Sets the reverb level.
---------------------------------------------------------------------*/
void FX_SetReverb
(
int32_t reverb
)
{}
/*---------------------------------------------------------------------
Function: FX_SetReverbDelay
Sets the delay level of reverb to add to mix.
---------------------------------------------------------------------*/
void FX_SetReverbDelay
(
int32_t delay
)
{}
/*---------------------------------------------------------------------
Function: FX_VoiceAvailable
Checks if a voice can be play at the specified priority.
---------------------------------------------------------------------*/
int32_t FX_VoiceAvailable
(
int32_t priority
)
{
return 0;
}
/*---------------------------------------------------------------------
Function: FX_PlayLoopedVOC
Begin playback of sound data with the given volume and priority.
---------------------------------------------------------------------*/
int32_t FX_PlayLoopedVOC
(
char *ptr,
int32_t loopstart,
int32_t loopend,
int32_t pitchoffset,
int32_t vol,
int32_t left,
int32_t right,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: FX_PlayWAV
Begin playback of sound data with the given volume and priority.
---------------------------------------------------------------------*/
int32_t FX_PlayLoopedWAV
(
char *ptr,
int32_t loopstart,
int32_t loopend,
int32_t pitchoffset,
int32_t vol,
int32_t left,
int32_t right,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: FX_PlayVOC3D
Begin playback of sound data at specified angle and distance
from listener.
---------------------------------------------------------------------*/
int32_t FX_PlayVOC3D
(
char *ptr,
int32_t pitchoffset,
int32_t angle,
int32_t distance,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: FX_PlayWAV3D
Begin playback of sound data at specified angle and distance
from listener.
---------------------------------------------------------------------*/
int32_t FX_PlayWAV3D
(
char *ptr,
int32_t pitchoffset,
int32_t angle,
int32_t distance,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: FX_Pan3D
Set the angle and distance from the listener of the voice associated
with the specified handle.
---------------------------------------------------------------------*/
int32_t FX_Pan3D
(
int32_t handle,
int32_t angle,
int32_t distance
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: FX_StopSound
Halts playback of a specific voice
---------------------------------------------------------------------*/
int32_t FX_StopSound
(
int32_t handle
)
{
return(FX_Ok);
}
/*---------------------------------------------------------------------
Function: FX_StopAllSounds
Halts playback of all sounds.
---------------------------------------------------------------------*/
int32_t FX_StopAllSounds
(
void
)
{
return(FX_Ok);
}
void AudioUpdate(void) { }
int32_t FX_PlayLoopedOGG
(
char *ptr,
int32_t loopstart,
int32_t loopend,
int32_t pitchoffset,
int32_t vol,
int32_t left,
int32_t right,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}
int32_t FX_PlayOGG3D
(
char *ptr,
int32_t pitchoffset,
int32_t angle,
int32_t distance,
int32_t priority,
uint32_t callbackval
)
{
return(0);
}

View file

@ -1,494 +0,0 @@
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Dummy AudioLib stub implementation by Jonathon Fowler (jonof@edgenetwk.com)
*/
//-------------------------------------------------------------------------
#include "music.h"
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
int32_t MUSIC_ErrorCode = MUSIC_Ok;
/*---------------------------------------------------------------------
Function: MUSIC_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *MUSIC_ErrorString
(
int32_t ErrorNumber
)
{
char *ErrorString;
switch (ErrorNumber)
{
case MUSIC_Warning :
case MUSIC_Error :
ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode);
break;
case MUSIC_Ok :
ErrorString = "Music ok.";
break;
case MUSIC_ASSVersion :
ErrorString = "Apogee Sound System Version "
"Programmed by Jim Dose\n"
"(c) Copyright 1996 James R. Dose. All Rights Reserved.\n";
break;
case MUSIC_SoundCardError :
break;
case MUSIC_MPU401Error :
ErrorString = "Could not detect MPU-401.";
break;
case MUSIC_InvalidCard :
ErrorString = "Invalid Music device.";
break;
case MUSIC_MidiError :
ErrorString = "Error playing MIDI file.";
break;
case MUSIC_TaskManError :
ErrorString = "TaskMan error.";
break;
case MUSIC_DPMI_Error :
ErrorString = "DPMI Error in MUSIC.";
break;
default :
ErrorString = "Unknown Music error code.";
break;
}
return(ErrorString);
}
/*---------------------------------------------------------------------
Function: MUSIC_Init
Selects which sound device to use.
---------------------------------------------------------------------*/
int32_t MUSIC_Init
(
int32_t SoundCard,
int32_t Address
)
{
int32_t i;
int32_t status;
status = MUSIC_Ok;
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_Shutdown
Terminates use of sound device.
---------------------------------------------------------------------*/
int32_t MUSIC_Shutdown
(
void
)
{
int32_t status;
status = MUSIC_Ok;
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetMaxFMMidiChannel
Sets the maximum MIDI channel that FM cards respond to.
---------------------------------------------------------------------*/
void MUSIC_SetMaxFMMidiChannel
(
int32_t channel
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_SetVolume
Sets the volume of music playback.
---------------------------------------------------------------------*/
void MUSIC_SetVolume
(
int32_t volume
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_SetMidiChannelVolume
Sets the volume of music playback on the specified MIDI channel.
---------------------------------------------------------------------*/
void MUSIC_SetMidiChannelVolume
(
int32_t channel,
int32_t volume
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_ResetMidiChannelVolumes
Sets the volume of music playback on all MIDI channels to full volume.
---------------------------------------------------------------------*/
void MUSIC_ResetMidiChannelVolumes
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_GetVolume
Returns the volume of music playback.
---------------------------------------------------------------------*/
int32_t MUSIC_GetVolume
(
void
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetLoopFlag
Set whether the music will loop or end when it reaches the end of
the song.
---------------------------------------------------------------------*/
void MUSIC_SetLoopFlag
(
int32_t loopflag
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_SongPlaying
Returns whether there is a song playing.
---------------------------------------------------------------------*/
int32_t MUSIC_SongPlaying
(
void
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: MUSIC_Continue
Continues playback of a paused song.
---------------------------------------------------------------------*/
void MUSIC_Continue
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_Pause
Pauses playback of a song.
---------------------------------------------------------------------*/
void MUSIC_Pause
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_StopSong
Stops playback of current song.
---------------------------------------------------------------------*/
int32_t MUSIC_StopSong
(
void
)
{
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_PlaySong
Begins playback of MIDI song.
---------------------------------------------------------------------*/
int32_t MUSIC_PlaySong
(
char *song,
int32_t loopflag
)
{
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetContext
Sets the song context.
---------------------------------------------------------------------*/
void MUSIC_SetContext
(
int32_t context
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_GetContext
Returns the current song context.
---------------------------------------------------------------------*/
int32_t MUSIC_GetContext
(
void
)
{ return 0; }
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTick
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTick
(
uint32_t PositionInTicks
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTime
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTime
(
uint32_t milliseconds
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongPosition
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongPosition
(
int32_t measure,
int32_t beat,
int32_t tick
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongPosition
Returns the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_GetSongPosition
(
songposition *pos
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongLength
Returns the length of the song.
---------------------------------------------------------------------*/
void MUSIC_GetSongLength
(
songposition *pos
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_FadeVolume
Fades music volume from current level to another over a specified
period of time.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeVolume
(
int32_t tovolume,
int32_t milliseconds
)
{
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_FadeActive
Returns whether the fade routine is active.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeActive
(
void
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: MUSIC_StopFade
Stops fading the music.
---------------------------------------------------------------------*/
void MUSIC_StopFade
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_RerouteMidiChannel
Sets callback function to reroute MIDI commands from specified
function.
---------------------------------------------------------------------*/
void MUSIC_RerouteMidiChannel
(
int32_t channel,
int32_t(*function)(int32_t event, int32_t c1, int32_t c2)
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_RegisterTimbreBank
Halts playback of all sounds.
---------------------------------------------------------------------*/
void MUSIC_RegisterTimbreBank
(
char *timbres
)
{}
void MUSIC_Update(void)
{}
void MUSIC_PlayMusic(char *_filename, int32_t loopflag)
{}

View file

@ -1,30 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __DEBUGIO_H
#define __DEBUGIO_H
void DB_SetXY( int32_t x, int32_t y );
void DB_PutChar( char ch );
int32_t DB_PrintString( char *string );
int32_t DB_PrintNum( int32_t number );
int32_t DB_PrintUnsigned( uint32_t number, int32_t radix );
int32_t DB_printf( char *fmt, ... );
#endif

View file

@ -1,280 +0,0 @@
/*
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
*/
#include <stdlib.h>
#include <string.h>
#include "compat.h"
#include "dsl.h"
#include "pragmas.h"
#define _NEED_SDLMIXER 1
#include "sdl_inc.h"
extern int32_t MV_MixPage;
int32_t DSL_ErrorCode = DSL_Ok;
static int32_t mixer_initialized;
static int32_t interrupts_disabled = 0;
static int32_t(*_DSL_CallBackFunc)(int32_t);
static volatile char *_DSL_BufferStart;
static int32_t _DSL_BufferSize;
static int32_t _DSL_SampleRate;
static int32_t _DSL_remainder;
static Uint16 _DSL_format;
static int32_t _DSL_channels;
static Mix_Chunk *blank;
static uint8_t *blank_buf;
/*
possible todo ideas: cache sdl/sdl mixer error messages.
*/
char *DSL_ErrorString(int32_t ErrorNumber)
{
char *ErrorString;
switch (ErrorNumber)
{
case DSL_Warning:
case DSL_Error:
ErrorString = DSL_ErrorString(DSL_ErrorCode);
break;
case DSL_Ok:
ErrorString = "SDL Driver ok.";
break;
case DSL_SDLInitFailure:
ErrorString = "SDL Audio initialization failed.";
break;
case DSL_MixerActive:
ErrorString = "SDL Mixer already initialized.";
break;
case DSL_MixerInitFailure:
ErrorString = "SDL Mixer initialization failed.";
break;
default:
ErrorString = "Unknown SDL Driver error.";
break;
}
return ErrorString;
}
static void DSL_SetErrorCode(int32_t ErrorCode)
{
DSL_ErrorCode = ErrorCode;
}
int32_t DSL_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize)
{
/* FIXME: Do I need an SDL_mixer version check
* like that in sdlmusic.h here, too???
*/
UNREFERENCED_PARAMETER(soundcard);
UNREFERENCED_PARAMETER(buffersize);
DSL_SetErrorCode(DSL_Ok);
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
DSL_SetErrorCode(DSL_SDLInitFailure);
return DSL_Error;
}
_DSL_channels = numchannels;
_DSL_SampleRate = mixrate;
_DSL_format = (samplebits == 16) ? AUDIO_S16SYS : AUDIO_U8;
return DSL_Ok;
}
void DSL_Shutdown(void)
{
DSL_StopPlayback();
}
static void mixer_callback(int32_t chan, void *stream, int32_t len, void *udata)
{
Uint8 *stptr;
Uint8 *fxptr;
int32_t copysize;
UNREFERENCED_PARAMETER(chan);
UNREFERENCED_PARAMETER(udata);
/* len should equal _DSL_BufferSize, else this is screwed up */
stptr = (Uint8 *)stream;
if (_DSL_remainder > 0)
{
copysize = min(len, _DSL_remainder);
fxptr = (Uint8 *)(&_DSL_BufferStart[MV_MixPage *
_DSL_BufferSize]);
Bmemcpy(stptr, fxptr+(_DSL_BufferSize-_DSL_remainder), copysize);
len -= copysize;
_DSL_remainder -= copysize;
stptr += copysize;
}
while (len > 0)
{
/* new buffer */
_DSL_CallBackFunc(0);
fxptr = (Uint8 *)(&_DSL_BufferStart[MV_MixPage *
_DSL_BufferSize]);
copysize = min(len, _DSL_BufferSize);
Bmemcpy(stptr, fxptr, copysize);
len -= copysize;
stptr += copysize;
}
_DSL_remainder = len;
}
//int32_t DSL_BeginBufferedPlayback(char *BufferStart,
// int32_t BufferSize, int32_t NumDivisions, uint32_t SampleRate,
// int32_t MixMode, void(*CallBackFunc)(void))
int32_t DSL_BeginBufferedPlayback(char *BufferStart, int32_t(*CallBackFunc)(int32_t), int32_t BufferSize, int32_t NumDivisions)
{
int32_t chunksize;
if (mixer_initialized)
{
DSL_SetErrorCode(DSL_MixerActive);
return DSL_Error;
}
_DSL_CallBackFunc = CallBackFunc;
_DSL_BufferStart = BufferStart;
_DSL_BufferSize = (BufferSize / NumDivisions);
_DSL_remainder = 0;
/*
23ms is typically ideal (11025,22050,44100)
46ms isn't bad
*/
chunksize = 512;
if (_DSL_SampleRate >= 16000) chunksize *= 2;
if (_DSL_SampleRate >= 32000) chunksize *= 2;
if (Mix_OpenAudio(_DSL_SampleRate, _DSL_format, _DSL_channels, chunksize) < 0)
{
DSL_SetErrorCode(DSL_MixerInitFailure);
return DSL_Error;
}
/*
Mix_SetPostMix(mixer_callback, NULL);
*/
/* have to use a channel because postmix will overwrite the music... */
Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
/* create a dummy sample just to allocate that channel */
blank_buf = (Uint8 *)malloc(4096);
memset(blank_buf, 0, 4096);
blank = Mix_QuickLoad_RAW(blank_buf, 4096);
Mix_PlayChannel(0, blank, -1);
mixer_initialized = 1;
return DSL_Ok;
}
void DSL_StopPlayback(void)
{
if (mixer_initialized)
{
Mix_HaltChannel(0);
}
if (blank != NULL)
{
Mix_FreeChunk(blank);
}
blank = NULL;
if (blank_buf != NULL)
{
free(blank_buf);
}
blank_buf = NULL;
if (mixer_initialized)
{
Mix_CloseAudio();
}
mixer_initialized = 0;
}
uint32_t DSL_GetPlaybackRate(void)
{
return _DSL_SampleRate;
}
int32_t DisableInterrupts(void)
{
if (interrupts_disabled++)
return 0;
// interrupts_disabled = 1;
SDL_LockAudio();
return(0);
}
int32_t RestoreInterrupts(int32_t flags)
{
UNREFERENCED_PARAMETER(flags);
if (--interrupts_disabled)
return 0;
// interrupts_disabled = 0;
SDL_UnlockAudio();
return(0);
}

View file

@ -1,52 +0,0 @@
/*
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
*/
#ifndef AUDIOLIB__DSL_H
#define AUDIOLIB__DSL_H
#define MONO_8BIT 0
#define STEREO 1
#define SIXTEEN_BIT 2
enum DSL_ERRORS
{
DSL_Warning = -2,
DSL_Error = -1,
DSL_Ok = 0,
DSL_SDLInitFailure,
DSL_MixerActive,
DSL_MixerInitFailure
};
extern int32_t DSL_ErrorCode;
char *DSL_ErrorString( int32_t ErrorNumber );
int32_t DisableInterrupts(void); // simulated using critical sections
int32_t RestoreInterrupts(int32_t);
int32_t DSL_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize);
void DSL_StopPlayback( void );
uint32_t DSL_GetPlaybackRate( void );
int32_t DSL_BeginBufferedPlayback(char *BufferStart, int32_t (*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions);
void DSL_Shutdown( void );
#endif

View file

@ -1,639 +0,0 @@
/*
* DirectSound output code for MultiVoc
* by Jonathon Fowler (jonof@edgenetwk.com)
*/
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#include <dsound.h>
#include "dsoundout.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include <stdio.h>
#include <string.h>
#ifdef USE_OPENAL
#include "openal.h"
#endif
#include "compat.h"
#include "winlayer.h"
#if defined(_MSC_VER)
#include <malloc.h>
#endif
#ifndef RENDERTYPEWIN
#error The DirectSound output module for AudioLib only works with the Windows interface.
#endif
static CRITICAL_SECTION mutex;
static int32_t _DSOUND_CriticalSectionAlloced = FALSE;
static HANDLE isrthread = NULL;
static HANDLE isrfinish = NULL;
static HMODULE hDSoundDLL = NULL;
static LPDIRECTSOUND lpDS = NULL;
static LPDIRECTSOUNDBUFFER lpDSBPrimary = NULL;
static LPDIRECTSOUNDBUFFER lpDSBSecondary = NULL;
static LPDIRECTSOUNDNOTIFY lpDSNotify = NULL;
static HANDLE *hPosNotify = NULL;
static int32_t(*_DSOUND_CallBack)(int32_t) = NULL;
static int32_t _DSOUND_BufferLength = 0;
static int32_t _DSOUND_NumBuffers = 0;
static char *_DSOUND_MixBuffer = NULL;
static int32_t DSOUND_Installed = FALSE;
int32_t DSOUND_ErrorCode = DSOUND_Ok;
#define DSOUND_SetErrorCode( status ) \
DSOUND_ErrorCode = ( status );
/*
* DisableInterrupts
* Enter the critical section.
*/
int32_t DisableInterrupts(void)
{
if (!_DSOUND_CriticalSectionAlloced) return -1;
EnterCriticalSection(&mutex);
return 0;
}
/*
* RestoreInterrupts
* Leave the critical section.
*/
int32_t RestoreInterrupts(int32_t a)
{
if (!_DSOUND_CriticalSectionAlloced) return -1;
LeaveCriticalSection(&mutex);
return 0;
a=a;
}
/*
* DSOUND_ErrorString
* Returns a description of an error code.
*/
char *DSOUND_ErrorString(int32_t errorcode)
{
switch (errorcode)
{
case DSOUND_Warning:
case DSOUND_Error:
return DSOUND_ErrorString(DSOUND_ErrorCode);
case DSOUND_Ok:
return "DirectSound ok.";
case DSOUND_NoDLL:
return "Failed loading DSOUND.DLL.";
case DSOUND_NoDirectSoundCreate:
return "Failed getting DirectSoundCreate entry point.";
case DSOUND_FailedDSC:
return "DirectSoundCreate failed.";
case DSOUND_FailedSetCoopLevel:
return "Failed setting cooperative level.";
case DSOUND_FailedCreatePrimary:
return "Failed creating primary buffer.";
case DSOUND_FailedSetFormat:
return "Failed setting primary buffer format.";
case DSOUND_FailedCreateSecondary:
return "Failed creating secondary buffer.";
case DSOUND_FailedCreateNotifyEvent:
return "Failed creating notification event object.";
case DSOUND_FailedQueryNotify:
return "Failed querying notification interface.";
case DSOUND_FailedSetNotify:
return "Failed setting notification positions.";
case DSOUND_FailedCreateFinishEvent:
return "Failed creating finish event object.";
case DSOUND_FailedCreateThread:
return "Failed creating playback thread.";
case DSOUND_FailedPlaySecondary:
return "Failed playing secondary buffer.";
case DSOUND_FailedGetExitCode:
return "GetExitCodeThread failed.";
default:
return "Unknown DirectSound error code.";
}
}
/*
* DSOUND_Init
* Initializes the DirectSound objects.
*/
int32_t DSOUND_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize)
{
HRESULT(WINAPI *aDirectSoundCreate)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
HRESULT hr;
DSBUFFERDESC dsbuf;
WAVEFORMATEX wfex;
DSBPOSITIONNOTIFY posn;
UNREFERENCED_PARAMETER(soundcard);
if (DSOUND_Installed)
{
DSOUND_Shutdown();
}
initprintf("Initializing DirectSound...\n");
if (!_DSOUND_CriticalSectionAlloced)
{
// initialize the critical section object we'll use to
// simulate (dis|en)abling interrupts
InitializeCriticalSection(&mutex);
_DSOUND_CriticalSectionAlloced = TRUE;
}
// initprintf(" - Loading DSOUND.DLL\n");
hDSoundDLL = LoadLibrary("DSOUND.DLL");
if (!hDSoundDLL)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_NoDLL);
return DSOUND_Error;
}
aDirectSoundCreate = (void *)GetProcAddress(hDSoundDLL, "DirectSoundCreate");
if (!aDirectSoundCreate)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_NoDirectSoundCreate);
return DSOUND_Error;
}
// initprintf(" - Creating DirectSound object\n");
hr = aDirectSoundCreate(NULL, &lpDS, NULL);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedDSC);
return DSOUND_Error;
}
hr = IDirectSound_SetCooperativeLevel(lpDS, (HWND)win_gethwnd(), DSSCL_EXCLUSIVE);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetCoopLevel);
return DSOUND_Error;
}
// initprintf(" - Creating primary buffer\n");
ZeroMemory(&dsbuf, sizeof(dsbuf));
dsbuf.dwSize = sizeof(DSBUFFERDESC);
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBPrimary, NULL);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedCreatePrimary);
return DSOUND_Error;
}
/* initprintf(" - Setting primary buffer format\n"
" Channels: %d\n"
" Sample rate: %dHz\n"
" Sample size: %d bits\n",
numchannels, mixrate, samplebits); */
initprintf(" - Primary buffer format: %d ch, %dHz, %d bits\n",
numchannels, mixrate, samplebits);
ZeroMemory(&wfex, sizeof(wfex));
wfex.wFormatTag = WAVE_FORMAT_PCM;
wfex.nChannels = numchannels;
wfex.nSamplesPerSec = mixrate;
wfex.wBitsPerSample = samplebits;
wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels;
wfex.nAvgBytesPerSec = wfex.nBlockAlign * wfex.nSamplesPerSec;
hr = IDirectSoundBuffer_SetFormat(lpDSBPrimary, &wfex);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetFormat);
return DSOUND_Error;
}
initprintf(" - Creating secondary buffer\n");
ZeroMemory(&dsbuf, sizeof(dsbuf));
dsbuf.dwSize = sizeof(DSBUFFERDESC);
dsbuf.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
dsbuf.dwBufferBytes = buffersize;
dsbuf.lpwfxFormat = &wfex;
hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBSecondary, NULL);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedCreateSecondary);
return DSOUND_Error;
}
hr = IDirectSoundBuffer_QueryInterface(lpDSBSecondary, &IID_IDirectSoundNotify, (LPVOID *)&lpDSNotify);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedQueryNotify);
return DSOUND_Error;
}
hPosNotify = (HANDLE *)malloc(sizeof(HANDLE));
if (!hPosNotify)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
hPosNotify[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hPosNotify)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedCreateNotifyEvent);
return DSOUND_Error;
}
_DSOUND_BufferLength = 0;
_DSOUND_NumBuffers = 1;
posn.dwOffset = 0;
posn.hEventNotify = hPosNotify[0];
hr = IDirectSoundNotify_SetNotificationPositions(lpDSNotify, 1, &posn);
if (hr != DS_OK)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
DSOUND_Installed = TRUE;
DSOUND_SetErrorCode(DSOUND_Ok);
return DSOUND_Ok;
}
/*
* DSOUND_Shutdown
* Shuts down DirectSound and it's associates.
*/
int32_t DSOUND_Shutdown(void)
{
int32_t i;
if (DSOUND_Installed) initprintf("Uninitializing DirectSound...\n");
DSOUND_Installed = FALSE;
DSOUND_StopPlayback();
if (lpDSNotify)
{
IDirectSoundNotify_Release(lpDSNotify);
lpDSNotify = NULL;
}
if (hPosNotify)
{
for (i=0; i<_DSOUND_NumBuffers; i++)
{
if (hPosNotify[i]) CloseHandle(hPosNotify[i]);
}
free(hPosNotify);
hPosNotify = NULL;
}
if (lpDSBSecondary)
{
// initprintf(" - Releasing secondary buffer\n");
IDirectSoundBuffer_Stop(lpDSBSecondary);
IDirectSoundBuffer_Release(lpDSBSecondary);
lpDSBSecondary = NULL;
}
if (lpDSBPrimary)
{
// initprintf(" - Releasing primary buffer\n");
IDirectSoundBuffer_Release(lpDSBPrimary);
lpDSBPrimary = NULL;
}
if (lpDS)
{
// initprintf(" - Releasing DirectSound object\n");
IDirectSound_Release(lpDS);
lpDS = NULL;
}
if (hDSoundDLL)
{
// initprintf(" - Unloading DSOUND.DLL\n");
FreeLibrary(hDSoundDLL);
hDSoundDLL = NULL;
}
DSOUND_SetErrorCode(DSOUND_Ok);
return DSOUND_Ok;
}
/*
* DSOUND_SetMixMode
* Bit of filler for the future.
*/
int32_t DSOUND_SetMixMode(int32_t mode)
{
return mode;
}
//#define DEBUGAUDIO
#ifdef DEBUGAUDIO
#include <sys/stat.h>
#endif
static DWORD WINAPI isr(LPVOID parm)
{
HANDLE *handles;
HRESULT hr;
int32_t rv;
#ifdef DEBUGAUDIO
int32_t h;
#endif
int32_t p;
LPVOID lockptr; DWORD lockbytes;
LPVOID lockptr2; DWORD lockbytes2;
UNREFERENCED_PARAMETER(parm);
handles = (HANDLE *)malloc(sizeof(HANDLE)*(1+_DSOUND_NumBuffers));
if (!handles) return 1;
handles[0] = isrfinish;
for (p=0; p<_DSOUND_NumBuffers; p++)
handles[p+1] = hPosNotify[p];
#ifdef DEBUGAUDIO
h = creat("audio.raw",S_IREAD|S_IWRITE);
#endif
while (1)
{
#ifdef USE_OPENAL
AL_Update();
#endif
rv = WaitForMultipleObjects(1+_DSOUND_NumBuffers, handles, FALSE, INFINITE);
if (!(rv >= WAIT_OBJECT_0 && rv <= WAIT_OBJECT_0+1+_DSOUND_NumBuffers)) return -1;
if (rv == WAIT_OBJECT_0)
{
// we've been asked to finish up
break;
}
// otherwise we just service the interrupt
if (_DSOUND_CallBack)
{
DisableInterrupts();
p = _DSOUND_CallBack(rv-WAIT_OBJECT_0-1);
#ifdef DEBUGAUDIO
write(h, _DSOUND_MixBuffer + p*_DSOUND_BufferLength, _DSOUND_BufferLength);
#endif
hr = IDirectSoundBuffer_Lock(lpDSBSecondary, p*_DSOUND_BufferLength, _DSOUND_BufferLength,
&lockptr, &lockbytes, &lockptr2, &lockbytes2, 0);
if (hr == DSERR_BUFFERLOST)
{
hr = IDirectSoundBuffer_Restore(lpDSBSecondary);
}
if (hr == DS_OK)
{
/*
#define copybuf(S,D,c) \
({ void *__S=(S), *__D=(D); int32_t __c=(c); \
__asm__ __volatile__ ("rep; movsl" \
: "+S" (__S), "+D" (__D), "+c" (__c) : : "memory", "cc"); \
0; })
*/
//copybuf(_DSOUND_MixBuffer + p * _DSOUND_BufferLength, lockptr, _DSOUND_BufferLength >> 2);
Bmemcpy(lockptr, _DSOUND_MixBuffer + p * _DSOUND_BufferLength, _DSOUND_BufferLength);
IDirectSoundBuffer_Unlock(lpDSBSecondary, lockptr, lockbytes, lockptr2, lockbytes2);
}
RestoreInterrupts(0);
}
}
#ifdef DEBUGAUDIO
close(h);
#endif
return 0;
}
/*
* DSOUND_BeginBufferedPlayback
* Spins off a thread that behaves somewhat like the SoundBlaster DMA ISR did.
*/
int32_t DSOUND_BeginBufferedPlayback(char *BufferStart, int32_t(*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions)
{
DWORD threadid;
HRESULT hr;
DSBPOSITIONNOTIFY *posns;
int32_t i;
_DSOUND_CallBack = CallBackFunc;
_DSOUND_MixBuffer = BufferStart;
if (!lpDSBSecondary) return DSOUND_Error;
if (isrthread)
{
DSOUND_StopPlayback();
}
isrfinish = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!isrfinish)
{
DSOUND_SetErrorCode(DSOUND_FailedCreateFinishEvent);
return DSOUND_Error;
}
isrthread = CreateThread(NULL, 0, isr, NULL, CREATE_SUSPENDED, &threadid);
if (!isrthread)
{
DSOUND_SetErrorCode(DSOUND_FailedCreateThread);
return DSOUND_Error;
}
hPosNotify = (HANDLE *)malloc(sizeof(HANDLE)*numdivisions);
if (!hPosNotify)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
memset(hPosNotify, 0, sizeof(HANDLE)*numdivisions);
for (i=0; i<numdivisions; i++)
{
hPosNotify[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!hPosNotify[i])
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
}
posns = (LPDSBPOSITIONNOTIFY)malloc(sizeof(DSBPOSITIONNOTIFY)*numdivisions);
if (!posns)
{
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
_DSOUND_BufferLength = buffersize/numdivisions;
_DSOUND_NumBuffers = numdivisions;
for (i=0; i<numdivisions; i++)
{
posns[i].dwOffset = i*_DSOUND_BufferLength;
posns[i].hEventNotify = hPosNotify[i];
}
hr = IDirectSoundNotify_SetNotificationPositions(lpDSNotify, numdivisions, posns);
if (hr != DS_OK)
{
free(posns);
DSOUND_Shutdown();
DSOUND_SetErrorCode(DSOUND_FailedSetNotify);
return DSOUND_Error;
}
free(posns);
SetThreadPriority(isrthread, THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(isrthread);
hr = IDirectSoundBuffer_Play(lpDSBSecondary, 0, 0, DSBPLAY_LOOPING);
if (hr != DS_OK)
{
DSOUND_SetErrorCode(DSOUND_FailedPlaySecondary);
return DSOUND_Error;
}
return DSOUND_Ok;
}
/*
* DSOUND_StopPlayback
* Halts the playback thread.
*/
int32_t DSOUND_StopPlayback(void)
{
// DWORD exitcode;
int32_t i;
if (isrthread)
{
SetEvent(isrfinish);
// initprintf("DirectSound: Waiting for sound thread to exit\n");
// if (WaitForSingleObject(isrthread, 300) == WAIT_OBJECT_0)
// initprintf("DirectSound: Sound thread has exited\n");
// else
// initprintf("DirectSound: Sound thread failed to exit!\n");
if (WaitForSingleObject(isrthread, 300) != WAIT_OBJECT_0)
initprintf("DirectSound: Sound thread failed to exit!\n");
/*
while (1) {
if (!GetExitCodeThread(isrthread, &exitcode)) {
DSOUND_SetErrorCode(DSOUND_FailedGetExitCode);
return DSOUND_Warning;
}
if (exitcode != STILL_ACTIVE) break;
}*/
CloseHandle(isrthread);
isrthread = NULL;
}
if (isrfinish)
{
CloseHandle(isrfinish);
isrfinish = NULL;
}
if (lpDSBSecondary)
{
IDirectSoundBuffer_Stop(lpDSBSecondary);
}
if (hPosNotify)
{
for (i=0; i<_DSOUND_NumBuffers; i++)
{
if (hPosNotify[i]) CloseHandle(hPosNotify[i]);
}
free(hPosNotify);
hPosNotify = NULL;
}
return DSOUND_Ok;
}

View file

@ -1,64 +0,0 @@
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#ifndef __dsoundout_h__
#define __dsoundout_h__
#include "compat.h"
enum DSOUND_ERRORS {
DSOUND_Warning = -2,
DSOUND_Error = -1,
DSOUND_Ok = 0,
DSOUND_NoDLL,
DSOUND_NoDirectSoundCreate,
DSOUND_FailedDSC,
DSOUND_FailedSetCoopLevel,
DSOUND_FailedCreatePrimary,
DSOUND_FailedSetFormat,
DSOUND_FailedCreateSecondary,
DSOUND_FailedCreateNotifyEvent,
DSOUND_FailedQueryNotify,
DSOUND_FailedSetNotify,
DSOUND_FailedCreateFinishEvent,
DSOUND_FailedCreateThread,
DSOUND_FailedPlaySecondary,
DSOUND_FailedGetExitCode
};
extern int32_t DSOUND_ErrorCode;
char *DSOUND_ErrorString(int32_t);
int32_t DisableInterrupts(void); // simulated using critical sections
int32_t RestoreInterrupts(int32_t);
int32_t DSOUND_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize);
int32_t DSOUND_Shutdown(void);
int32_t DSOUND_SetMixMode(int32_t mode);
int32_t DSOUND_BeginBufferedPlayback(char *BufferStart, int32_t (*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions);
int32_t DSOUND_StopPlayback(void);
#endif // __dsoundout_h__

File diff suppressed because it is too large Load diff

View file

@ -1,143 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: FX_MAN.H
author: James R. Dose
date: March 17, 1994
Public header for FX_MAN.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __FX_MAN_H
#define __FX_MAN_H
#include "compat.h"
typedef struct
{
int32_t MaxVoices;
int32_t MaxSampleBits;
int32_t MaxChannels;
} fx_device;
#define MonoFx 1
#define StereoFx 2
typedef struct
{
uint32_t Address;
uint32_t Type;
uint32_t Interrupt;
uint32_t Dma8;
uint32_t Dma16;
uint32_t Midi;
uint32_t Emu;
} fx_blaster_config;
enum FX_ERRORS
{
FX_Warning = -2,
FX_Error = -1,
FX_Ok = 0,
FX_ASSVersion,
FX_BlasterError,
FX_SoundCardError,
FX_InvalidCard,
FX_MultiVocError,
FX_DPMI_Error
};
/*
enum fx_BLASTER_Types
{
fx_SB = 1,
fx_SBPro = 2,
fx_SB20 = 3,
fx_SBPro2 = 4,
fx_SB16 = 6
};
*/
char *FX_ErrorString( int32_t ErrorNumber );
//int32_t FX_SetupCard( int32_t SoundCard, fx_device *device );
//int32_t FX_GetBlasterSettings( fx_blaster_config *blaster );
//int32_t FX_SetupSoundBlaster( fx_blaster_config blaster, int32_t *MaxVoices, int32_t *MaxSampleBits, int32_t *MaxChannels );
int32_t FX_Init( int32_t SoundCard, int32_t numvoices, int32_t numchannels, int32_t samplebits, uint32_t mixrate );
int32_t FX_Shutdown( void );
int32_t FX_SetCallBack( void ( *function )( uint32_t ) );
void FX_SetVolume( int32_t volume );
int32_t FX_GetVolume( void );
void FX_SetReverseStereo( int32_t setting );
int32_t FX_GetReverseStereo( void );
void FX_SetReverb( int32_t reverb );
void FX_SetFastReverb( int32_t reverb );
int32_t FX_GetMaxReverbDelay( void );
int32_t FX_GetReverbDelay( void );
void FX_SetReverbDelay( int32_t delay );
int32_t FX_VoiceAvailable( int32_t priority );
int32_t FX_EndLooping( int32_t handle );
int32_t FX_SetPan( int32_t handle, int32_t vol, int32_t left, int32_t right );
int32_t FX_SetPitch( int32_t handle, int32_t pitchoffset );
int32_t FX_SetFrequency( int32_t handle, int32_t frequency );
int32_t FX_PlayVOC( char *ptr, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
int32_t priority, uint32_t callbackval );
int32_t FX_PlayLoopedVOC( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t FX_PlayWAV( char *ptr, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
int32_t priority, uint32_t callbackval );
int32_t FX_PlayLoopedWAV( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t FX_PlayLoopedOGG( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t FX_PlayOGG3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t FX_PlayVOC3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t FX_PlayWAV3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t FX_PlayRaw( char *ptr, uint32_t length, uint32_t rate,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t FX_PlayLoopedRaw( char *ptr, uint32_t length, char *loopstart,
char *loopend, uint32_t rate, int32_t pitchoffset, int32_t vol, int32_t left,
int32_t right, int32_t priority, uint32_t callbackval );
int32_t FX_Pan3D( int32_t handle, int32_t angle, int32_t distance );
int32_t FX_SoundActive( int32_t handle );
int32_t FX_SoundsPlaying( void );
int32_t FX_StopSound( int32_t handle );
int32_t FX_StopAllSounds( void );
int32_t FX_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ),
int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
int32_t priority, uint32_t callbackval );
int32_t FX_StartRecording( int32_t MixRate, void ( *function )( char *ptr, int32_t length ) );
void FX_StopRecord( void );
void FX_Update(void);
#endif

View file

@ -1,50 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**********************************************************************
module: INTERRUP.H
author: James R. Dose
date: March 31, 1994
Inline functions for disabling and restoring the interrupt flag.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __INTERRUPT_H
#define __INTERRUPT_H
uint32_t DisableInterrupts( void );
void RestoreInterrupts( uint32_t flags );
#ifdef PLAT_DOS
#pragma aux DisableInterrupts = \
"pushfd", \
"pop eax", \
"cli" \
modify [ eax ];
#pragma aux RestoreInterrupts = \
"push eax", \
"popfd" \
parm [ eax ];
#endif
#endif

View file

@ -1,119 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
#ifndef __linklist_h
#define __linklist_h
#ifdef __cplusplus
extern "C" {
#endif
#define NewNode(type) ((type*)SafeMalloc(sizeof(type)))
#define LL_CreateNewLinkedList(rootnode,type,next,prev) \
{ \
(rootnode) = NewNode(type); \
(rootnode)->prev = (rootnode); \
(rootnode)->next = (rootnode); \
}
#define LL_AddNode(rootnode, newnode, next, prev) \
{ \
(newnode)->next = (rootnode); \
(newnode)->prev = (rootnode)->prev; \
(rootnode)->prev->next = (newnode); \
(rootnode)->prev = (newnode); \
}
#define LL_TransferList(oldroot,newroot,next,prev) \
{ \
if ((oldroot)->prev != (oldroot)) \
{ \
(oldroot)->prev->next = (newroot); \
(oldroot)->next->prev = (newroot)->prev; \
(newroot)->prev->next = (oldroot)->next; \
(newroot)->prev = (oldroot)->prev; \
(oldroot)->next = (oldroot); \
(oldroot)->prev = (oldroot); \
} \
}
#define LL_ReverseList(root,type,next,prev) \
{ \
type *newend,*trav,*tprev; \
\
newend = (root)->next; \
for(trav = (root)->prev; trav != newend; trav = tprev) \
{ \
tprev = trav->prev; \
LL_MoveNode(trav,newend,next,prev); \
} \
}
#define LL_RemoveNode(node,next,prev) \
{ \
(node)->prev->next = (node)->next; \
(node)->next->prev = (node)->prev; \
(node)->next = (node); \
(node)->prev = (node); \
}
#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \
{ \
type *hoya; \
\
hoya = (rootnode)->next; \
while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \
{ \
hoya = hoya->next; \
} \
LL_AddNode(hoya,(insertnode),next,prev); \
}
#define LL_MoveNode(node,newroot,next,prev) \
{ \
LL_RemoveNode((node),next,prev); \
LL_AddNode((newroot),(node),next,prev); \
}
#define LL_ListEmpty(list,next,prev) \
( \
((list)->next == (list)) && \
((list)->prev == (list)) \
)
#define LL_Free(list) SafeFree(list)
#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list)
#define LL_New LL_CreateNewLinkedList
#define LL_Remove LL_RemoveNode
#define LL_Add LL_AddNode
#define LL_Empty LL_ListEmpty
#define LL_Move LL_MoveNode
#ifdef __cplusplus
};
#endif
#endif

View file

@ -1,103 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: LL_MAN.C
author: James R. Dose
date: January 1, 1994
Linked list management routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stddef.h>
#include "ll_man.h"
#define OFFSET( structure, offset ) \
( *( ( char ** )&( structure )[ offset ] ) )
/**********************************************************************
Memory locked functions:
**********************************************************************/
void LL_AddNode
(
char *item,
char **head,
char **tail,
int32_t next,
int32_t prev
)
{
OFFSET(item, prev) = NULL;
OFFSET(item, next) = *head;
if (*head)
{
OFFSET(*head, prev) = item;
}
else
{
*tail = item;
}
*head = item;
}
void LL_RemoveNode
(
char *item,
char **head,
char **tail,
int32_t next,
int32_t prev
)
{
if (OFFSET(item, prev) == NULL)
{
*head = OFFSET(item, next);
}
else
{
OFFSET(OFFSET(item, prev), next) = OFFSET(item, next);
}
if (OFFSET(item, next) == NULL)
{
*tail = OFFSET(item, prev);
}
else
{
OFFSET(OFFSET(item, next), prev) = OFFSET(item, prev);
}
OFFSET(item, next) = NULL;
OFFSET(item, prev) = NULL;
}

View file

@ -1,77 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: LL_MAN.H
author: James R. Dose
date: February 4, 1994
Public header for LL_MAN.C. Linked list management routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __LL_MAN_H
#define __LL_MAN_H
#include "compat.h"
enum LL_Errors
{
LL_Warning = -2,
LL_Error = -1,
LL_Ok = 0
};
typedef struct list
{
void *start;
void *end;
} list;
void LL_AddNode( char *node, char **head, char **tail, int32_t next, int32_t prev );
void LL_RemoveNode( char *node, char **head, char **tail, int32_t next, int32_t prev );
#define LL_AddToHead( type, listhead, node ) \
LL_AddNode( ( char * )( node ), \
( char ** )&( ( listhead )->start ), \
( char ** )&( ( listhead )->end ), \
( int32_t )&( ( type * ) 0 )->next, \
( int32_t )&( ( type * ) 0 )->prev )
#define LL_AddToTail( type, listhead, node ) \
LL_AddNode( ( char * )( node ), \
( char ** )&( ( listhead )->end ), \
( char ** )&( ( listhead )->start ), \
( int32_t )&( ( type * ) 0 )->prev, \
( int32_t )&( ( type * ) 0 )->next )
#define LL_Remove( type, listhead, node ) \
LL_RemoveNode( ( char * )( node ), \
( char ** )&( ( listhead )->start ), \
( char ** )&( ( listhead )->end ), \
( int32_t )&( ( type * ) 0 )->next, \
( int32_t )&( ( type * ) 0 )->prev )
#define LL_NextNode( node ) ( ( node )->next )
#define LL_PreviousNode( node ) ( ( node )->prev )
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,100 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: MIDI.H
author: James R. Dose
date: May 25, 1994
Public header for MIDI.C. Midi song file playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MIDI_H
#define __MIDI_H
enum MIDI_Errors
{
MIDI_Warning = -2,
MIDI_Error = -1,
MIDI_Ok = 0,
MIDI_NullMidiModule,
MIDI_InvalidMidiFile,
MIDI_UnknownMidiFormat,
MIDI_NoTracks,
MIDI_InvalidTrack,
MIDI_NoMemory,
MIDI_DPMI_Error
};
#define MIDI_PASS_THROUGH 1
#define MIDI_DONT_PLAY 0
#define MIDI_MaxVolume 255
extern char MIDI_PatchMap[ 128 ];
typedef struct
{
void ( *NoteOff )( int32_t channel, int32_t key, int32_t velocity );
void ( *NoteOn )( int32_t channel, int32_t key, int32_t velocity );
void ( *PolyAftertouch )( int32_t channel, int32_t key, int32_t pressure );
void ( *ControlChange )( int32_t channel, int32_t number, int32_t value );
void ( *ProgramChange )( int32_t channel, int32_t program );
void ( *ChannelAftertouch )( int32_t channel, int32_t pressure );
void ( *PitchBend )( int32_t channel, int32_t lsb, int32_t msb );
void ( *ReleasePatches )( void );
void ( *LoadPatch )( int32_t number );
void ( *SetVolume )( int32_t volume );
int32_t ( *GetVolume )( void );
void ( *FinishBuffer )( void );
} midifuncs;
void MIDI_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) );
int32_t MIDI_AllNotesOff( void );
void MIDI_SetUserChannelVolume( int32_t channel, int32_t volume );
void MIDI_ResetUserChannelVolume( void );
int32_t MIDI_Reset( void );
int32_t MIDI_SetVolume( int32_t volume );
int32_t MIDI_GetVolume( void );
void MIDI_SetMidiFuncs( midifuncs *funcs );
void MIDI_SetContext( int32_t context );
int32_t MIDI_GetContext( void );
void MIDI_SetLoopFlag( int32_t loopflag );
void MIDI_ContinueSong( void );
void MIDI_PauseSong( void );
int32_t MIDI_SongPlaying( void );
void MIDI_StopSong( void );
int32_t MIDI_PlaySong( char *song, int32_t loopflag );
void MIDI_SetTempo( int32_t tempo );
int32_t MIDI_GetTempo( void );
void MIDI_SetSongTick( uint32_t PositionInTicks );
void MIDI_SetSongTime( uint32_t milliseconds );
void MIDI_SetSongPosition( int32_t measure, int32_t beat, int32_t tick );
void MIDI_GetSongPosition( songposition *pos );
void MIDI_GetSongLength( songposition *pos );
void MIDI_LoadTimbres( void );
void MIDI_UpdateMusic(void);
void MIDI_SetDivision( int32_t division );
#endif

View file

@ -1,496 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: MPU401.C
author: James R. Dose
date: January 1, 1994
Low level routines to support sending of MIDI data to MPU401
compatible MIDI interfaces.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include "mpu401.h"
#include "compat.h"
#include "osd.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
static HMIDISTRM hmido = (HMIDISTRM)-1;
static MIDIOUTCAPS midicaps;
static DWORD mididevice = -1;
typedef struct
{
int32_t time;
int32_t stream;
int32_t event;
}
MIDIEVENTHEAD;
#define PAD(x) ((((x)+3)&(~3)))
#define BUFFERLEN (32*4*4)
#define NUMBUFFERS 8
static char eventbuf[NUMBUFFERS][BUFFERLEN];
static int32_t eventcnt[NUMBUFFERS];
static MIDIHDR bufferheaders[NUMBUFFERS];
int32_t _MPU_CurrentBuffer = 0;
int32_t _MPU_BuffersWaiting = 0;
extern uint32_t _MIDI_GlobalPositionInTicks;
uint32_t _MPU_LastEvent=0;
#define MIDI_NOTE_OFF 0x80
#define MIDI_NOTE_ON 0x90
#define MIDI_POLY_AFTER_TCH 0xA0
#define MIDI_CONTROL_CHANGE 0xB0
#define MIDI_PROGRAM_CHANGE 0xC0
#define MIDI_AFTER_TOUCH 0xD0
#define MIDI_PITCH_BEND 0xE0
#define MIDI_META_EVENT 0xFF
#define MIDI_END_OF_TRACK 0x2F
#define MIDI_TEMPO_CHANGE 0x51
#define MIDI_MONO_MODE_ON 0x7E
#define MIDI_ALL_NOTES_OFF 0x7B
/**********************************************************************
Memory locked functions:
**********************************************************************/
void MPU_FinishBuffer(int32_t buffer)
{
if (!eventcnt[buffer]) return;
ZeroMemory(&bufferheaders[buffer], sizeof(MIDIHDR));
bufferheaders[buffer].lpData = eventbuf[buffer];
bufferheaders[buffer].dwBufferLength =
bufferheaders[buffer].dwBytesRecorded = eventcnt[buffer];
midiOutPrepareHeader((HMIDIOUT)hmido, &bufferheaders[buffer], sizeof(MIDIHDR));
midiStreamOut(hmido, &bufferheaders[buffer], sizeof(MIDIHDR));
// OSD_Printf("Sending %d bytes (buffer %d)\n",eventcnt[buffer],buffer);
_MPU_BuffersWaiting++;
}
void MPU_BeginPlayback(void)
{
_MPU_LastEvent = _MIDI_GlobalPositionInTicks;
if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido);
}
void MPU_Pause(void)
{
if (hmido != (HMIDISTRM)-1) midiStreamPause(hmido);
}
void MPU_Unpause(void)
{
if (hmido != (HMIDISTRM)-1) midiStreamRestart(hmido);
}
void CALLBACK MPU_MIDICallback(HMIDIOUT handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
int32_t i;
UNREFERENCED_PARAMETER(dwInstance);
UNREFERENCED_PARAMETER(dwParam2);
switch (uMsg)
{
case MOM_DONE:
midiOutUnprepareHeader((HMIDIOUT)handle, (MIDIHDR*)dwParam1, sizeof(MIDIHDR));
for (i=0;i<NUMBUFFERS;i++)
{
if (dwParam1 == (uint32_t)&bufferheaders[i])
{
eventcnt[i] = 0; // marks the buffer as free
// OSD_Printf("Finished buffer %d\n",i);
_MPU_BuffersWaiting--;
break;
}
}
return;
default: return;
}
}
/*---------------------------------------------------------------------
Function: MPU_SendMidi
Queues a MIDI message to the music device.
---------------------------------------------------------------------*/
int32_t MPU_GetNextBuffer(void)
{
int32_t i;
for (i=0; i<NUMBUFFERS; i++)
{
if (eventcnt[i] == 0) return i;
}
return -1;
}
void MPU_SendMidi(char *data, int32_t count)
{
char *p;
int32_t padded, nextbuffer;
static int32_t masks[3] = { 0x000000ffl, 0x0000ffffl, 0x00ffffffl };
if (count <= 0) return;
if (count <= 3)
{
if (eventcnt[_MPU_CurrentBuffer] + 12 > BUFFERLEN)
{
// buffer over-full
nextbuffer = MPU_GetNextBuffer();
if (nextbuffer < 0)
{
// OSD_Printf("All buffers full!\n");
return;
}
MPU_FinishBuffer(_MPU_CurrentBuffer);
_MPU_CurrentBuffer = nextbuffer;
}
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_SHORTMSG << 24) | ((*((int32_t*)data)) & masks[count-1]);
eventcnt[_MPU_CurrentBuffer] += 12;
}
else
{
padded = PAD(count);
if (eventcnt[_MPU_CurrentBuffer] + 12 + padded > BUFFERLEN)
{
// buffer over-full
nextbuffer = MPU_GetNextBuffer();
if (nextbuffer < 0)
{
// OSD_Printf("All buffers full!\n");
return;
}
MPU_FinishBuffer(_MPU_CurrentBuffer);
_MPU_CurrentBuffer = nextbuffer;
}
p = eventbuf[_MPU_CurrentBuffer] + eventcnt[_MPU_CurrentBuffer];
((int32_t*)p)[0] = _MIDI_GlobalPositionInTicks - _MPU_LastEvent;
((int32_t*)p)[1] = 0;
((int32_t*)p)[2] = (MEVT_LONGMSG<<24) | (count & 0xffffffl);
p+=12; eventcnt[_MPU_CurrentBuffer] += 12;
for (; count>0; count--, padded--, eventcnt[_MPU_CurrentBuffer]++)
*(p++) = *(data++);
for (; padded>0; padded--, eventcnt[_MPU_CurrentBuffer]++)
*(p++) = 0;
}
_MPU_LastEvent = _MIDI_GlobalPositionInTicks;
}
/*---------------------------------------------------------------------
Function: MPU_SendMidiImmediate
Sends a MIDI message immediately to the the music device.
---------------------------------------------------------------------*/
void MPU_SendMidiImmediate(char *data, int32_t count)
{
MIDIHDR mhdr;
static int32_t masks[3] = { 0x00ffffffl, 0x0000ffffl, 0x000000ffl };
if (!count) return;
if (count<=3) midiOutShortMsg((HMIDIOUT)hmido, (*((int32_t*)data)) & masks[count-1]);
else
{
ZeroMemory(&mhdr, sizeof(mhdr));
mhdr.lpData = data;
mhdr.dwBufferLength = count;
midiOutPrepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
midiOutLongMsg((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
while (!(mhdr.dwFlags & MHDR_DONE)) ;
midiOutUnprepareHeader((HMIDIOUT)hmido, &mhdr, sizeof(MIDIHDR));
}
}
/*---------------------------------------------------------------------
Function: MPU_Reset
Resets the MPU401 card.
---------------------------------------------------------------------*/
int32_t MPU_Reset
(
void
)
{
midiStreamStop(hmido);
midiStreamClose(hmido);
return(MPU_Ok);
}
/*---------------------------------------------------------------------
Function: MPU_Init
Detects and initializes the MPU401 card.
---------------------------------------------------------------------*/
int32_t MPU_Init
(
int32_t addr
)
{
int32_t i;
for (i=0;i<NUMBUFFERS;i++) eventcnt[i]=0;
mididevice = addr;
if (midiOutGetDevCaps(mididevice, &midicaps, sizeof(MIDIOUTCAPS)) != MMSYSERR_NOERROR) return MPU_Error;
if (midiStreamOpen(&hmido,(LPUINT)&mididevice,1,(DWORD)MPU_MIDICallback,0L,CALLBACK_FUNCTION) != MMSYSERR_NOERROR) return(MPU_Error);
return(MPU_Ok);
}
/*---------------------------------------------------------------------
Function: MPU_NoteOff
Sends a full MIDI note off event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOff
(
int32_t channel,
int32_t key,
int32_t velocity
)
{
char msg[3];
msg[0] = (MIDI_NOTE_OFF | channel);
msg[1] = (key);
msg[2] = (velocity);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_NoteOn
Sends a full MIDI note on event out to the music device.
---------------------------------------------------------------------*/
void MPU_NoteOn
(
int32_t channel,
int32_t key,
int32_t velocity
)
{
char msg[3];
msg[0] = (MIDI_NOTE_ON | channel);
msg[1] = (key);
msg[2] = (velocity);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_PolyAftertouch
Sends a full MIDI polyphonic aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_PolyAftertouch
(
int32_t channel,
int32_t key,
int32_t pressure
)
{
char msg[3];
msg[0] = (MIDI_POLY_AFTER_TCH | channel);
msg[1] = (key);
msg[2] = (pressure);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_ControlChange
Sends a full MIDI control change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ControlChange
(
int32_t channel,
int32_t number,
int32_t value
)
{
char msg[3];
msg[0] = (MIDI_CONTROL_CHANGE | channel);
msg[1] = (number);
msg[2] = (value);
MPU_SendMidi(msg, 3);
}
/*---------------------------------------------------------------------
Function: MPU_ProgramChange
Sends a full MIDI program change event out to the music device.
---------------------------------------------------------------------*/
void MPU_ProgramChange
(
int32_t channel,
int32_t program
)
{
char msg[2];
msg[0] = (MIDI_PROGRAM_CHANGE | channel);
msg[1] = (program);
MPU_SendMidi(msg, 2);
}
/*---------------------------------------------------------------------
Function: MPU_ChannelAftertouch
Sends a full MIDI channel aftertouch event out to the music device.
---------------------------------------------------------------------*/
void MPU_ChannelAftertouch
(
int32_t channel,
int32_t pressure
)
{
char msg[2];
msg[0] = (MIDI_AFTER_TOUCH | channel);
msg[1] = (pressure);
MPU_SendMidi(msg, 2);
}
/*---------------------------------------------------------------------
Function: MPU_PitchBend
Sends a full MIDI pitch bend event out to the music device.
---------------------------------------------------------------------*/
void MPU_PitchBend
(
int32_t channel,
int32_t lsb,
int32_t msb
)
{
char msg[3];
msg[0] = (MIDI_PITCH_BEND | channel);
msg[1] = (lsb);
msg[2] = (msb);
MPU_SendMidi(msg, 3);
}
void MPU_SetTempo(int32_t tempo)
{
MIDIPROPTEMPO prop;
prop.cbStruct = sizeof(MIDIPROPTEMPO);
prop.dwTempo = 60000000l/tempo;
midiStreamProperty(hmido, (LPBYTE)&prop, MIDIPROP_SET|MIDIPROP_TEMPO);
}
void MPU_SetDivision(int32_t division)
{
MIDIPROPTIMEDIV prop;
prop.cbStruct = sizeof(MIDIPROPTIMEDIV);
prop.dwTimeDiv = division;
midiStreamProperty(hmido, (LPBYTE)&prop, MIDIPROP_SET|MIDIPROP_TIMEDIV);
}
void MPU_SetVolume(int32_t volume)
{
/*
HMIXER hmixer;
int32_t mixerid;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcdu;
MMRESULT mme;
if (mididevice < 0) return;
mme = mixerOpen(&hmixer, mididevice, 0,0, MIXER_OBJECTF_MIDIOUT);
if (mme) {
puts("Failed opening mixer");
return;
}
mixerGetID(hmixer, &mixerid, MIXER_OBJECTF_HMIXER);
printf("mixerid=%d\n",mixerid);
ZeroMemory(&mxcd,sizeof(mxcd));
mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
mxcd.dwControlID = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
mxcd.paDetails = (LPVOID)&mxcdu;
mxcdu.dwValue = (volume << 8) & 0xffff;
printf("set %d\n",mixerSetControlDetails((HMIXEROBJ)mididevice, &mxcd,
MIXER_OBJECTF_MIDIOUT|MIXER_SETCONTROLDETAILSF_VALUE));
mixerClose(hmixer);
*/
UNREFERENCED_PARAMETER(volume);
}
int32_t MPU_GetVolume(void)
{
// if (mididevice < 0) return 0;
return 0;
}

View file

@ -1,68 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
#ifndef __MPU401_H
#define __MPU401_H
#include "compat.h"
#define MPU_DefaultAddress 0x330
enum MPU_ERRORS
{
MPU_Warning = -2,
MPU_Error = -1,
MPU_Ok = 0
};
#define MPU_NotFound -1
#define MPU_UARTFailed -2
#define MPU_ReadyToWrite 0x40
#define MPU_ReadyToRead 0x80
#define MPU_CmdEnterUART 0x3f
#define MPU_CmdReset 0xff
#define MPU_CmdAcknowledge 0xfe
extern int32_t _MPU_CurrentBuffer;
extern int32_t _MPU_BuffersWaiting;
void MPU_SendMidi( char *data, int32_t count );
void MPU_SendMidiImmediate( char *data, int32_t count );
int32_t MPU_Reset( void );
int32_t MPU_Init( int32_t addr );
void MPU_NoteOff( int32_t channel, int32_t key, int32_t velocity );
void MPU_NoteOn( int32_t channel, int32_t key, int32_t velocity );
void MPU_PolyAftertouch( int32_t channel, int32_t key, int32_t pressure );
void MPU_ControlChange( int32_t channel, int32_t number, int32_t value );
void MPU_ProgramChange( int32_t channel, int32_t program );
void MPU_ChannelAftertouch( int32_t channel, int32_t pressure );
void MPU_PitchBend( int32_t channel, int32_t lsb, int32_t msb );
void MPU_SetTempo(int32_t tempo);
void MPU_SetDivision(int32_t division);
void MPU_SetVolume(int32_t volume);
int32_t MPU_GetVolume(void);
void MPU_BeginPlayback( void );
void MPU_Pause(void);
void MPU_Unpause(void);
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,133 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
file: MULTIVOC.H
author: James R. Dose
date: December 20, 1993
Public header for MULTIVOC.C
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MULTIVOC_H
#define __MULTIVOC_H
#include "compat.h"
#define MV_MinVoiceHandle 1
extern int32_t MV_ErrorCode;
enum MV_Errors
{
MV_Warning = -2,
MV_Error = -1,
MV_Ok = 0,
MV_UnsupportedCard,
MV_NotInstalled,
MV_NoVoices,
MV_NoMem,
MV_VoiceNotFound,
MV_BlasterError,
MV_DPMI_Error,
MV_InvalidVOCFile,
MV_InvalidWAVFile,
MV_InvalidOGGFile,
MV_InvalidMixMode,
MV_IrqFailure,
MV_DMAFailure,
MV_DMA16Failure,
MV_NullRecordFunction
};
typedef int16_t MONO16;
typedef int8_t MONO8;
typedef MONO8 VOLUME8[ 256 ];
typedef MONO16 VOLUME16[ 256 ];
char *MV_ErrorString( int32_t ErrorNumber );
int32_t MV_VoicePlaying( int32_t handle );
int32_t MV_KillAllVoices( void );
int32_t MV_Kill( int32_t handle );
int32_t MV_VoicesPlaying( void );
int32_t MV_VoiceAvailable( int32_t priority );
int32_t MV_SetPitch( int32_t handle, int32_t pitchoffset );
int32_t MV_SetFrequency( int32_t handle, int32_t frequency );
int32_t MV_EndLooping( int32_t handle );
int32_t MV_SetPan( int32_t handle, int32_t vol, int32_t left, int32_t right );
int32_t MV_Pan3D( int32_t handle, int32_t angle, int32_t distance );
void MV_SetReverb( int32_t reverb );
void MV_SetFastReverb( int32_t reverb );
int32_t MV_GetMaxReverbDelay( void );
int32_t MV_GetReverbDelay( void );
void MV_SetReverbDelay( int32_t delay );
int32_t MV_SetMixMode( int32_t numchannels, int32_t samplebits );
int32_t MV_StartPlayback( void );
void MV_StopPlayback( void );
int32_t MV_StartRecording( int32_t MixRate, void ( *function )( char *ptr, int32_t length ) );
void MV_StopRecord( void );
int32_t MV_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ),
int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
int32_t priority, uint32_t callbackval );
int32_t MV_PlayRaw( char *ptr, uint32_t length,
uint32_t rate, int32_t pitchoffset, int32_t vol, int32_t left,
int32_t right, int32_t priority, uint32_t callbackval );
int32_t MV_PlayLoopedRaw( char *ptr, int32_t length,
char *loopstart, char *loopend, uint32_t rate, int32_t pitchoffset,
int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t MV_PlayWAV( char *ptr, int32_t pitchoffset, int32_t vol, int32_t left,
int32_t right, int32_t priority, uint32_t callbackval );
int32_t MV_PlayWAV3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t MV_PlayLoopedWAV( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t MV_PlayOGG( char *ptr, int32_t pitchoffset, int32_t vol, int32_t left,
int32_t right, int32_t priority, uint32_t callbackval );
int32_t MV_PlayOGG3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t MV_PlayLoopedOGG( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
int32_t MV_PlayVOC3D( char *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
int32_t priority, uint32_t callbackval );
int32_t MV_PlayVOC( char *ptr, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
int32_t priority, uint32_t callbackval );
int32_t MV_PlayLoopedVOC( char *ptr, int32_t loopstart, int32_t loopend,
int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
uint32_t callbackval );
void MV_CreateVolumeTable( int32_t index, int32_t volume, int32_t MaxVolume );
void MV_SetVolume( int32_t volume );
int32_t MV_GetVolume( void );
void MV_SetCallBack( void ( *function )( uint32_t ) );
void MV_SetReverseStereo( int32_t setting );
int32_t MV_GetReverseStereo( void );
int32_t MV_Init( int32_t soundcard, int32_t MixRate, int32_t Voices, int32_t numchannels,
int32_t samplebits );
int32_t MV_Shutdown( void );
void MV_Update(void);
#endif

View file

@ -1,634 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: MUSIC.C
author: James R. Dose
date: March 25, 1994
Device independant music playback routines.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "music.h"
#include "midi.h"
#include "mpu401.h"
#include "compat.h"
#ifdef USE_OPENAL
#include "openal.h"
#endif
#include "duke3d.h"
#ifndef TRUE
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#endif
#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef max
# define max(a,b) ( ((a) > (b)) ? (a) : (b) )
#endif
int32_t MUSIC_SoundDevice = -1;
int32_t MUSIC_ErrorCode = MUSIC_Ok;
static midifuncs MUSIC_MidiFunctions;
int32_t MUSIC_InitMidi(int32_t card, midifuncs *Funcs, int32_t Address);
#define MUSIC_SetErrorCode( status ) \
MUSIC_ErrorCode = ( status );
/*---------------------------------------------------------------------
Function: MUSIC_ErrorString
Returns a pointer to the error message associated with an error
number. A -1 returns a pointer the current error.
---------------------------------------------------------------------*/
char *MUSIC_ErrorString
(
int32_t ErrorNumber
)
{
char *ErrorString;
switch (ErrorNumber)
{
case MUSIC_Warning :
case MUSIC_Error :
ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode);
break;
case MUSIC_Ok :
ErrorString = "Music ok.";
break;
case MUSIC_ASSVersion :
ErrorString = "Apogee Sound System Version WinMM "
"Programmed by Jim Dose, Ported by Jonathon Fowler\n"
"(c) Copyright 1996 James R. Dose. All Rights Reserved.\n";
break;
case MUSIC_SoundCardError :
case MUSIC_MPU401Error :
ErrorString = "Could not detect MPU-401.";
break;
case MUSIC_InvalidCard :
ErrorString = "Invalid Music device.";
break;
case MUSIC_MidiError :
ErrorString = "Error playing MIDI file.";
break;
case MUSIC_TaskManError :
ErrorString = "TaskMan error.";
break;
case MUSIC_DPMI_Error :
ErrorString = "DPMI Error in MUSIC.";
break;
default :
ErrorString = "Unknown Music error code.";
break;
}
return(ErrorString);
}
/*---------------------------------------------------------------------
Function: MUSIC_Init
Selects which sound device to use.
---------------------------------------------------------------------*/
int32_t MUSIC_Init
(
int32_t SoundCard,
int32_t Address
)
{
int32_t i;
int32_t status;
for (i = 0; i < 128; i++)
{
MIDI_PatchMap[ i ] = i;
}
MUSIC_SoundDevice = SoundCard;
status = MUSIC_InitMidi(SoundCard, &MUSIC_MidiFunctions, Address);
#ifdef USE_OPENAL
if (AL_Init())
{
int32_t i;
// no AL support so shitcan the ogg definitions
for (i=(MAXLEVELS*(MAXVOLUMES+1))-1;i>=0;i--) // +1 volume for "intro", "briefing" music
{
if (MapInfo[i].musicfn1 != NULL)
Bfree(MapInfo[i].musicfn1);
MapInfo[i].musicfn1 = NULL;
}
}
#endif
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_Shutdown
Terminates use of sound device.
---------------------------------------------------------------------*/
int32_t MUSIC_Shutdown
(
void
)
{
int32_t status;
status = MUSIC_Ok;
MIDI_StopSong();
//MPU_Reset();
#ifdef USE_OPENAL
AL_Shutdown();
#endif
return(status);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetVolume
Sets the volume of music playback.
---------------------------------------------------------------------*/
void MUSIC_SetVolume
(
int32_t volume
)
{
volume = max(0, volume);
volume = min(volume, 255);
#ifdef USE_OPENAL
AL_SetMusicVolume(volume);
#endif
if (MUSIC_SoundDevice != -1)
{
MIDI_SetVolume(volume);
}
}
/*---------------------------------------------------------------------
Function: MUSIC_SetMidiChannelVolume
Sets the volume of music playback on the specified MIDI channel.
---------------------------------------------------------------------*/
void MUSIC_SetMidiChannelVolume
(
int32_t channel,
int32_t volume
)
{
MIDI_SetUserChannelVolume(channel, volume);
}
/*---------------------------------------------------------------------
Function: MUSIC_ResetMidiChannelVolumes
Sets the volume of music playback on all MIDI channels to full volume.
---------------------------------------------------------------------*/
void MUSIC_ResetMidiChannelVolumes
(
void
)
{
MIDI_ResetUserChannelVolume();
}
/*---------------------------------------------------------------------
Function: MUSIC_GetVolume
Returns the volume of music playback.
---------------------------------------------------------------------*/
int32_t MUSIC_GetVolume
(
void
)
{
if (MUSIC_SoundDevice == -1)
{
return(0);
}
return(MIDI_GetVolume());
}
/*---------------------------------------------------------------------
Function: MUSIC_SetLoopFlag
Set whether the music will loop or end when it reaches the end of
the song.
---------------------------------------------------------------------*/
void MUSIC_SetLoopFlag
(
int32_t loopflag
)
{
MIDI_SetLoopFlag(loopflag);
}
/*---------------------------------------------------------------------
Function: MUSIC_SongPlaying
Returns whether there is a song playing.
---------------------------------------------------------------------*/
int32_t MUSIC_SongPlaying
(
void
)
{
return(MIDI_SongPlaying());
}
/*---------------------------------------------------------------------
Function: MUSIC_Continue
Continues playback of a paused song.
---------------------------------------------------------------------*/
void MUSIC_Continue
(
void
)
{
#ifdef USE_OPENAL
AL_Continue();
#endif
MIDI_ContinueSong();
}
/*---------------------------------------------------------------------
Function: MUSIC_Pause
Pauses playback of a song.
---------------------------------------------------------------------*/
void MUSIC_Pause
(
void
)
{
#ifdef USE_OPENAL
AL_Pause();
#endif
MIDI_PauseSong();
}
/*---------------------------------------------------------------------
Function: MUSIC_StopSong
Stops playback of current song.
---------------------------------------------------------------------*/
int32_t MUSIC_StopSong
(
void
)
{
#ifdef USE_OPENAL
AL_Stop();
#endif
MUSIC_StopFade();
MIDI_StopSong();
MUSIC_SetErrorCode(MUSIC_Ok);
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_PlaySong
Begins playback of MIDI song.
---------------------------------------------------------------------*/
int32_t MUSIC_PlaySong
(
char *song,
int32_t loopflag
)
{
int32_t status;
#ifdef USE_OPENAL
AL_PlaySong((char *)song,loopflag);
if (AL_isntALmusic())
#endif
{
MUSIC_StopSong();
status = MIDI_PlaySong(song, loopflag);
if (status != MIDI_Ok)
{
MUSIC_SetErrorCode(MUSIC_MidiError);
return(MUSIC_Warning);
}
}
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetContext
Sets the song context.
---------------------------------------------------------------------*/
void MUSIC_SetContext
(
int32_t context
)
{
MIDI_SetContext(context);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetContext
Returns the current song context.
---------------------------------------------------------------------*/
int32_t MUSIC_GetContext
(
void
)
{
return MIDI_GetContext();
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTick
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTick
(
uint32_t PositionInTicks
)
{
MIDI_SetSongTick(PositionInTicks);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongTime
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongTime
(
uint32_t milliseconds
)
{
MIDI_SetSongTime(milliseconds);
}
/*---------------------------------------------------------------------
Function: MUSIC_SetSongPosition
Sets the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_SetSongPosition
(
int32_t measure,
int32_t beat,
int32_t tick
)
{
MIDI_SetSongPosition(measure, beat, tick);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongPosition
Returns the position of the song pointer.
---------------------------------------------------------------------*/
void MUSIC_GetSongPosition
(
songposition *pos
)
{
MIDI_GetSongPosition(pos);
}
/*---------------------------------------------------------------------
Function: MUSIC_GetSongLength
Returns the length of the song.
---------------------------------------------------------------------*/
void MUSIC_GetSongLength
(
songposition *pos
)
{
MIDI_GetSongLength(pos);
}
int32_t MUSIC_InitMidi
(
int32_t card,
midifuncs *Funcs,
int32_t Address
)
{
UNREFERENCED_PARAMETER(card);
UNREFERENCED_PARAMETER(Address);
Funcs->NoteOff = MPU_NoteOff;
Funcs->NoteOn = MPU_NoteOn;
Funcs->PolyAftertouch = MPU_PolyAftertouch;
Funcs->ControlChange = MPU_ControlChange;
Funcs->ProgramChange = MPU_ProgramChange;
Funcs->ChannelAftertouch = MPU_ChannelAftertouch;
Funcs->PitchBend = MPU_PitchBend;
Funcs->ReleasePatches = NULL;
Funcs->LoadPatch = NULL;
Funcs->SetVolume = NULL /*MPU_SetVolume*/;
Funcs->GetVolume = NULL /*MPU_GetVolume*/;
MIDI_SetMidiFuncs(Funcs);
return(MIDI_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_FadeVolume
Fades music volume from current level to another over a specified
period of time.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeVolume
(
int32_t tovolume,
int32_t milliseconds
)
{
UNREFERENCED_PARAMETER(milliseconds);
MIDI_SetVolume(tovolume);
return(MUSIC_Ok);
}
/*---------------------------------------------------------------------
Function: MUSIC_FadeActive
Returns whether the fade routine is active.
---------------------------------------------------------------------*/
int32_t MUSIC_FadeActive
(
void
)
{
return(0);
}
/*---------------------------------------------------------------------
Function: MUSIC_StopFade
Stops fading the music.
---------------------------------------------------------------------*/
void MUSIC_StopFade
(
void
)
{}
/*---------------------------------------------------------------------
Function: MUSIC_RerouteMidiChannel
Sets callback function to reroute MIDI commands from specified
function.
---------------------------------------------------------------------*/
void MUSIC_RerouteMidiChannel
(
int32_t channel,
int32_t(*function)(int32_t event, int32_t c1, int32_t c2)
)
{
MIDI_RerouteMidiChannel(channel, function);
}
/*---------------------------------------------------------------------
Function: MUSIC_RegisterTimbreBank
Halts playback of all sounds.
---------------------------------------------------------------------*/
void MUSIC_RegisterTimbreBank
(
char *timbres
)
{
UNREFERENCED_PARAMETER(timbres);
}
void MUSIC_Update(void)
{
MIDI_UpdateMusic();
}

View file

@ -1,92 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: MUSIC.H
author: James R. Dose
date: March 25, 1994
Public header for MUSIC.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __MUSIC_H
#define __MUSIC_H
#include "compat.h"
extern int32_t MUSIC_ErrorCode;
enum MUSIC_ERRORS
{
MUSIC_Warning = -2,
MUSIC_Error = -1,
MUSIC_Ok = 0,
MUSIC_ASSVersion,
MUSIC_SoundCardError,
MUSIC_MPU401Error,
MUSIC_InvalidCard,
MUSIC_MidiError,
MUSIC_TaskManError,
MUSIC_DPMI_Error
};
typedef struct
{
uint32_t tickposition;
uint32_t milliseconds;
uint32_t measure;
uint32_t beat;
uint32_t tick;
} songposition;
#define MUSIC_LoopSong ( 1 == 1 )
#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
char *MUSIC_ErrorString( int32_t ErrorNumber );
int32_t MUSIC_Init( int32_t SoundCard, int32_t Address );
int32_t MUSIC_Shutdown( void );
void MUSIC_SetVolume( int32_t volume );
void MUSIC_SetMidiChannelVolume( int32_t channel, int32_t volume );
void MUSIC_ResetMidiChannelVolumes( void );
int32_t MUSIC_GetVolume( void );
void MUSIC_SetLoopFlag( int32_t loopflag );
int32_t MUSIC_SongPlaying( void );
void MUSIC_Continue( void );
void MUSIC_Pause( void );
int32_t MUSIC_StopSong( void );
int32_t MUSIC_PlaySong( char *song, int32_t loopflag );
void MUSIC_SetContext( int32_t context );
int32_t MUSIC_GetContext( void );
void MUSIC_SetSongTick( uint32_t PositionInTicks );
void MUSIC_SetSongTime( uint32_t milliseconds );
void MUSIC_SetSongPosition( int32_t measure, int32_t beat, int32_t tick );
void MUSIC_GetSongPosition( songposition *pos );
void MUSIC_GetSongLength( songposition *pos );
int32_t MUSIC_FadeVolume( int32_t tovolume, int32_t milliseconds );
int32_t MUSIC_FadeActive( void );
void MUSIC_StopFade( void );
void MUSIC_RerouteMidiChannel( int32_t channel, int32_t ( *function )( int32_t event, int32_t c1, int32_t c2 ) );
void MUSIC_RegisterTimbreBank( char *timbres );
void MUSIC_Update(void);
#endif

View file

@ -1,301 +0,0 @@
#include "multivoc.h"
extern char *MV_MixDestination;
extern uint32_t MV_MixPosition;
extern char *MV_LeftVolume;
extern char *MV_RightVolume;
extern char *MV_HarshClipTable;
extern int32_t MV_RightChannelOffset;
extern int32_t MV_SampleSize;
void MV_Mix8BitMono(uint32_t position, uint32_t rate,
const char *start, uint32_t length)
{
const char *src;
char *dest;
uint32_t i;
src = (const char *)start;
dest = (char *)MV_MixDestination;
for (i = 0; i < length; i++)
{
int32_t s = src[position >> 16];
int32_t d = *dest;
s = MV_LeftVolume[s * 2];
s += d;
s = MV_HarshClipTable[s + 0x80];
*dest = (s & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitStereo(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const char *src;
char *dest;
uint32_t i;
src = (const char *)start;
dest = (char *)MV_MixDestination;
for (i = 0; i < length; i++)
{
int32_t s = src[(position >> 16)];
int32_t dl = dest[0];
int32_t dr = dest[MV_RightChannelOffset];
dl += MV_LeftVolume[s * 2];
dr += MV_RightVolume[s * 2];
dl = MV_HarshClipTable[dl + 0x80];
dr = MV_HarshClipTable[dr + 0x80];
dest[0] = (dl & 0xff);
dest[MV_RightChannelOffset] = (dr & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitMono(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const int16_t *MV_LeftVolumeS;
const char *src;
int16_t *dest;
uint32_t i;
src = (const char *)start;
dest = (int16_t *)MV_MixDestination;
MV_LeftVolumeS = (const int16_t *)MV_LeftVolume;
for (i = 0; i < length; i++)
{
int32_t s = src[position >> 16];
int32_t d = dest[0];
s = MV_LeftVolumeS[s];
s += d;
if (s < -32768) s = -32768;
if (s > 32767) s = 32767;
*dest = (int16_t) s;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitStereo(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const int16_t *MV_LeftVolumeS;
const int16_t *MV_RightVolumeS;
const char *src;
int16_t *dest;
uint32_t i;
src = (char *)start;
dest = (int16_t *)MV_MixDestination;
MV_LeftVolumeS = (const int16_t *)MV_LeftVolume;
MV_RightVolumeS = (const int16_t *)MV_RightVolume;
for (i = 0; i < length; i++)
{
int32_t s = src[position >> 16];
int32_t dl = dest[0];
int32_t dr = dest[MV_RightChannelOffset/2];
dl += MV_LeftVolumeS[s];
dr += MV_RightVolumeS[s];
if (dl < -32768) dl = -32768;
if (dl > 32767) dl = 32767;
if (dr < -32768) dr = -32768;
if (dr > 32767) dr = 32767;
dest[0] = (int16_t) dl;
dest[MV_RightChannelOffset/2] = (int16_t) dr;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitMono16(uint32_t position, uint32_t rate,
const char *start, uint32_t length)
{
const char *src;
char *dest;
uint32_t i;
src = (const char *)start + 1;
dest = (char *)MV_MixDestination;
for (i = 0; i < length; i++)
{
int32_t s = (int32_t)src[(position >> 16) * 2] + 0x80;
int32_t d = *dest;
s = MV_LeftVolume[s * 2];
s += d;
s = MV_HarshClipTable[s + 0x80];
*dest = (s & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix8BitStereo16(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const char *src;
char *dest;
uint32_t i;
src = (const char *)start + 1;
dest = (char *)MV_MixDestination;
for (i = 0; i < length; i++)
{
int32_t s = src[(position >> 16) * 2] + 0x80;
int32_t dl = dest[0];
int32_t dr = dest[MV_RightChannelOffset];
dl += MV_LeftVolume[s * 2];
dr += MV_RightVolume[s * 2];
dl = MV_HarshClipTable[dl + 0x80];
dr = MV_HarshClipTable[dr + 0x80];
dest[0] = (dl & 0xff);
dest[MV_RightChannelOffset] = (dr & 0xff);
position += rate;
dest += MV_SampleSize;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitMono16(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const int16_t *MV_LeftVolumeS;
const char *src;
int16_t *dest;
uint32_t i;
src = (const char *)start;
dest = (int16_t *)MV_MixDestination;
MV_LeftVolumeS = (const int16_t *)MV_LeftVolume;
for (i = 0; i < length; i++)
{
int32_t sl = src[(position >> 16) * 2 + 0];
int32_t sh = src[(position >> 16) * 2 + 1] ^ 0x80;
int32_t d = *dest;
sl = MV_LeftVolume[sl * 2 + 1];
sh = MV_LeftVolumeS[sh];
d = sl + sh + 0x80 + d;
if (d < -32768) d = -32768;
if (d > 32767) d = 32767;
*dest = (int16_t) d;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}
void MV_Mix16BitStereo16(uint32_t position,
uint32_t rate, const char *start, uint32_t length)
{
const int16_t *MV_LeftVolumeS;
const int16_t *MV_RightVolumeS;
const char *src;
int16_t *dest;
uint32_t i;
src = (const char *)start;
dest = (int16_t *)MV_MixDestination;
MV_LeftVolumeS = (const int16_t *)MV_LeftVolume;
MV_RightVolumeS = (const int16_t *)MV_RightVolume;
for (i = 0; i < length; i++)
{
int32_t sl = src[(position >> 16) * 2 + 0];
int32_t sh = src[(position >> 16) * 2 + 1] ^ 0x80;
int32_t dl = dest[0];
int32_t dr = dest[MV_RightChannelOffset/2];
int32_t sll = MV_LeftVolume[sl * 2 + 1];
int32_t slh = MV_LeftVolumeS[sh];
int32_t srl = MV_RightVolume[sl * 2 + 1];
int32_t srh = MV_RightVolumeS[sh];
dl = sll + slh + 0x80 + dl;
dr = srl + srh + 0x80 + dr;
if (dl < -32768) dl = -32768;
if (dl > 32767) dl = 32767;
if (dr < -32768) dr = -32768;
if (dr > 32767) dr = 32767;
dest[0] = (int16_t) dl;
dest[MV_RightChannelOffset/2] = (int16_t) dr;
position += rate;
dest += MV_SampleSize/2;
}
MV_MixPosition = position;
MV_MixDestination = (char *)dest;
}

View file

@ -1,487 +0,0 @@
.586P
EXTRN _MV_HarshClipTable : dword
EXTRN _MV_MixDestination : dword
EXTRN _MV_MixPosition : dword
EXTRN _MV_LeftVolume : dword
EXTRN _MV_RightVolume : dword
EXTRN _MV_SampleSize : dword
EXTRN _MV_RightChannelOffset : dword
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_Mix8BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix8BitMono
_MV_Mix8BitMono:
; Two at once
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [apatch7+2],bl
mov byte ptr [apatch8+2],bl
mov byte ptr [apatch9+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov dword ptr [apatch1+4],ebx
mov dword ptr [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov dword ptr [apatch3+2],ebx
mov dword ptr [apatch4+2],ebx
; Rate scale ptr
mov dword ptr [apatch5+2],edx
mov dword ptr [apatch6+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je short exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
;ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 1 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
movzx eax, byte ptr [esi+edx] ; get third sample
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix8BitStereo
_MV_Mix8BitStereo:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [bpatch8+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [bpatch6+3],ebx
mov dword ptr [bpatch7+2],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [bpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [bpatch2+4],ebx
; Rate scale ptr
mov dword ptr [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov dword ptr [bpatch4+2],ebx
mov dword ptr [bpatch5+2],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
;ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 2 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix16BitMono
_MV_Mix16BitMono:
; Two at once
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [cpatch5+3],bl
mov byte ptr [cpatch6+3],bl
add bl,bl
mov byte ptr [cpatch7+2],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [cpatch1+4],ebx
mov dword ptr [cpatch2+4],ebx
; Rate scale ptr
mov dword ptr [cpatch3+2],edx
mov dword ptr [cpatch4+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
;ALIGN 4
mix16Mloop:
movsx edx, word ptr [edi] ; get current sample from destination
cpatch1:
movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
add ebx, edx ; mix second sample
mov [edi], ax ; write new sample to destination
mov edx, ebp ; begin calculating third sample
cmp ebx, -32768 ; Harsh clip sample
jge short m16skip3
mov ebx, -32768
jmp short m16skip4
m16skip3:
cmp ebx, 32767
jle short m16skip4
mov ebx, 32767
m16skip4:
cpatch3:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
cpatch6:
mov [edi + 2], bx ; write new sample to destination
shr eax, 16 ; finish calculation for fourth sample
cpatch4:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
cpatch7:
add edi, 4 ; move destination to third sample
movzx eax, byte ptr [esi+edx] ; get third sample
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix16BitStereo
_MV_Mix16BitStereo:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [dpatch6+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [dpatch4+3],ebx
mov dword ptr [dpatch5+3],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [dpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [dpatch2+4],ebx
; Rate scale ptr
mov dword ptr [dpatch3+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
;ALIGN 4
mix16Sloop:
dpatch1:
movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample
movsx edx, word ptr [edi] ; get current sample from destination
dpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
dpatch3:
add ebp,12345678h ; advance frac pointer
dpatch4:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
add ebx, edx ; mix right sample
mov [edi], ax ; write left sample to destination
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch5:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch6:
add edi, 4 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
CODE ENDS
END

View file

@ -1,524 +0,0 @@
;Copyright (C) 1994-1995 Apogee Software, Ltd.
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.
;
;This program 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 General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
CPU 386
SECTION .data
%ifdef UNDERSCORES
%define MV_Mix8BitMono _MV_Mix8BitMono
%define MV_Mix8BitStereo _MV_Mix8BitStereo
%define MV_Mix16BitMono _MV_Mix16BitMono
%define MV_Mix16BitStereo _MV_Mix16BitStereo
%else
%define _MV_HarshClipTable MV_HarshClipTable
%define _MV_MixDestination MV_MixDestination
%define _MV_MixPosition MV_MixPosition
%define _MV_LeftVolume MV_LeftVolume
%define _MV_RightVolume MV_RightVolume
%define _MV_SampleSize MV_SampleSize
%define _MV_RightChannelOffset MV_RightChannelOffset
%endif
EXTERN _MV_HarshClipTable
EXTERN _MV_MixDestination
EXTERN _MV_MixPosition
EXTERN _MV_LeftVolume
EXTERN _MV_RightVolume
EXTERN _MV_SampleSize
EXTERN _MV_RightChannelOffset
GLOBAL MV_Mix8BitMono
GLOBAL MV_Mix8BitStereo
GLOBAL MV_Mix16BitMono
GLOBAL MV_Mix16BitStereo
;================
;
; MV_Mix8BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix8BitMono:
; Two at once
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [apatch7+2],bl
mov byte [apatch8+2],bl
mov byte [apatch9+3],bl
; Volume table ptr
mov ebx, dword [_MV_LeftVolume] ; Since we're mono, use left volume
mov dword [apatch1+4],ebx
mov dword [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, dword [_MV_HarshClipTable]
add ebx, 128
mov dword [apatch3+2],ebx
mov dword [apatch4+2],ebx
; Rate scale ptr
mov dword [apatch5+2],edx
mov dword [apatch6+2],edx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je short exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte [esi+eax] ; get first sample
movzx ebx, byte [esi+ebx] ; get second sample
ALIGN 4
mix8Mloop:
movzx edx, byte [edi] ; get current sample from destination
apatch1:
movsx eax, byte [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte [edi + 1] ; get current sample from destination
apatch3:
mov eax, dword [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov byte [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, dword [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 1 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov byte [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte [esi+eax] ; get fourth sample
movzx eax, byte [esi+edx] ; get third sample
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix8BitStereo:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [bpatch8+2],bl
; Right channel offset
mov ebx, dword [_MV_RightChannelOffset]
mov dword [bpatch6+3],ebx
mov dword [bpatch7+2],ebx
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [bpatch1+4],ebx
mov ebx, dword [_MV_RightVolume]
mov dword [bpatch2+4],ebx
; Rate scale ptr
mov dword [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, dword [_MV_HarshClipTable]
add ebx,128
mov dword [bpatch4+2],ebx
mov dword [bpatch5+2],ebx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short EXIT8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte [esi+eax] ; get first sample
ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, dword [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov byte [edi], al ; write left sample to destination
bpatch5:
mov ebx, dword [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov byte [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 2 ; move destination to second sample
movzx ebx, byte [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix16BitMono:
; Two at once
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [cpatch5+3],bl
mov byte [cpatch6+3],bl
add bl,bl
mov byte [cpatch7+2],bl
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [cpatch1+4],ebx
mov dword [cpatch2+4],ebx
; Rate scale ptr
mov dword [cpatch3+2],edx
mov dword [cpatch4+2],edx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je near EXIT16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte [esi+eax] ; get first sample
movzx ebx, byte [esi+ebx] ; get second sample
ALIGN 4
mix16Mloop:
movsx edx, word [edi] ; get current sample from destination
cpatch1:
movsx eax, word [2*eax+12345678h] ; volume translate first sample
cpatch2:
movsx ebx, word [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
cpatch5:
movsx edx, word [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
add ebx, edx ; mix second sample
mov word [edi], ax ; write new sample to destination
mov edx, ebp ; begin calculating third sample
cmp ebx, -32768 ; Harsh clip sample
jge short m16skip3
mov ebx, -32768
jmp short m16skip4
m16skip3:
cmp ebx, 32767
jle short m16skip4
mov ebx, 32767
m16skip4:
cpatch3:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
cpatch6:
mov word [edi + 2], bx ; write new sample to destination
shr eax, 16 ; finish calculation for fourth sample
cpatch4:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte [esi+eax] ; get fourth sample
cpatch7:
add edi, 4 ; move destination to third sample
movzx eax, byte [esi+edx] ; get third sample
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix16BitStereo:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [dpatch6+2],bl
; Right channel offset
mov ebx, dword [_MV_RightChannelOffset]
mov dword [dpatch4+3],ebx
mov dword [dpatch5+3],ebx
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [dpatch1+4],ebx
mov ebx, dword [_MV_RightVolume]
mov dword [dpatch2+4],ebx
; Rate scale ptr
mov dword [dpatch3+2],edx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je near exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte [esi+eax] ; get first sample
ALIGN 4
mix16Sloop:
dpatch1:
movsx eax, word [2*ebx+12345678h] ; volume translate left sample
movsx edx, word [edi] ; get current sample from destination
dpatch2:
movsx ebx, word [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
dpatch3:
add ebp,12345678h ; advance frac pointer
dpatch4:
movsx edx, word [edi+12345678h] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
add ebx, edx ; mix right sample
mov word [edi], ax ; write left sample to destination
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch5:
mov word [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch6:
add edi, 4 ; move destination to second sample
movzx ebx, byte [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
exit16S:
popad
ret

View file

@ -1,491 +0,0 @@
.586P
EXTRN _MV_HarshClipTable : dword
EXTRN _MV_MixDestination : dword
EXTRN _MV_MixPosition : dword
EXTRN _MV_LeftVolume : dword
EXTRN _MV_RightVolume : dword
EXTRN _MV_SampleSize : dword
EXTRN _MV_RightChannelOffset : dword
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_Mix8BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix8BitMono_
MV_Mix8BitMono_:
; Two at once
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [apatch7+2],bl
mov byte ptr [apatch8+2],bl
mov byte ptr [apatch9+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov dword ptr [apatch1+4],ebx
mov dword ptr [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov dword ptr [apatch3+2],ebx
mov dword ptr [apatch4+2],ebx
; Rate scale ptr
mov dword ptr [apatch5+2],edx
mov dword ptr [apatch6+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je short exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
;ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 1 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
movzx eax, byte ptr [esi+edx] ; get third sample
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix8BitStereo_
MV_Mix8BitStereo_:
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [bpatch8+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [bpatch6+3],ebx
mov dword ptr [bpatch7+2],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [bpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [bpatch2+4],ebx
; Rate scale ptr
mov dword ptr [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov dword ptr [bpatch4+2],ebx
mov dword ptr [bpatch5+2],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
;ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 2 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix16BitMono_
MV_Mix16BitMono_:
; Two at once
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [cpatch5+3],bl
mov byte ptr [cpatch6+3],bl
add bl,bl
mov byte ptr [cpatch7+2],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [cpatch1+4],ebx
mov dword ptr [cpatch2+4],ebx
; Rate scale ptr
mov dword ptr [cpatch3+2],edx
mov dword ptr [cpatch4+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movzx eax, byte ptr [esi+eax] ; get first sample
movzx ebx, byte ptr [esi+ebx] ; get second sample
;ALIGN 4
mix16Mloop:
movsx edx, word ptr [edi] ; get current sample from destination
cpatch1:
movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
add ebx, edx ; mix second sample
mov [edi], ax ; write new sample to destination
mov edx, ebp ; begin calculating third sample
cmp ebx, -32768 ; Harsh clip sample
jge short m16skip3
mov ebx, -32768
jmp short m16skip4
m16skip3:
cmp ebx, 32767
jle short m16skip4
mov ebx, 32767
m16skip4:
cpatch3:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
cpatch6:
mov [edi + 2], bx ; write new sample to destination
shr eax, 16 ; finish calculation for fourth sample
cpatch4:
add ebp,12345678h ; advance frac pointer
movzx ebx, byte ptr [esi+eax] ; get fourth sample
cpatch7:
add edi, 4 ; move destination to third sample
movzx eax, byte ptr [esi+edx] ; get third sample
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix16BitStereo_
MV_Mix16BitStereo_:
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [dpatch6+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [dpatch4+3],ebx
mov dword ptr [dpatch5+3],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [dpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [dpatch2+4],ebx
; Rate scale ptr
mov dword ptr [dpatch3+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movzx ebx, byte ptr [esi+eax] ; get first sample
;ALIGN 4
mix16Sloop:
dpatch1:
movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample
movsx edx, word ptr [edi] ; get current sample from destination
dpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
dpatch3:
add ebp,12345678h ; advance frac pointer
dpatch4:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
add ebx, edx ; mix right sample
mov [edi], ax ; write left sample to destination
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch5:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch6:
add edi, 4 ; move destination to second sample
movzx ebx, byte ptr [esi+edx] ; get second sample
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
CODE ENDS
END

View file

@ -1,507 +0,0 @@
.586P
EXTRN _MV_HarshClipTable:DWORD
EXTRN _MV_MixDestination:DWORD
EXTRN _MV_MixPosition:DWORD
EXTRN _MV_LeftVolume:DWORD
EXTRN _MV_RightVolume:DWORD
EXTRN _MV_SampleSize:DWORD
EXTRN _MV_RightChannelOffset:DWORD
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_Mix8BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix8BitMono16
_MV_Mix8BitMono16:
; Two at once
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [apatch7+2],bl
mov byte ptr [apatch8+2],bl
mov byte ptr [apatch9+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov dword ptr [apatch1+4],ebx
mov dword ptr [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov dword ptr [apatch3+2],ebx
mov dword ptr [apatch4+2],ebx
; Rate scale ptr
mov dword ptr [apatch5+2],edx
mov dword ptr [apatch6+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movsx eax, byte ptr [esi+2*eax] ; get first sample
movsx ebx, byte ptr [esi+2*ebx] ; get second sample
add eax, 80h
add ebx, 80h
;ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 2 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movsx ebx, byte ptr [esi+2*eax] ; get fourth sample
movsx eax, byte ptr [esi+2*edx] ; get third sample
add ebx, 80h
add eax, 80h
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix8BitStereo16
_MV_Mix8BitStereo16:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [bpatch8+2],bl
; mov byte ptr [bpatch9+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [bpatch6+3],ebx
mov dword ptr [bpatch7+2],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [bpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [bpatch2+4],ebx
; Rate scale ptr
mov dword ptr [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov dword ptr [bpatch4+2],ebx
mov dword ptr [bpatch5+2],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movsx ebx, byte ptr [esi+2*eax] ; get first sample
add ebx, 80h
;ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 1 ; move destination to second sample
movsx ebx, byte ptr [esi+2*edx] ; get second sample
add ebx, 80h
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix16BitMono16
_MV_Mix16BitMono16:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [cpatch4+2],bl
mov byte ptr [cpatch5+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [cpatch2+4],ebx
inc ebx
mov dword ptr [cpatch1+4],ebx
; Rate scale ptr
mov dword ptr [cpatch3+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov ebx,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for first sample
movzx eax, word ptr [esi+2*ebx] ; get low byte of sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
movsx edx, word ptr [edi] ; get current sample from destination
;ALIGN 4
mix16Mloop:
cpatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
add eax, edx ; mix low byte of sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
mov ebx, ebp ; begin calculating second sample
mov [edi], ax ; write new sample to destination
shr ebx, 16 ; finish calculation for second sample
cpatch3:
add ebp, 12345678h ; advance frac pointer
movzx eax, word ptr [esi+2*ebx] ; get second sample
cpatch4:
add edi, 2 ; move destination to second sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC _MV_Mix16BitStereo16
_MV_Mix16BitStereo16:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [dpatch9+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [dpatch7+3],ebx
mov dword ptr [dpatch8+3],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [dpatch1+4],ebx
inc ebx
mov dword ptr [dpatch2+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [dpatch3+4],ebx
inc ebx
mov dword ptr [dpatch4+4],ebx
; Rate scale ptr
mov dword ptr [dpatch5+2],edx
; Source ptr
mov dword ptr [dpatch6+4],esi
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; esi - scratch
; ecx - count
; edi - destination
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov ebx,ebp ; begin calculating first sample
shr ebx,16 ; finish calculation for first sample
movzx edx, word ptr [esi+2*ebx] ; get first sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
;ALIGN 4
mix16Sloop:
; Left channel
dpatch1:
movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch2:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
; Right channel
dpatch3:
movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch4:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample
dpatch7:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
dpatch5:
add ebp,12345678h ; advance frac pointer
add eax, edx ; mix left sample
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
movsx edx, word ptr [edi+2] ; get current sample from destination
mov [edi], ax ; write left sample to destination
add ebx, edx ; mix right sample
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch8:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch9:
add edi, 4 ; move destination to second sample
dpatch6:
movzx edx, word ptr [2*edx+12345678h] ; get second sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
CODE ENDS
END

View file

@ -1,544 +0,0 @@
;Copyright (C) 1994-1995 Apogee Software, Ltd.
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.
;
;This program 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 General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
CPU 386
SECTION .data
%ifdef UNDERSCORES
%define MV_Mix8BitMono16 _MV_Mix8BitMono16
%define MV_Mix8BitStereo16 _MV_Mix8BitStereo16
%define MV_Mix16BitMono16 _MV_Mix16BitMono16
%define MV_Mix16BitStereo16 _MV_Mix16BitStereo16
%else
%define _MV_HarshClipTable MV_HarshClipTable
%define _MV_MixDestination MV_MixDestination
%define _MV_MixPosition MV_MixPosition
%define _MV_LeftVolume MV_LeftVolume
%define _MV_RightVolume MV_RightVolume
%define _MV_SampleSize MV_SampleSize
%define _MV_RightChannelOffset MV_RightChannelOffset
%endif
EXTERN _MV_HarshClipTable
EXTERN _MV_MixDestination
EXTERN _MV_MixPosition
EXTERN _MV_LeftVolume
EXTERN _MV_RightVolume
EXTERN _MV_SampleSize
EXTERN _MV_RightChannelOffset
GLOBAL MV_Mix8BitMono16
GLOBAL MV_Mix8BitStereo16
GLOBAL MV_Mix16BitMono16
GLOBAL MV_Mix16BitStereo16
%define OFFSET
;================
;
; MV_Mix8BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix8BitMono16:
; Two at once
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [apatch7+2],bl
mov byte [apatch8+2],bl
mov byte [apatch9+3],bl
; Volume table ptr
mov ebx, dword [_MV_LeftVolume] ; Since we're mono, use left volume
mov dword [apatch1+4],ebx
mov dword [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, dword [_MV_HarshClipTable]
add ebx, 128
mov dword [apatch3+2],ebx
mov dword [apatch4+2],ebx
; Rate scale ptr
mov dword [apatch5+2],edx
mov dword [apatch6+2],edx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je near exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movsx eax, byte [esi+2*eax] ; get first sample
movsx ebx, byte [esi+2*ebx] ; get second sample
add eax, 80h
add ebx, 80h
ALIGN 4
mix8Mloop:
movzx edx, byte [edi] ; get current sample from destination
apatch1:
movsx eax, byte [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte [edi + 1] ; get current sample from destination
apatch3:
mov eax, dword [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov byte [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, dword [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 2 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov byte [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movsx ebx, byte [esi+2*eax] ; get fourth sample
movsx eax, byte [esi+2*edx] ; get third sample
add ebx, 80h
add eax, 80h
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix8BitStereo16:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [bpatch8+2],bl
; mov byte [bpatch9+2],bl
; Right channel offset
mov ebx, dword [_MV_RightChannelOffset]
mov dword [bpatch6+3],ebx
mov dword [bpatch7+2],ebx
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [bpatch1+4],ebx
mov ebx, dword [_MV_RightVolume]
mov dword [bpatch2+4],ebx
; Rate scale ptr
mov dword [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, dword [_MV_HarshClipTable]
add ebx,128
mov dword [bpatch4+2],ebx
mov dword [bpatch5+2],ebx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short EXIT8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movsx ebx, byte [esi+2*eax] ; get first sample
add ebx, 80h
ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, dword [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov byte [edi], al ; write left sample to destination
bpatch5:
mov ebx, dword [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov byte [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 1 ; move destination to second sample
movsx ebx, byte [esi+2*edx] ; get second sample
add ebx, 80h
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix16BitMono16:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [cpatch4+2],bl
mov byte [cpatch5+3],bl
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [cpatch2+4],ebx
inc ebx
mov dword [cpatch1+4],ebx
; Rate scale ptr
mov dword [cpatch3+2],edx
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je near EXIT16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov ebx,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for first sample
movzx eax, word [esi+2*ebx] ; get low byte of sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
movsx edx, word [edi] ; get current sample from destination
ALIGN 4
mix16Mloop:
cpatch1:
movsx eax, byte [2*eax+12345678h] ; volume translate low byte of sample
cpatch2:
movsx ebx, word [2*ebx+12345678h] ; volume translate high byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
add eax, edx ; mix low byte of sample
cpatch5:
movsx edx, word [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
mov ebx, ebp ; begin calculating second sample
mov word [edi], ax ; write new sample to destination
shr ebx, 16 ; finish calculation for second sample
cpatch3:
add ebp, 12345678h ; advance frac pointer
movzx eax, word [esi+2*ebx] ; get second sample
cpatch4:
add edi, 2 ; move destination to second sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 4
MV_Mix16BitStereo16:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, dword [_MV_SampleSize]
mov byte [dpatch9+2],bl
; Right channel offset
mov ebx, dword [_MV_RightChannelOffset]
mov dword [dpatch7+3],ebx
mov dword [dpatch8+3],ebx
; Volume table ptr
mov ebx, dword [_MV_LeftVolume]
mov dword [dpatch1+4],ebx
inc ebx
mov dword [dpatch2+4],ebx
mov ebx, dword [_MV_RightVolume]
mov dword [dpatch3+4],ebx
inc ebx
mov dword [dpatch4+4],ebx
; Rate scale ptr
mov dword [dpatch5+2],edx
; Source ptr
mov dword [dpatch6+4],esi
mov edi, dword [_MV_MixDestination] ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je near exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; esi - scratch
; ecx - count
; edi - destination
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov ebx,ebp ; begin calculating first sample
shr ebx,16 ; finish calculation for first sample
movzx edx, word [esi+2*ebx] ; get first sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
ALIGN 4
mix16Sloop:
; Left channel
dpatch1:
movsx eax, word [2*esi+12345678h] ; volume translate high byte of sample
dpatch2:
movsx ebx, byte [2*edx+12345678h] ; volume translate low byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
; Right channel
dpatch3:
movsx esi, word [2*esi+12345678h] ; volume translate high byte of sample
dpatch4:
movsx ebx, byte [2*edx+12345678h] ; volume translate low byte of sample
lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample
dpatch7:
movsx edx, word [edi+12345678h] ; get current sample from destination
dpatch5:
add ebp,12345678h ; advance frac pointer
add eax, edx ; mix left sample
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
movsx edx, word [edi+2] ; get current sample from destination
mov word [edi], ax ; write left sample to destination
add ebx, edx ; mix right sample
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch8:
mov word [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch9:
add edi, 4 ; move destination to second sample
dpatch6:
movzx edx, word [2*edx+12345678h] ; get second sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov dword [_MV_MixDestination], edi ; Store the current write position
mov dword [_MV_MixPosition], ebp ; return position
exit16S:
popad
ret

View file

@ -1,511 +0,0 @@
.586P
EXTRN _MV_HarshClipTable:DWORD
EXTRN _MV_MixDestination:DWORD
EXTRN _MV_MixPosition:DWORD
EXTRN _MV_LeftVolume:DWORD
EXTRN _MV_RightVolume:DWORD
EXTRN _MV_SampleSize:DWORD
EXTRN _MV_RightChannelOffset:DWORD
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_Mix8BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix8BitMono16_
MV_Mix8BitMono16_:
; Two at once
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [apatch7+2],bl
mov byte ptr [apatch8+2],bl
mov byte ptr [apatch9+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
mov dword ptr [apatch1+4],ebx
mov dword ptr [apatch2+4],ebx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx, 128
mov dword ptr [apatch3+2],ebx
mov dword ptr [apatch4+2],ebx
; Rate scale ptr
mov dword ptr [apatch5+2],edx
mov dword ptr [apatch6+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
shr ecx, 1 ; double sample count
cmp ecx, 0
je exit8m
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; apatch1 - volume table
; apatch2 - volume table
; apatch3 - harsh clip table
; apatch4 - harsh clip table
; apatch5 - sample rate
; apatch6 - sample rate
mov eax,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr eax,16 ; finish calculation for first sample
mov ebx,ebp ; begin calculating second sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for second sample
movsx eax, byte ptr [esi+2*eax] ; get first sample
movsx ebx, byte ptr [esi+2*ebx] ; get second sample
add eax, 80h
add ebx, 80h
;ALIGN 4
mix8Mloop:
movzx edx, byte ptr [edi] ; get current sample from destination
apatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
apatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
add eax, edx ; mix first sample
apatch9:
movzx edx, byte ptr [edi + 1] ; get current sample from destination
apatch3:
mov eax, [eax + 12345678h] ; harsh clip new sample
add ebx, edx ; mix second sample
mov [edi], al ; write new sample to destination
mov edx, ebp ; begin calculating third sample
apatch4:
mov ebx, [ebx + 12345678h] ; harsh clip new sample
apatch5:
add ebp,12345678h ; advance frac pointer
shr edx, 16 ; finish calculation for third sample
mov eax, ebp ; begin calculating fourth sample
apatch7:
add edi, 2 ; move destination to second sample
shr eax, 16 ; finish calculation for fourth sample
mov [edi], bl ; write new sample to destination
apatch6:
add ebp,12345678h ; advance frac pointer
movsx ebx, byte ptr [esi+2*eax] ; get fourth sample
movsx eax, byte ptr [esi+2*edx] ; get third sample
add ebx, 80h
add eax, 80h
apatch8:
add edi, 2 ; move destination to third sample
dec ecx ; decrement count
jnz mix8Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit8m:
popad
ret
;================
;
; MV_Mix8BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix8BitStereo16_
MV_Mix8BitStereo16_:
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
inc esi
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [bpatch8+2],bl
; mov byte ptr [bpatch9+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [bpatch6+3],ebx
mov dword ptr [bpatch7+2],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [bpatch1+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [bpatch2+4],ebx
; Rate scale ptr
mov dword ptr [bpatch3+2],edx
; Harsh Clip table ptr
mov ebx, _MV_HarshClipTable
add ebx,128
mov dword ptr [bpatch4+2],ebx
mov dword ptr [bpatch5+2],ebx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je short exit8S
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; bpatch1 - left volume table
; bpatch2 - right volume table
; bpatch3 - sample rate
; bpatch4 - harsh clip table
; bpatch5 - harsh clip table
mov eax,ebp ; begin calculating first sample
shr eax,16 ; finish calculation for first sample
movsx ebx, byte ptr [esi+2*eax] ; get first sample
add ebx, 80h
;ALIGN 4
mix8Sloop:
bpatch1:
movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
movzx edx, byte ptr [edi] ; get current sample from destination
bpatch2:
movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
add eax, edx ; mix left sample
bpatch3:
add ebp,12345678h ; advance frac pointer
bpatch6:
movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
bpatch4:
mov eax, [eax + 12345678h] ; harsh clip left sample
add ebx, edx ; mix right sample
mov [edi], al ; write left sample to destination
bpatch5:
mov ebx, [ebx + 12345678h] ; harsh clip right sample
mov edx, ebp ; begin calculating second sample
bpatch7:
mov [edi+12345678h], bl ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
bpatch8:
add edi, 1 ; move destination to second sample
movsx ebx, byte ptr [esi+2*edx] ; get second sample
add ebx, 80h
dec ecx ; decrement count
jnz mix8Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT8S:
popad
ret
;================
;
; MV_Mix16BitMono16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix16BitMono16_
MV_Mix16BitMono16_:
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [cpatch4+2],bl
mov byte ptr [cpatch5+3],bl
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [cpatch2+4],ebx
inc ebx
mov dword ptr [cpatch1+4],ebx
; Rate scale ptr
mov dword ptr [cpatch3+2],edx
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16M
; eax - scratch
; ebx - scratch
; edx - scratch
; ecx - count
; edi - destination
; esi - source
; ebp - frac pointer
; cpatch1 - volume table
; cpatch2 - volume table
; cpatch3 - sample rate
; cpatch4 - sample rate
mov ebx,ebp ; begin calculating first sample
add ebp,edx ; advance frac pointer
shr ebx,16 ; finish calculation for first sample
movzx eax, word ptr [esi+2*ebx] ; get low byte of sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
movsx edx, word ptr [edi] ; get current sample from destination
;ALIGN 4
mix16Mloop:
cpatch1:
movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample
cpatch2:
movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
add eax, edx ; mix low byte of sample
cpatch5:
movsx edx, word ptr [edi + 2] ; get current sample from destination
cmp eax, -32768 ; Harsh clip sample
jge short m16skip1
mov eax, -32768
jmp short m16skip2
m16skip1:
cmp eax, 32767
jle short m16skip2
mov eax, 32767
m16skip2:
mov ebx, ebp ; begin calculating second sample
mov [edi], ax ; write new sample to destination
shr ebx, 16 ; finish calculation for second sample
cpatch3:
add ebp, 12345678h ; advance frac pointer
movzx eax, word ptr [esi+2*ebx] ; get second sample
cpatch4:
add edi, 2 ; move destination to second sample
xor eax, 8000h
movzx ebx, ah
sub ah, ah
dec ecx ; decrement count
jnz mix16Mloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
EXIT16M:
popad
ret
;================
;
; MV_Mix16BitStereo16
;
;================
; eax - position
; edx - rate
; ebx - start
; ecx - number of samples to mix
ALIGN 16
PUBLIC MV_Mix16BitStereo16_
MV_Mix16BitStereo16_:
pushad
; Thanks to Lauri Liinat for spotting this lunacy
;mov eax, dword ptr [esp + 0*4 + 9*4]
;mov edx, dword ptr [esp + 1*4 + 9*4]
;mov ebx, dword ptr [esp + 2*4 + 9*4]
;mov ecx, dword ptr [esp + 3*4 + 9*4]
mov ebp, eax
mov esi, ebx ; Source pointer
; Sample size
mov ebx, _MV_SampleSize
mov byte ptr [dpatch9+2],bl
; Right channel offset
mov ebx, _MV_RightChannelOffset
mov dword ptr [dpatch7+3],ebx
mov dword ptr [dpatch8+3],ebx
; Volume table ptr
mov ebx, _MV_LeftVolume
mov dword ptr [dpatch1+4],ebx
inc ebx
mov dword ptr [dpatch2+4],ebx
mov ebx, _MV_RightVolume
mov dword ptr [dpatch3+4],ebx
inc ebx
mov dword ptr [dpatch4+4],ebx
; Rate scale ptr
mov dword ptr [dpatch5+2],edx
; Source ptr
mov dword ptr [dpatch6+4],esi
mov edi, _MV_MixDestination ; Get the position to write to
; Number of samples to mix
cmp ecx, 0
je exit16S
; eax - scratch
; ebx - scratch
; edx - scratch
; esi - scratch
; ecx - count
; edi - destination
; ebp - frac pointer
; dpatch1 - left volume table
; dpatch2 - right volume table
; dpatch3 - sample rate
mov ebx,ebp ; begin calculating first sample
shr ebx,16 ; finish calculation for first sample
movzx edx, word ptr [esi+2*ebx] ; get first sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
;ALIGN 4
mix16Sloop:
; Left channel
dpatch1:
movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch2:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
; Right channel
dpatch3:
movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample
dpatch4:
movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample
dpatch7:
movsx edx, word ptr [edi+12345678h] ; get current sample from destination
dpatch5:
add ebp,12345678h ; advance frac pointer
add eax, edx ; mix left sample
cmp eax, -32768 ; Harsh clip sample
jge short s16skip1
mov eax, -32768
jmp short s16skip2
s16skip1:
cmp eax, 32767
jle short s16skip2
mov eax, 32767
s16skip2:
movsx edx, word ptr [edi+2] ; get current sample from destination
mov [edi], ax ; write left sample to destination
add ebx, edx ; mix right sample
cmp ebx, -32768 ; Harsh clip sample
jge short s16skip3
mov ebx, -32768
jmp short s16skip4
s16skip3:
cmp ebx, 32767
jle short s16skip4
mov ebx, 32767
s16skip4:
mov edx, ebp ; begin calculating second sample
dpatch8:
mov [edi+12345678h], bx ; write right sample to destination
shr edx, 16 ; finish calculation for second sample
dpatch9:
add edi, 4 ; move destination to second sample
dpatch6:
movzx edx, word ptr [2*edx+12345678h] ; get second sample
xor edx, 8000h ; Change from signed to unsigned
movzx esi, dh ; put high byte in esi
sub dh, dh ; lo byte in edx
dec ecx ; decrement count
jnz mix16Sloop ; loop
mov _MV_MixDestination, edi ; Store the current write position
mov _MV_MixPosition, ebp ; return position
exit16S:
popad
ret
CODE ENDS
END

View file

@ -1,67 +0,0 @@
#include "multivoc.h"
// #include "_multivc.h"
void MV_16BitReverb(char *src, char *dest, VOLUME16 *volume, int count)
{
int i;
short *pdest = (short *)dest;
for (i = 0; i < count; i++)
{
#if PLATFORM_BIGENDIAN
int sl = src[i*2+1];
int sh = src[i*2+0] ^ 0x80;
#else
int sl = src[i*2+0];
int sh = src[i*2+1] ^ 0x80;
#endif
sl = (*volume)[sl] >> 8;
sh = (*volume)[sh];
pdest[i] = (short)(sl + sh + 0x80);
}
}
void MV_8BitReverb(signed char *src, signed char *dest, VOLUME16 *volume, int count)
{
int i;
for (i = 0; i < count; i++)
{
unsigned char s = (unsigned char) src[i];
s = (*volume)[s] & 0xff;
dest[i] = (char)(s + 0x80);
}
}
void MV_16BitReverbFast(char *src, char *dest, int count, int shift)
{
int i;
short *pdest = (short *)dest;
const short *psrc = (const short *)src;
for (i = 0; i < count; i++)
{
pdest[i] = psrc[i] >> shift;
}
}
void MV_8BitReverbFast(signed char *src, signed char *dest, int count, int shift)
{
int i;
unsigned char sh = 0x80 - (0x80 >> shift);
for (i = 0; i < count; i++)
{
unsigned char a = ((unsigned char) src[i]) >> shift;
unsigned char c = (((unsigned char) src[i]) ^ 0x80) >> 7;
dest[i] = (signed char)(a + sh + c);
}
}

View file

@ -1,202 +0,0 @@
.586P
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_16BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 16
PUBLIC _MV_16BitReverb
_MV_16BitReverb:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov esi, eax
lea edi, [edx - 2]
;ALIGN 4
rev16loop:
movzx eax, word ptr [esi] ; get sample
add edi, 2
movzx edx, ah
sub ah, ah
movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample
xor edx, 80h
movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample
add esi, 2
lea eax, [ eax + edx + 80h ] ; mix high byte of sample
dec ecx ; decrement count
mov [edi], ax ; write new sample to destination
jnz rev16loop ; loop
popad
ret
;================
;
; MV_8BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 16
PUBLIC _MV_8BitReverb
_MV_8BitReverb:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov esi, eax
lea edi, [edx - 1]
xor eax, eax
;ALIGN 4
rev8loop:
; movzx eax, byte ptr [esi] ; get sample
mov al, byte ptr [esi] ; get sample
inc edi
; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample
mov al, byte ptr [2*eax+ebx] ; volume translate sample
inc esi
; add eax, 80h
add al, 80h
dec ecx ; decrement count
mov [edi], al ; write new sample to destination
jnz rev8loop ; loop
popad
ret
;================
;
; MV_16BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 16
PUBLIC _MV_16BitReverbFast
_MV_16BitReverbFast:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov esi, eax
mov eax,OFFSET rpatch16+3
mov [eax],cl
lea edi, [edx - 2]
;ALIGN 4
frev16loop:
mov ax, word ptr [esi] ; get sample
add edi, 2
rpatch16:
sar ax, 5 ;;;;Add 1 before shift
add esi, 2
mov [edi], ax ; write new sample to destination
dec ebx ; decrement count
jnz frev16loop ; loop
popad
ret
;================
;
; MV_8BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 16
PUBLIC _MV_8BitReverbFast
_MV_8BitReverbFast:
pushad
mov eax, dword ptr [esp + 0*4 + 9*4]
mov edx, dword ptr [esp + 1*4 + 9*4]
mov ebx, dword ptr [esp + 2*4 + 9*4]
mov ecx, dword ptr [esp + 3*4 + 9*4]
mov esi, eax
mov eax,OFFSET rpatch8+2
mov edi, edx
mov edx, 80h
mov [eax],cl
mov eax, 80h
shr eax, cl
dec edi
sub edx, eax
;ALIGN 4
frev8loop:
mov al, byte ptr [esi] ; get sample
inc esi
mov ecx, eax
inc edi
rpatch8:
shr eax, 3
xor ecx, 80h ; flip the sign bit
shr ecx, 7 ; shift the sign down to 1
add eax, edx
add eax, ecx ; add sign bit to round to 0
dec ebx ; decrement count
mov [edi], al ; write new sample to destination
jnz frev8loop ; loop
popad
ret
CODE ENDS
END

View file

@ -1,230 +0,0 @@
;Copyright (C) 1994-1995 Apogee Software, Ltd.
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.
;
;This program 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 General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
;
;Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
CPU 386
SECTION .data
%ifdef UNDERSCORES
%define MV_16BitReverb _MV_16BitReverb
%define MV_8BitReverb _MV_8BitReverb
%define MV_16BitReverbFast _MV_16BitReverbFast
%define MV_8BitReverbFast _MV_8BitReverbFast
%endif
GLOBAL MV_16BitReverb
GLOBAL MV_8BitReverb
GLOBAL MV_16BitReverbFast
GLOBAL MV_8BitReverbFast
%define OFFSET
;================
;
; MV_16BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 4
MV_16BitReverb:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov esi, eax
lea edi, [edx - 2]
ALIGN 4
rev16loop:
movzx eax, word [esi] ; get sample
add edi, 2
movzx edx, ah
sub ah, ah
movsx eax, byte [2*eax+ebx+1] ; volume translate low byte of sample
xor edx, 80h
movsx edx, word [2*edx+ebx] ; volume translate high byte of sample
add esi, 2
lea eax, [ eax + edx + 80h ] ; mix high byte of sample
dec ecx ; decrement count
mov word [edi], ax ; write new sample to destination
jnz rev16loop ; loop
popad
ret
;================
;
; MV_8BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 4
MV_8BitReverb:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov esi, eax
lea edi, [edx - 1]
xor eax, eax
ALIGN 4
rev8loop:
; movzx eax, byte ptr [esi] ; get sample
mov al, byte [esi] ; get sample
inc edi
; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample
mov al, byte [2*eax+ebx] ; volume translate sample
inc esi
; add eax, 80h
add al, 80h
dec ecx ; decrement count
mov byte [edi], al ; write new sample to destination
jnz rev8loop ; loop
popad
ret
;================
;
; MV_16BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 4
MV_16BitReverbFast:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov esi, eax
mov eax,OFFSET rpatch16+3
mov byte [eax],cl
lea edi, [edx - 2]
ALIGN 4
frev16loop:
mov ax, word [esi] ; get sample
add edi, 2
rpatch16:
sar ax, 5 ;;;;Add 1 before shift
add esi, 2
mov word [edi], ax ; write new sample to destination
dec ebx ; decrement count
jnz frev16loop ; loop
popad
ret
;================
;
; MV_8BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 4
MV_8BitReverbFast:
pushad
mov eax, dword [esp + 0*4 + 9*4]
mov edx, dword [esp + 1*4 + 9*4]
mov ebx, dword [esp + 2*4 + 9*4]
mov ecx, dword [esp + 3*4 + 9*4]
mov esi, eax
mov eax,OFFSET rpatch8+2
mov edi, edx
mov edx, 80h
mov byte [eax],cl
mov eax, 80h
shr eax, cl
dec edi
sub edx, eax
ALIGN 4
frev8loop:
mov al, byte [esi] ; get sample
inc esi
mov ecx, eax
inc edi
rpatch8:
shr eax, 3
xor ecx, 80h ; flip the sign bit
shr ecx, 7 ; shift the sign down to 1
add eax, edx
add eax, ecx ; add sign bit to round to 0
dec ebx ; decrement count
mov byte [edi], al ; write new sample to destination
jnz frev8loop ; loop
popad
ret

View file

@ -1,174 +0,0 @@
.586P
CODE SEGMENT PUBLIC USE32 'DATA'
ASSUME cs:CODE,ds:CODE
;================
;
; MV_16BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 16
PUBLIC MV_16BitReverb_
MV_16BitReverb_:
mov esi, eax
lea edi, [edx - 2]
;ALIGN 4
rev16loop:
movzx eax, word ptr [esi] ; get sample
add edi, 2
movzx edx, ah
sub ah, ah
movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample
xor edx, 80h
movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample
add esi, 2
lea eax, [ eax + edx + 80h ] ; mix high byte of sample
dec ecx ; decrement count
mov [edi], ax ; write new sample to destination
jnz rev16loop ; loop
ret
;================
;
; MV_8BitReverb
;
;================
; eax - source position
; edx - destination position
; ebx - Volume table
; ecx - number of samples
ALIGN 16
PUBLIC MV_8BitReverb_
MV_8BitReverb_:
mov esi, eax
lea edi, [edx - 1]
xor eax, eax
;ALIGN 4
rev8loop:
; movzx eax, byte ptr [esi] ; get sample
mov al, byte ptr [esi] ; get sample
inc edi
; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample
mov al, byte ptr [2*eax+ebx] ; volume translate sample
inc esi
; add eax, 80h
add al, 80h
dec ecx ; decrement count
mov [edi], al ; write new sample to destination
jnz rev8loop ; loop
ret
;================
;
; MV_16BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 16
PUBLIC MV_16BitReverbFast_
MV_16BitReverbFast_:
mov esi, eax
mov eax,OFFSET rpatch16+3
mov [eax],cl
lea edi, [edx - 2]
;ALIGN 4
frev16loop:
mov ax, word ptr [esi] ; get sample
add edi, 2
rpatch16:
sar ax, 5 ;;;;Add 1 before shift
add esi, 2
mov [edi], ax ; write new sample to destination
dec ebx ; decrement count
jnz frev16loop ; loop
ret
;================
;
; MV_8BitReverbFast
;
;================
; eax - source position
; edx - destination position
; ebx - number of samples
; ecx - shift
ALIGN 16
PUBLIC MV_8BitReverbFast_
MV_8BitReverbFast_:
mov esi, eax
mov eax,OFFSET rpatch8+2
mov edi, edx
mov edx, 80h
mov [eax],cl
mov eax, 80h
shr eax, cl
dec edi
sub edx, eax
;ALIGN 4
frev8loop:
mov al, byte ptr [esi] ; get sample
inc esi
mov ecx, eax
inc edi
rpatch8:
shr eax, 3
xor ecx, 80h ; flip the sign bit
shr ecx, 7 ; shift the sign down to 1
add eax, edx
add eax, ecx ; add sign bit to round to 0
dec ebx ; decrement count
mov [edi], al ; write new sample to destination
jnz frev8loop ; loop
ret
CODE ENDS
END

View file

@ -1,528 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2008 - EDuke32 developers
This file is part of EDuke32
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#include "baselayer.h"
#include "compat.h"
#define AL_NO_PROTOTYPES
#define ALC_NO_PROTOTYPES
#include <AL/al.h>
#include <AL/alc.h>
#include "openal.h"
// #include "_multivc.h"
ALCdevice * device=NULL;
ALCcontext * context=NULL;
char *ALdoing = NULL;
int32_t AL_Error;
int32_t bufsize;
int32_t openal_disabled = 0;
typedef struct SD
{
ALuint buffers[16];
ALuint source;
ALenum format;
char loop;
char type;
int32_t rate;
sounddef def;
int32_t ready;
} sounddef1;
sounddef1 music;
#ifdef _WIN32
// Windows
static HMODULE hALDLL = NULL;
#else
#include <dlfcn.h>
static void *alhandle = NULL;
#endif
static char *aldriver = NULL;
static LPALGETSOURCEI balGetSourcei = NULL;
static LPALSOURCEF balSourcef = NULL;
static LPALSOURCEPLAY balSourcePlay = NULL;
static LPALSOURCEPAUSE balSourcePause = NULL;
static LPALCGETERROR balcGetError = NULL;
static LPALGETERROR balGetError = NULL;
static LPALBUFFERDATA balBufferData = NULL;
static LPALGENBUFFERS balGenBuffers = NULL;
static LPALGENSOURCES balGenSources = NULL;
static LPALSOURCEI balSourcei = NULL;
static LPALSOURCEQUEUEBUFFERS balSourceQueueBuffers = NULL;
static LPALSOURCESTOP balSourceStop = NULL;
static LPALSOURCEUNQUEUEBUFFERS balSourceUnqueueBuffers = NULL;
static LPALCMAKECONTEXTCURRENT balcMakeContextCurrent = NULL;
static LPALDELETESOURCES balDeleteSources = NULL;
static LPALDELETEBUFFERS balDeleteBuffers = NULL;
static LPALCDESTROYCONTEXT balcDestroyContext = NULL;
static LPALCCLOSEDEVICE balcCloseDevice = NULL;
static LPALCOPENDEVICE balcOpenDevice = NULL;
static LPALCCREATECONTEXT balcCreateContext = NULL;
static LPALGETSTRING balGetString = NULL;
static void * algetproc_(const char *s, int32_t *err, int32_t fatal)
{
void *t;
#if defined _WIN32
t = (void*)GetProcAddress(hALDLL,s);
#else
t = (void*)dlsym(alhandle,s);
#endif
if (!t && fatal)
{
initprintf("Failed to find %s in %s\n", s, aldriver);
*err = 1;
}
return t;
}
#define ALGETPROC(s) algetproc_(s,&err,1)
#define ALGETPROCSOFT(s) algetproc_(s,&err,0)
static int32_t unloadaldriver(void)
{
#ifdef _WIN32
if (!hALDLL) return 0;
#endif
if (aldriver)
free(aldriver);
aldriver = NULL;
#ifdef _WIN32
if (hALDLL)
FreeLibrary(hALDLL);
hALDLL = NULL;
#else
if (alhandle)
dlclose(alhandle);
alhandle = NULL;
#endif
balGetSourcei = NULL;
balSourcef = NULL;
balSourcePlay = NULL;
balSourcePause = NULL;
balcGetError = NULL;
balGetError = NULL;
balBufferData = NULL;
balGenBuffers = NULL;
balGenSources = NULL;
balSourcei = NULL;
balSourceQueueBuffers = NULL;
balSourceStop = NULL;
balSourceUnqueueBuffers = NULL;
balDeleteSources = NULL;
balcMakeContextCurrent = NULL;
balDeleteSources = NULL;
balDeleteBuffers = NULL;
balcDestroyContext = NULL;
balcCloseDevice = NULL;
balcOpenDevice = NULL;
balcCreateContext = NULL;
balGetString = NULL;
return 0;
}
static int32_t loadaldriver(void)
{
int32_t err=0;
char *driver;
#ifdef _WIN32
if (hALDLL)
return 0;
#endif
// if (!driver)
{
#ifdef _WIN32
driver = "OpenAL32.DLL";
#elif defined __APPLE__
driver = "/System/Library/Frameworks/OpenGL.framework/OpenGL"; // FIXME: like I know anything about Apple. Hah.
#else
driver = "libopenal.so";
#endif
}
initprintf("Loading %s\n",driver);
#ifdef _WIN32
hALDLL = LoadLibrary(driver);
if (!hALDLL) return -1;
#else
alhandle = dlopen(driver, RTLD_NOW|RTLD_GLOBAL);
if (!alhandle) return -1;
#endif
aldriver = strdup(driver);
balGetSourcei = ALGETPROC("alGetSourcei");
balSourcef = ALGETPROC("alSourcef");
balSourcePlay = ALGETPROC("alSourcePlay");
balSourcePause = ALGETPROC("alSourcePause");
balcGetError = ALGETPROC("alcGetError");
balGetError = ALGETPROC("alGetError");
balBufferData = ALGETPROC("alBufferData");
balGenBuffers = ALGETPROC("alGenBuffers");
balGenSources = ALGETPROC("alGenSources");
balSourcei = ALGETPROC("alSourcei");
balSourceQueueBuffers = ALGETPROC("alSourceQueueBuffers");
balSourceStop = ALGETPROC("alSourceStop");
balSourceUnqueueBuffers = ALGETPROC("alSourceUnqueueBuffers");
balDeleteSources = ALGETPROC("alDeleteSources");
balcMakeContextCurrent = ALGETPROC("alcMakeContextCurrent");
balDeleteSources = ALGETPROC("alDeleteSources");
balDeleteBuffers = ALGETPROC("alDeleteBuffers");
balcDestroyContext = ALGETPROC("alcDestroyContext");
balcCloseDevice = ALGETPROC("alcCloseDevice");
balcOpenDevice = ALGETPROC("alcOpenDevice");
balcCreateContext = ALGETPROC("alcCreateContext");
balGetString = ALGETPROC("alGetString");
if (err) unloadaldriver();
return err;
}
char *ALC_ErrorString(int32_t code)
{
switch (code)
{
case ALC_NO_ERROR:
return "OpenAL error: There is no current error.";
case ALC_INVALID_DEVICE:
return "OpenAL error: No device.";
case ALC_INVALID_CONTEXT:
return "OpenAL error: Invalid context ID.";
case ALC_INVALID_ENUM:
return "OpenAL error: Invalid parameter.";
case ALC_INVALID_VALUE:
return "OpenAL error: Invalid enum parameter value.";
case ALC_OUT_OF_MEMORY:
return "OpenAL error: Unable to allocate memory.";
default:
return "OpenAL error: Unknown error.";
}
}
char *AL_ErrorString(int32_t code)
{
switch (code)
{
case AL_NO_ERROR:
return "OpenAL error: There is no current error.";
case AL_INVALID_NAME:
return "OpenAL error: Invalid name parameter.";
case AL_INVALID_ENUM:
return "OpenAL error: Invalid parameter.";
case AL_INVALID_VALUE:
return "OpenAL error: Invalid enum parameter value.";
case AL_INVALID_OPERATION:
return "OpenAL error: Illegal call.";
case AL_OUT_OF_MEMORY:
return "OpenAL error: Unable to allocate memory.";
case OV_EFAULT:
return "Internal logic fault (bug or heap/stack corruption.";
case OV_EREAD:
return "Read from media.";
case OV_EIMPL:
return "The bitstream makes use of a feature not implemented in this library version.";
case OV_EINVAL:
return "Invalid argument value.";
case OV_ENOTVORBIS:
return "Not Vorbis data.";
case OV_EBADHEADER:
return "Invalid Vorbis header.";
case OV_EVERSION:
return "Vorbis version mismatch.";
case OV_ENOTAUDIO:
return "Packet data submitted to vorbis_synthesis is not audio data.";
case OV_EBADPACKET:
return "Invalid packet submitted to vorbis_synthesis.";
case OV_EBADLINK:
return "Invalid stream section supplied to libvorbis/libvorbisfile, or the requested link is corrupt.";
case OV_ENOSEEK:
return "Bitstream is not seekable.";
default:
return "Unknown OpenAL/Ogg error.";
}
}
void check(int32_t show)
{
AL_Error=balcGetError(device);
if (AL_Error!=ALC_NO_ERROR&&show)
initprintf("%s(%s)\n",ALC_ErrorString(AL_Error),ALdoing);
AL_Error=balGetError();
if (AL_Error!= AL_NO_ERROR&&show)
initprintf("%s(%s)\n", AL_ErrorString(AL_Error),ALdoing);
}
extern ov_callbacks cb;
int32_t AL_Init()
{
Bmemset(&music,0,sizeof(music)); // "music.def.size=0" means music not playing
if (loadaldriver())
{
initprintf("Failed loading OpenAL driver.\nDownload OpenAL 1.1 or greater from http://www.openal.org/downloads.html\n");
openal_disabled = 1;
return 1;
}
ALdoing="Init";
// device=alcOpenDevice(ud.config.HardwareAL?"Generic Hardware":"Generic Software");
device=balcOpenDevice(NULL);
check(1);
if (device)
{
context=balcCreateContext(device,NULL);
check(1);
}
if (context)
{
// char *s,*t,*u,i;
balcMakeContextCurrent(context);check(1);
initprintf("OpenAL Information:\n"
" Version: %s\n"
" Vendor: %s\n"
" Renderer: %s\n"
// " Extensions:\n"
,balGetString(AL_VERSION),balGetString(AL_VENDOR),balGetString(AL_RENDERER));
/* s = Bstrdup(balGetString(AL_EXTENSIONS));
if (!s) initprintf(balGetString(AL_EXTENSIONS));
else
{
i = 0; t = u = s;
while (*t)
{
if (*t == ' ')
{
if (i&1)
{
*t = 0;
initprintf(" %s\n",u);
u = t+1;
}
i++;
}
t++;
}
if (i&1) initprintf(" %s\n",u);
Bfree(s);
}
*/
}
else initprintf("OpenAL initialization failed.\n");
return 0;
}
void AL_Stop();
void AL_Shutdown()
{
if (openal_disabled || !device) return;
initprintf("Uninitializing OpenAL...\n");
AL_Stop();
ALdoing="Shut";
balcMakeContextCurrent(NULL);
check(1);
balcDestroyContext(context);
check(1);
balcCloseDevice(device);
unloadaldriver();
}
#define BUFFER_SIZE 65536 // (4096 * 4*8*8)
int32_t AL_MusicVolume;
extern int32_t g_musicSize;
int32_t update();
int32_t stream(ALuint buffer);
void open1(char *ptr,int32_t sizef,char loop);
void AL_Pause() {if (music.def.size)balSourcePause(music.source);}
void AL_Continue() {if (music.def.size)balSourcePlay(music.source);}
void AL_Update() {if (music.def.size&&music.ready&&!update(0))AL_Stop();}
int32_t AL_isntALmusic() {return !music.def.size;}
void AL_SetMusicVolume(int32_t volume)
{
AL_MusicVolume=volume;
if (music.def.size)balSourcef(music.source,AL_GAIN,volume/(255.));
}
int32_t isplaying()
{
ALenum state;
balGetSourcei(music.source,AL_SOURCE_STATE,&state);
return state==AL_PLAYING;
}
int32_t update()
{
int32_t processed=0;
int32_t active=1;
ALuint buffer;
ALdoing="update";
balGetSourcei(music.source,AL_BUFFERS_PROCESSED,&processed);
check(1);
if (processed)
switch (music.type)
{
case 1:
while (processed--)
{
ALdoing="update1";
balSourceUnqueueBuffers(music.source,1,&buffer);
check(1);
active=stream(buffer);
if (active)
{
ALdoing="update2";
balSourceQueueBuffers(music.source,1,&buffer);
check(1);
}
}
break;
}
return active;
}
void AL_Stop()
{
int32_t queued=0;ALuint buffer;
if (!music.def.size)
return;
music.ready=0;
balSourceStop(music.source);
balGetSourcei(music.source,AL_BUFFERS_QUEUED,&queued);
ALdoing="release";
while (queued--)
{
balSourceUnqueueBuffers(music.source,1,&buffer);
check(1);
}
balDeleteSources(1,&music.source);check(1);
balDeleteBuffers(2, music.buffers);check(1);
if (music.type == 1)
ov_clear(&music.def.oggStream);
Bmemset(&music,0,sizeof(music));
}
static char pcm[BUFFER_SIZE];
int32_t stream(ALuint buffer)
{
ALsizei size=0;
int32_t section,result;
while (size<BUFFER_SIZE)
{
result=ov_read(&music.def.oggStream,pcm+size,BUFFER_SIZE-size,0,2,1,&section);
if (result==0&&music.loop)ov_pcm_seek(&music.def.oggStream,0);else
if (result> 0)size+=result;else break;
}
if (!size)
return 0;
ALdoing="stream";
balBufferData(buffer,music.format,pcm,size,music.rate);
check(1);
return 1;
}
void AL_PlaySong(char *ptr,int32_t loop)
{
vorbis_info* vorbisInfo;
int32_t bf=2,i;
if (!context)
return;
Bmemset(&music,0,sizeof(sounddef1));
switch (*ptr)
{
case 'O':
music.type=1;
break;
default:
return;
}
music.def.size=g_musicSize;
music.loop=loop;
music.def.ptrsnd=ptr;
switch (music.type)
{
case 1:
if ((i=ov_open_callbacks(&music.def,&music.def.oggStream,0,0,cb))<0)
{
Bmemset(&music,0,sizeof(sounddef1));
initprintf("Music error: %s\n",AL_ErrorString(i));
return;
}
vorbisInfo=ov_info(&music.def.oggStream,-1);
if (!vorbisInfo)
{
initprintf("Music error: vorbisInfo\n");
Bmemset(&music,0,sizeof(sounddef1));
return;
}
music.rate=vorbisInfo->rate;
music.format=(vorbisInfo->channels==1)?AL_FORMAT_MONO16:AL_FORMAT_STEREO16;
break;
}
ALdoing="Open";
balGenBuffers(2, music.buffers);check(1);
balGenSources(1,&music.source);check(1);
balSourcei(music.source,AL_SOURCE_RELATIVE,AL_TRUE);
switch (music.type)
{
case 1:
stream(music.buffers[0]);
if (!stream(music.buffers[1]))
bf=1;
balSourceQueueBuffers(music.source,bf,music.buffers);
break;
}
AL_SetMusicVolume(AL_MusicVolume);
AL_Continue();
music.ready=1;
}

View file

@ -1,50 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2008 - EDuke32 developers
This file is part of EDuke32
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#ifndef __OPENAL_H
#define __OPENAL_H
#include <vorbis/vorbisfile.h>
int32_t AL_Init();
void AL_Shutdown();
void AL_Update();
char *AL_ErrorString(int32_t code);
char *ALC_ErrorString(int32_t code);
void AL_Stop();
int32_t AL_isntALmusic();
void AL_PlaySong(char *song,int32_t loopflag);
void AL_Pause();
void AL_Continue();
void AL_SetMusicVolume(int32_t volume);
int32_t openal_disabled;
typedef struct sounddef
{
uint32_t pos;
char *ptrsnd;
uint32_t size;
OggVorbis_File oggStream;
} sounddef;
#endif

View file

@ -1,199 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: PITCH.C
author: James R. Dose
date: June 14, 1993
Routines for pitch scaling.
(c) Copyright 1993 James R. Dose. All Rights Reserved.
**********************************************************************/
#include <stdlib.h>
//#include <math.h>
#include "standard.h"
#include "pitch.h"
#define MAXDETUNE 25
static uint32_t PitchTable[ 12 ][ MAXDETUNE ] =
{
{
0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
0x10e98
},
{ 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
0x11eaf },
{ 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
0x12fbc },
{ 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
0x141cb },
{ 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
0x154ee },
{ 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
0x16934 },
{ 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
0x17eae },
{ 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
0x1956f },
{ 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
0x1ad8b },
{ 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
0x1c716 },
{ 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
0x1e225 },
{ 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
0x1fed1 }
};
//static int32_t PITCH_Installed = FALSE;
/*---------------------------------------------------------------------
Function: PITCH_Init
Initializes pitch table.
---------------------------------------------------------------------*/
/*
void PITCH_Init
(
void
)
{
int32_t note;
int32_t detune;
if ( !PITCH_Installed )
{
for( note = 0; note < 12; note++ )
{
for( detune = 0; detune < MAXDETUNE; detune++ )
{
PitchTable[ note ][ detune ] = 0x10000 *
pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
}
}
PITCH_Installed = TRUE;
}
}
*/
/**********************************************************************
Memory locked functions:
**********************************************************************/
/*---------------------------------------------------------------------
Function: PITCH_GetScale
Returns a fixed-point value to scale number the specified amount.
---------------------------------------------------------------------*/
uint32_t PITCH_GetScale
(
int32_t pitchoffset
)
{
uint32_t scale;
int32_t octaveshift;
int32_t noteshift;
int32_t note;
int32_t detune;
// if ( !PITCH_Installed )
// {
// PITCH_Init();
// }
if (pitchoffset == 0)
{
return(PitchTable[ 0 ][ 0 ]);
}
noteshift = pitchoffset % 1200;
if (noteshift < 0)
{
noteshift += 1200;
}
note = noteshift / 100;
detune = (noteshift % 100) / (100 / MAXDETUNE);
octaveshift = (pitchoffset - noteshift) / 1200;
if (detune < 0)
{
detune += (100 / MAXDETUNE);
note--;
if (note < 0)
{
note += 12;
octaveshift--;
}
}
scale = PitchTable[ note ][ detune ];
if (octaveshift < 0)
{
scale >>= -octaveshift;
}
else
{
scale <<= octaveshift;
}
return(scale);
}

View file

@ -1,46 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: PITCH.H
author: James R. Dose
date: June 14, 1994
Public header for PITCH.C
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __PITCH_H
#define __PITCH_H
#include "compat.h"
enum PITCH_ERRORS
{
PITCH_Warning = -2,
PITCH_Error = -1,
PITCH_Ok = 0,
};
//void PITCH_Init( void );
uint32_t PITCH_GetScale( int32_t pitchoffset );
#endif

View file

@ -1,57 +0,0 @@
#ifndef _INCLUDE_PLATFORM_H_
#define _INCLUDE_PLATFORM_H_
#if (!defined __EXPORT__)
#define __EXPORT__
#endif
static __inline uint16_t _swap16(uint16_t D)
{
#if PLATFORM_MACOSX
register uint16_t returnValue;
__asm__ volatile("lhbrx %0,0,%1"
: "=r" (returnValue)
: "r" (&D)
);
return returnValue;
#else
return((D<<8)|(D>>8));
#endif
}
static __inline uint32_t _swap32(uint32_t D)
{
#if PLATFORM_MACOSX
register uint32_t returnValue;
__asm__ volatile("lwbrx %0,0,%1"
: "=r" (returnValue)
: "r" (&D)
);
return returnValue;
#else
return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
#endif
}
#if PLATFORM_MACOSX
#define PLATFORM_BIGENDIAN 1
#define BUILDSWAP_INTEL16(x) _swap16(x)
#define BUILDSWAP_INTEL32(x) _swap32(x)
#else
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define PLATFORM_LITTLEENDIAN 1
#define BUILDSWAP_INTEL16(x) (x)
#define BUILDSWAP_INTEL32(x) (x)
#else
#define PLATFORM_BIGENDIAN 1
#define BUILDSWAP_INTEL16(x) _swap16(x)
#define BUILDSWAP_INTEL32(x) _swap32(x)
#endif
#endif
extern int32_t has_altivec; /* PowerPC-specific. */
#endif /* !defined _INCLUDE_PLATFORM_H_ */
/* end of platform.h ... */

View file

@ -1,418 +0,0 @@
/*
Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
*/
/*
* A reimplementation of Jim Dose's FX_MAN routines, using SDL_mixer 1.2.
* Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for
* short. How strangely appropriate that seems.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include "duke3d.h"
#include "cache1d.h"
#ifndef _MSC_VER
#define cdecl
#endif
#define _NEED_SDLMIXER 1
#include "sdl_inc.h"
#include "music.h"
#define __FX_TRUE (1 == 1)
#define __FX_FALSE (!__FX_TRUE)
#define DUKESND_DEBUG "DUKESND_DEBUG"
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
int32_t MUSIC_ErrorCode = MUSIC_Ok;
static char warningMessage[80];
static char errorMessage[80];
static FILE *debug_file = NULL;
static int32_t initialized_debugging = 0;
static int32_t external_midi = 0;
static int32_t music_initialized = 0;
static int32_t music_context = 0;
static int32_t music_loopflag = MUSIC_PlayOnce;
static Mix_Music *music_musicchunk = NULL;
// static char *music_songdata = NULL;
// This gets called all over the place for information and debugging messages.
// If the user set the DUKESND_DEBUG environment variable, the messages
// go to the file that is specified in that variable. Otherwise, they
// are ignored for the expense of the function call. If DUKESND_DEBUG is
// set to "-" (without the quotes), then the output goes to stdout.
static void musdebug(const char *fmt, ...)
{
va_list ap;
if (debug_file)
{
fprintf(debug_file, "DUKEMUS: ");
va_start(ap, fmt);
vfprintf(debug_file, fmt, ap);
va_end(ap);
fprintf(debug_file, "\n");
fflush(debug_file);
} // if
} // musdebug
static void init_debugging(void)
{
const char *envr;
if (initialized_debugging)
return;
envr = getenv(DUKESND_DEBUG);
if (envr != NULL)
{
if (Bstrcmp(envr, "-") == 0)
debug_file = stdout;
else
debug_file = fopen(envr, "w");
if (debug_file == NULL)
fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n");
else
setbuf(debug_file, NULL);
} // if
initialized_debugging = 1;
} // init_debugging
static void setErrorMessage(const char *msg)
{
Bstrncpy(errorMessage, msg, sizeof(errorMessage));
// strncpy() doesn't add the null char if there isn't room...
errorMessage[sizeof(errorMessage) - 1] = '\0';
musdebug("Error message set to [%s].", errorMessage);
} // setErrorMessage
// The music functions...
char *MUSIC_ErrorString(int32_t ErrorNumber)
{
switch (ErrorNumber)
{
case MUSIC_Warning:
return(warningMessage);
case MUSIC_Error:
return(errorMessage);
case MUSIC_Ok:
return("OK; no error.");
case MUSIC_ASSVersion:
return("Incorrect sound library version.");
case MUSIC_SoundCardError:
return("General sound card error.");
case MUSIC_InvalidCard:
return("Invalid sound card.");
case MUSIC_MidiError:
return("MIDI error.");
case MUSIC_MPU401Error:
return("MPU401 error.");
case MUSIC_TaskManError:
return("Task Manager error.");
//case MUSIC_FMNotDetected:
// return("FM not detected error.");
case MUSIC_DPMI_Error:
return("DPMI error.");
default:
return("Unknown error.");
} // switch
assert(0); // shouldn't hit this point.
return(NULL);
} // MUSIC_ErrorString
int32_t MUSIC_Init(int32_t SoundCard, int32_t Address)
{
// Use an external MIDI player if the user has specified to do so
char *command = getenv("EDUKE32_MUSIC_CMD");
const SDL_version *linked = Mix_Linked_Version();
if (SDL_VERSIONNUM(linked->major,linked->minor,linked->patch) < MIX_REQUIREDVERSION)
{
// reject running with SDL_Mixer versions older than what is stated in sdl_inc.h
initprintf("You need at least v%d.%d.%d of SDL_mixer for music\n",SDL_MIXER_MIN_X,SDL_MIXER_MIN_Y,SDL_MIXER_MIN_Z);
return(MUSIC_Error);
}
external_midi = (command != NULL && command[0] != 0);
if (external_midi)
Mix_SetMusicCMD(command);
else
{
FILE *fp = fopen("/etc/timidity.cfg", "r");
if (fp == NULL)
{
initprintf("Error opening /etc/timidity.cfg: %s\n",strerror(errno));
return MUSIC_Error;
}
Bfclose(fp);
}
init_debugging();
musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
if (music_initialized)
{
setErrorMessage("Music system is already initialized.");
return(MUSIC_Error);
} // if
SoundCard = 1;
music_initialized = 1;
return(MUSIC_Ok);
} // MUSIC_Init
int32_t MUSIC_Shutdown(void)
{
musdebug("shutting down sound subsystem.");
// TODO - make sure this is being called from the menu -- SA
if (external_midi)
Mix_SetMusicCMD(NULL);
MUSIC_StopSong();
music_context = 0;
music_initialized = 0;
music_loopflag = MUSIC_PlayOnce;
return(MUSIC_Ok);
} // MUSIC_Shutdown
void MUSIC_SetMaxFMMidiChannel(int32_t channel)
{
musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
} // MUSIC_SetMaxFMMidiChannel
void MUSIC_SetVolume(int32_t volume)
{
volume = max(0, volume);
volume = min(volume, 255);
Mix_VolumeMusic(volume >> 1); // convert 0-255 to 0-128.
} // MUSIC_SetVolume
void MUSIC_SetMidiChannelVolume(int32_t channel, int32_t volume)
{
musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
} // MUSIC_SetMidiChannelVolume
void MUSIC_ResetMidiChannelVolumes(void)
{
musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
} // MUSIC_ResetMidiChannelVolumes
int32_t MUSIC_GetVolume(void)
{
return(Mix_VolumeMusic(-1) << 1); // convert 0-128 to 0-255.
} // MUSIC_GetVolume
void MUSIC_SetLoopFlag(int32_t loopflag)
{
music_loopflag = loopflag;
} // MUSIC_SetLoopFlag
int32_t MUSIC_SongPlaying(void)
{
return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
} // MUSIC_SongPlaying
void MUSIC_Continue(void)
{
if (Mix_PausedMusic())
Mix_ResumeMusic();
} // MUSIC_Continue
void MUSIC_Pause(void)
{
Mix_PauseMusic();
} // MUSIC_Pause
int32_t MUSIC_StopSong(void)
{
//if (!fx_initialized)
if (!Mix_QuerySpec(NULL, NULL, NULL))
{
setErrorMessage("Need FX system initialized, too. Sorry.");
return(MUSIC_Error);
} // if
if ((Mix_PlayingMusic()) || (Mix_PausedMusic()))
Mix_HaltMusic();
if (music_musicchunk)
Mix_FreeMusic(music_musicchunk);
// if (music_songdata)
// Bfree(music_songdata);
music_musicchunk = NULL;
// music_songdata = NULL;
return(MUSIC_Ok);
} // MUSIC_StopSong
// Duke3D-specific. --ryan.
// void MUSIC_PlayMusic(char *_filename)
int32_t MUSIC_PlaySong(char *song, int32_t loopflag)
{
MUSIC_StopSong();
music_musicchunk = Mix_LoadMUS_RW(SDL_RWFromMem((char *) song, g_musicSize));
if (music_musicchunk != NULL)
{
Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_LoopSong)?-1:0);
} // if
return MUSIC_Ok;
}
void MUSIC_SetContext(int32_t context)
{
musdebug("STUB ... MUSIC_SetContext().\n");
music_context = context;
} // MUSIC_SetContext
int32_t MUSIC_GetContext(void)
{
return(music_context);
} // MUSIC_GetContext
void MUSIC_SetSongTick(uint32_t PositionInTicks)
{
UNREFERENCED_PARAMETER(PositionInTicks);
musdebug("STUB ... MUSIC_SetSongTick().\n");
} // MUSIC_SetSongTick
void MUSIC_SetSongTime(uint32_t milliseconds)
{
UNREFERENCED_PARAMETER(milliseconds);
musdebug("STUB ... MUSIC_SetSongTime().\n");
}// MUSIC_SetSongTime
void MUSIC_SetSongPosition(int32_t measure, int32_t beat, int32_t tick)
{
UNREFERENCED_PARAMETER(measure);
UNREFERENCED_PARAMETER(beat);
UNREFERENCED_PARAMETER(tick);
musdebug("STUB ... MUSIC_SetSongPosition().\n");
} // MUSIC_SetSongPosition
void MUSIC_GetSongPosition(songposition *pos)
{
UNREFERENCED_PARAMETER(pos);
musdebug("STUB ... MUSIC_GetSongPosition().\n");
} // MUSIC_GetSongPosition
void MUSIC_GetSongLength(songposition *pos)
{
UNREFERENCED_PARAMETER(pos);
musdebug("STUB ... MUSIC_GetSongLength().\n");
} // MUSIC_GetSongLength
int32_t MUSIC_FadeVolume(int32_t tovolume, int32_t milliseconds)
{
UNREFERENCED_PARAMETER(tovolume);
Mix_FadeOutMusic(milliseconds);
return(MUSIC_Ok);
} // MUSIC_FadeVolume
int32_t MUSIC_FadeActive(void)
{
return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
} // MUSIC_FadeActive
void MUSIC_StopFade(void)
{
musdebug("STUB ... MUSIC_StopFade().\n");
} // MUSIC_StopFade
void MUSIC_RerouteMidiChannel(int32_t channel, int32_t cdecl(*function)(int32_t event, int32_t c1, int32_t c2))
{
UNREFERENCED_PARAMETER(channel);
UNREFERENCED_PARAMETER(function);
musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
} // MUSIC_RerouteMidiChannel
void MUSIC_RegisterTimbreBank(char *timbres)
{
UNREFERENCED_PARAMETER(timbres);
musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
} // MUSIC_RegisterTimbreBank
void MUSIC_Update(void)
{}

View file

@ -1,275 +0,0 @@
/*
* DirectSound output code for MultiVoc
* by Jonathon Fowler (jonof@edgenetwk.com)
*/
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#include "sdlout.h"
#include "sdl_inc.h"
#include <stdio.h>
#include <string.h>
#include "sdlayer.h"
#if defined(_MSC_VER)
#include <malloc.h>
#endif
#ifndef RENDERTYPESDL
#error The SDL output module for AudioLib only works with the SDL interface.
#endif
static int32_t(*_SDLSOUND_CallBack)(int32_t) = NULL;
static int32_t _SDLSOUND_BufferLength = 0;
static int32_t _SDLSOUND_NumBuffers = 0;
static char *_SDLSOUND_MixBuffer = NULL;
static int32_t SDLSOUND_Installed = FALSE;
int32_t SDLSOUND_ErrorCode = SDLSOUND_Ok;
#define SDLSOUND_SetErrorCode( status ) \
SDLSOUND_ErrorCode = ( status );
static void isr(void *userdata, char *stream, int32_t len);
/*
* DisableInterrupts
* Enter the critical section.
*/
int32_t DisableInterrupts(void)
{
SDL_LockAudio();
return 0;
}
/*
* RestoreInterrupts
* Leave the critical section.
*/
int32_t RestoreInterrupts(int32_t a)
{
SDL_UnlockAudio();
return 0;
a=a;
}
/*
* SDLSOUND_ErrorString
* Returns a description of an error code.
*/
char *SDLSOUND_ErrorString(int32_t errorcode)
{
switch (errorcode)
{
case SDLSOUND_Warning:
case SDLSOUND_Error:
return SDLSOUND_ErrorString(SDLSOUND_ErrorCode);
case SDLSOUND_Ok:
return "SDL Sound ok.";
default:
return "Unknown SDL sound error code.";
}
}
/*
* SDLSOUND_Init
* Initializes the SDL sound objects.
*/
int32_t SDLSOUND_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize)
{
SDL_AudioSpec spec,got;
if (SDLSOUND_Installed)
{
SDLSOUND_Shutdown();
}
initprintf("Initializing SDL sound...\n");
initprintf(" - Requested sound format\n"
" Channels: %d\n"
" Sample rate: %dHz\n"
" Sample size: %d bits\n",
numchannels, mixrate, samplebits);
spec.freq = mixrate;
spec.format = (samplebits == 8 ? AUDIO_U8 : AUDIO_S16LSB);
spec.channels = (numchannels == 1 ? 1:2);
spec.samples = (buffersize >> (spec.channels-1)) >> (samplebits==16);
spec.callback = isr;
spec.userdata = NULL;
SDLSOUND_Installed = TRUE;
SDLSOUND_SetErrorCode(SDLSOUND_Ok);
return SDLSOUND_Ok;
}
/*
* SDLSOUND_Shutdown
* Shuts down SDL sound and it's associates.
*/
int32_t SDLSOUND_Shutdown(void)
{
int32_t i;
if (SDLSOUND_Installed) initprintf("Uninitializing SDL sound...\n");
SDLSOUND_Installed = FALSE;
SDLSOUND_StopPlayback();
SDLSOUND_SetErrorCode(SDLSOUND_Ok);
return SDLSOUND_Ok;
}
/*
* SDLSOUND_SetMixMode
* Bit of filler for the future.
*/
int32_t SDLSOUND_SetMixMode(int32_t mode)
{
return mode;
}
static void isr(void *userdata, char *stream, int32_t len)
{
// otherwise we just service the interrupt
if (_DSOUND_CallBack)
{
p = _DSOUND_CallBack(rv-WAIT_OBJECT_0-1);
hr = IDirectSoundBuffer_Lock(lpDSBSecondary, p*_DSOUND_BufferLength, _DSOUND_BufferLength,
&lockptr, &lockbytes, &lockptr2, &lockbytes2, 0);
if (hr == DSERR_BUFFERLOST)
{
hr = IDirectSoundBuffer_Restore(lpDSBSecondary);
}
if (hr == DS_OK)
{
/*
#define copybuf(S,D,c) \
({ void *__S=(S), *__D=(D); int32_t __c=(c); \
__asm__ __volatile__ ("rep; movsl" \
: "+S" (__S), "+D" (__D), "+c" (__c) : : "memory", "cc"); \
0; })
*/
//copybuf(_DSOUND_MixBuffer + p * _DSOUND_BufferLength, lockptr, _DSOUND_BufferLength >> 2);
Bmemcpy(lockptr, _DSOUND_MixBuffer + p * _DSOUND_BufferLength, _DSOUND_BufferLength);
IDirectSoundBuffer_Unlock(lpDSBSecondary, lockptr, lockbytes, lockptr2, lockbytes2);
}
}
}
}
/*
* SDLSOUND_BeginBufferedPlayback
* Unpause SDL sound playback.
*/
int32_t DSOUND_BeginBufferedPlayback(char *BufferStart, int32_t(*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions)
{
_SDLSOUND_CallBack = CallBackFunc;
_SDLSOUND_MixBuffer = BufferStart;
_SDLSOUND_BufferLength = buffersize/numdivisions;
_SDLSOUND_NumBuffers = numdivisions;
return SDLSOUND_Ok;
}
/*
* DSOUND_StopPlayback
* Halts the playback thread.
*/
int32_t DSOUND_StopPlayback(void)
{
// DWORD exitcode;
BOOL t;
int32_t i;
if (isrthread)
{
SetEvent(isrfinish);
initprintf("DirectSound: Waiting for sound thread to exit\n");
if (WaitForSingleObject(isrthread, 300) == WAIT_OBJECT_0)
initprintf("DirectSound: Sound thread has exited\n");
else
initprintf("DirectSound: Sound thread failed to exit!\n");
/*
while (1) {
if (!GetExitCodeThread(isrthread, &exitcode)) {
DSOUND_SetErrorCode(DSOUND_FailedGetExitCode);
return DSOUND_Warning;
}
if (exitcode != STILL_ACTIVE) break;
}*/
CloseHandle(isrthread);
isrthread = NULL;
}
if (isrfinish)
{
CloseHandle(isrfinish);
isrfinish = NULL;
}
if (lpDSBSecondary)
{
IDirectSoundBuffer_Stop(lpDSBSecondary);
}
if (hPosNotify)
{
for (i=0; i<_DSOUND_NumBuffers; i++)
{
if (hPosNotify[i]) CloseHandle(hPosNotify[i]);
}
free(hPosNotify);
hPosNotify = NULL;
}
return DSOUND_Ok;
}

View file

@ -1,48 +0,0 @@
//-------------------------------------------------------------------------
/*
Duke Nukem Copyright (C) 1996, 2003 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//-------------------------------------------------------------------------
#ifndef __sdlout_h__
#define __sdlout_h__
enum SDLSOUND_ERRORS {
SDLSOUND_Warning = -2,
SDLSOUND_Error = -1,
SDLSOUND_Ok = 0
};
extern int32_t SDLSOUND_ErrorCode;
char *SDLSOUND_ErrorString(int32_t);
int32_t DisableInterrupts(void); // simulated using critical sections
int32_t RestoreInterrupts(int32_t);
int32_t SDLSOUND_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize);
int32_t SDLSOUND_Shutdown(void);
int32_t SDLSOUND_SetMixMode(int32_t mode);
int32_t SDLSOUND_BeginBufferedPlayback(char *BufferStart, int32_t (*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions);
int32_t SDLSOUND_StopPlayback(void);
#endif // __sdlout_h__

View file

@ -1,73 +0,0 @@
/*
Copyright (C) 1994-1995 Apogee Software, Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Modifications for JonoF's port by Jonathon Fowler (jonof@edgenetwk.com)
*/
/**********************************************************************
module: STANDARD.H
author: James R. Dose
date: May 25, 1994
Header containing standard definitions.
(c) Copyright 1994 James R. Dose. All Rights Reserved.
**********************************************************************/
#ifndef __STANDARD_H
#define __STANDARD_H
typedef int boolean;
typedef int errorcode;
#ifndef TRUE
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )
#endif
enum STANDARD_ERRORS
{
Warning = -2,
FatalError = -1,
Success = 0
};
#define BITSET( data, bit ) \
( ( ( data ) & ( bit ) ) == ( bit ) )
#define ARRAY_LENGTH( array ) \
( sizeof( array ) / sizeof( ( array )[ 0 ] ) )
#define WITHIN_BOUNDS( array, index ) \
( ( 0 <= ( index ) ) && ( ( index ) < ARRAY_LENGTH( array ) ) )
#define FOREVER for( ; ; )
#ifdef NDEBUG
#define DEBUGGING 0
#else
#define DEBUGGING 1
#endif
#define DEBUG_CODE \
if ( DEBUGGING == 0 ) \
{ \
} \
else
#endif