2006-04-13 22:35:56 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
#include "i_musicinterns.h"
|
|
|
|
#include "templates.h"
|
|
|
|
#include "c_cvars.h"
|
|
|
|
#include "doomdef.h"
|
2008-03-11 22:17:57 +00:00
|
|
|
#include "SNES_SPC.h"
|
|
|
|
#include "SPC_Filter.h"
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
struct XID6Tag
|
|
|
|
{
|
|
|
|
BYTE ID;
|
|
|
|
BYTE Type;
|
|
|
|
WORD Value;
|
|
|
|
};
|
|
|
|
|
|
|
|
EXTERN_CVAR (Int, snd_samplerate)
|
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
CVAR (Float, spc_amp, 1.875f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
CUSTOM_CVAR (Int, spc_frequency, 32000, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|
|
|
{
|
|
|
|
if (spc_frequency < 8000)
|
|
|
|
{
|
|
|
|
spc_frequency = 8000;
|
|
|
|
}
|
2008-03-11 22:17:57 +00:00
|
|
|
else if (spc_frequency > 32000)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-03-11 22:17:57 +00:00
|
|
|
spc_frequency = 32000;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
SPCSong::SPCSong (FILE *iofile, char *musiccache, int len)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-03-11 22:17:57 +00:00
|
|
|
FileReader *file;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
if (iofile != NULL)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
2008-03-11 22:17:57 +00:00
|
|
|
file = new FileReader(iofile, len);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
file = new MemoryReader(musiccache, len);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
2006-04-14 12:58:52 +00:00
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
// No sense in using a higher frequency than the final output
|
|
|
|
int freq = MIN (*spc_frequency, *snd_samplerate);
|
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
SPC = new SNES_SPC;
|
|
|
|
SPC->init();
|
|
|
|
Filter = new SPC_Filter;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
BYTE spcfile[66048];
|
|
|
|
|
2006-04-14 12:58:52 +00:00
|
|
|
file->Read (spcfile, 66048);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
SPC->load_spc(spcfile, 66048);
|
|
|
|
SPC->clear_echo();
|
|
|
|
Filter->set_gain(int(SPC_Filter::gain_unit * spc_amp));
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2008-03-11 22:17:57 +00:00
|
|
|
m_Stream = GSnd->CreateStream (FillStream, 16384, 0, freq, this);
|
|
|
|
if (m_Stream == NULL)
|
|
|
|
{
|
|
|
|
Printf (PRINT_BOLD, "Could not create music stream.\n");
|
|
|
|
delete file;
|
|
|
|
return;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Search for amplification tag in extended ID666 info
|
|
|
|
if (len > 66056)
|
|
|
|
{
|
|
|
|
DWORD id;
|
|
|
|
|
2006-04-14 12:58:52 +00:00
|
|
|
file->Read (&id, 4);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (id == MAKE_ID('x','i','d','6'))
|
|
|
|
{
|
|
|
|
DWORD size;
|
|
|
|
|
2006-04-14 12:58:52 +00:00
|
|
|
(*file) >> size;
|
2006-02-24 04:48:15 +00:00
|
|
|
DWORD pos = 66056;
|
|
|
|
|
|
|
|
while (pos < size)
|
|
|
|
{
|
|
|
|
XID6Tag tag;
|
|
|
|
|
2006-04-14 12:58:52 +00:00
|
|
|
file->Read (&tag, 4);
|
2006-02-24 04:48:15 +00:00
|
|
|
if (tag.Type == 0)
|
|
|
|
{
|
|
|
|
// Don't care about these
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pos + LittleShort(tag.Value) <= size)
|
|
|
|
{
|
|
|
|
if (tag.Type == 4 && tag.ID == 0x36)
|
|
|
|
{
|
|
|
|
DWORD amp;
|
2006-04-14 12:58:52 +00:00
|
|
|
(*file) >> amp;
|
2008-03-11 22:17:57 +00:00
|
|
|
Filter->set_gain(amp >> 8);
|
2006-02-24 04:48:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-04-14 12:58:52 +00:00
|
|
|
file->Seek (LittleShort(tag.Value), SEEK_CUR);
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-04-14 12:58:52 +00:00
|
|
|
delete file;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SPCSong::~SPCSong ()
|
|
|
|
{
|
2008-03-11 22:17:57 +00:00
|
|
|
Stop();
|
|
|
|
delete Filter;
|
|
|
|
delete SPC;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SPCSong::IsValid () const
|
|
|
|
{
|
2008-03-11 22:17:57 +00:00
|
|
|
return SPC != NULL;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool SPCSong::IsPlaying ()
|
|
|
|
{
|
|
|
|
return m_Status == STATE_Playing;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SPCSong::Play (bool looping)
|
|
|
|
{
|
|
|
|
m_Status = STATE_Stopped;
|
|
|
|
m_Looping = true;
|
|
|
|
|
VERY IMPORTANT NOTE FOR ANYBODY BUILDING FROM THE TRUNK: This commit adds support
for FMOD Ex while at the same time removing support for FMOD 3. Be sure to update
your SDKs. GCC users, be sure to do a "make cleandep && make clean" before
building, or you will likely get inexplicable errors.
- Fixed: If you wanted to make cleandep with MinGW, you had to specifically
specify Makefile.mingw as the makefile to use.
- Added a normalizer to the OPL synth. It helped bring up the volume a little,
but not nearly as much as I would have liked.
- Removed MIDI Mapper references. It doesn't work with the stream API, and
it doesn't really exist on NT kernels, either.
- Reworked music volume: Except for MIDI, all music volume is controlled
through GSnd and not at the individual song level.
- Removed the mididevice global variable.
- Removed snd_midivolume. Now that all music uses a linear volume scale,
there's no need for two separate music volume controls.
- Increased snd_samplerate default up to 48000.
- Added snd_format, defaulting to "PCM-16".
- Added snd_speakermode, defaulting to "Auto".
- Replaced snd_fpu with snd_resampler, defaulting to "Linear".
- Bumped the snd_channels default up from a pitiful 12 to 32.
- Changed snd_3d default to true. The new cvar snd_hw3d determines if
hardware 3D support is used and default to false.
- Removed the libFLAC source, since FMOD Ex has native FLAC support.
- Removed the altsound code, since it was terribly gimped in comparison to
the FMOD code. It's original purpose was to have been as a springboard for
writing a non-FMOD sound system for Unix-y systems, but that never
happened.
- Finished preliminary FMOD Ex support.
SVN r789 (trunk)
2008-03-09 03:13:49 +00:00
|
|
|
if (m_Stream->Play (true, snd_musicvolume, false))
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
m_Status = STATE_Playing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SPCSong::FillStream (SoundStream *stream, void *buff, int len, void *userdata)
|
|
|
|
{
|
|
|
|
SPCSong *song = (SPCSong *)userdata;
|
2008-03-11 22:17:57 +00:00
|
|
|
song->SPC->play(len >> 1, (short *)buff);
|
|
|
|
song->Filter->run((short *)buff, len >> 1);
|
2006-02-24 04:48:15 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-04-13 22:35:56 +00:00
|
|
|
#endif
|