From 07f35a7008e5425a286773a547fbf2918aa6449d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Apr 2006 12:58:52 +0000 Subject: [PATCH] SVN r44 (trunk) --- FLAC/private/float.h | 97 ++++++++++++++++++ docs/rh-log.txt | 9 ++ src/g_level.cpp | 8 +- src/oplsynth/opl_mus_player.cpp | 19 +++- src/oplsynth/opl_mus_player.h | 2 +- src/p_conversation.cpp | 10 ++ src/s_sound.cpp | 46 +++++++-- src/sound/fmodsound.cpp | 26 ++++- src/sound/i_music.cpp | 165 +++++++++++++++++++----------- src/sound/i_music.h | 2 +- src/sound/i_musicinterns.h | 12 +-- src/sound/music_flac.cpp | 33 +++--- src/sound/music_midi_midiout.cpp | 13 ++- src/sound/music_midi_timidity.cpp | 20 +++- src/sound/music_mod.cpp | 4 +- src/sound/music_mus_midiout.cpp | 14 ++- src/sound/music_mus_opl.cpp | 4 +- src/sound/music_spc.cpp | 22 ++-- src/sound/music_stream.cpp | 4 +- src/sound/sample_flac.h | 3 +- src/w_wad.cpp | 26 +++++ src/w_wad.h | 3 + 22 files changed, 423 insertions(+), 119 deletions(-) create mode 100644 FLAC/private/float.h diff --git a/FLAC/private/float.h b/FLAC/private/float.h new file mode 100644 index 000000000..67a5f266e --- /dev/null +++ b/FLAC/private/float.h @@ -0,0 +1,97 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2004,2005 Josh Coalson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC__PRIVATE__FLOAT_H +#define FLAC__PRIVATE__FLOAT_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "FLAC/ordinals.h" + +/* + * These typedefs make it easier to ensure that integer versions of + * the library really only contain integer operations. All the code + * in libFLAC should use FLAC__float and FLAC__double in place of + * float and double, and be protected by checks of the macro + * FLAC__INTEGER_ONLY_LIBRARY. + * + * FLAC__real is the basic floating point type used in LPC analysis. + */ +#ifndef FLAC__INTEGER_ONLY_LIBRARY +typedef double FLAC__double; +typedef float FLAC__float; +/* + * WATCHOUT: changing FLAC__real will change the signatures of many + * functions that have assembly language equivalents and break them. + */ +typedef float FLAC__real; +#else +/* + * The convention for FLAC__fixedpoint is to use the upper 16 bits + * for the integer part and lower 16 bits for the fractional part. + */ +typedef FLAC__int32 FLAC__fixedpoint; +extern const FLAC__fixedpoint FLAC__FP_ZERO; +extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; +extern const FLAC__fixedpoint FLAC__FP_ONE; +extern const FLAC__fixedpoint FLAC__FP_LN2; +extern const FLAC__fixedpoint FLAC__FP_E; + +#define FLAC__fixedpoint_trunc(x) ((x)>>16) + +#define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) ) + +#define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) + +/* + * FLAC__fixedpoint_log2() + * -------------------------------------------------------------------- + * Returns the base-2 logarithm of the fixed-point number 'x' using an + * algorithm by Knuth for x >= 1.0 + * + * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must + * be < 32 and evenly divisible by 4 (0 is OK but not very precise). + * + * 'precision' roughly limits the number of iterations that are done; + * use (unsigned)(-1) for maximum precision. + * + * If 'x' is less than one -- that is, x < (1<OPLinit (TwoChips + 1, rate)) + + if (file) + { + if (fread (scoredata, 1, len, file) != (size_t)len) + { + delete[] scoredata; + scoredata = NULL; + return; + } + } + else + { + memcpy(scoredata, &musiccache[0], len); + } + + if (io->OPLinit (TwoChips + 1, rate)) { delete[] scoredata; scoredata = NULL; diff --git a/src/oplsynth/opl_mus_player.h b/src/oplsynth/opl_mus_player.h index b0a5e37e8..8bc7edeec 100644 --- a/src/oplsynth/opl_mus_player.h +++ b/src/oplsynth/opl_mus_player.h @@ -11,7 +11,7 @@ class OPLmusicBlock : public musicBlock { public: - OPLmusicBlock (FILE *file, int len, int rate, int maxSamples); + OPLmusicBlock (FILE *file, char * musiccache, int len, int rate, int maxSamples); ~OPLmusicBlock (); bool IsValid () const; diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 417189737..c2d43195e 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -15,6 +15,7 @@ #include "a_strifeglobal.h" #include "a_keys.h" #include "p_enemy.h" +#include "sound/i_music.h" // The conversations as they exist inside a SCRIPTxx lump. struct Response @@ -664,6 +665,12 @@ static void TakeStrifeItem (const TypeInfo *itemtype, int amount) } } +CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE) +{ + if (self < 0.f) self = 0.f; + else if (self > 1.f) self = 1.f; +} + //============================================================================ // // P_StartConversation @@ -723,6 +730,7 @@ void P_StartConversation (AActor *npc, AActor *pc) if (CurNode->SpeakerVoice != 0) { + I_SetMusicVolume(dlg_musicvolume); S_SoundID (npc, CHAN_VOICE, CurNode->SpeakerVoice, 1, ATTN_NORM); } @@ -1043,6 +1051,7 @@ static void PickConversationReply () } ConversationNPC->angle = ConversationNPCAngle; + I_SetMusicVolume(1.f); } //============================================================================ @@ -1075,5 +1084,6 @@ void CleanupConversationMenu () DialogueLines = NULL; } ConversationItems.Clear (); + I_SetMusicVolume(1.f); } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index b1772c33d..d7b87046c 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -265,8 +265,8 @@ void S_NoiseDebug (void) BorderNeedRefresh = screen->GetPageCount (); } -static string LastLocalSndInfo = ""; -static string LastLocalSndSeq = ""; +static string LastLocalSndInfo; +static string LastLocalSndSeq; void S_AddLocalSndInfo(int lump); //========================================================================== @@ -1414,6 +1414,8 @@ bool S_StartMusic (const char *m_id) // specified, it will only be played if the specified CD is in a drive. //========================================================================== +TArray musiccache; + bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) { if (!force && PlayList) @@ -1467,8 +1469,24 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) Printf ("Music \"%s\" not found\n", musicname); return false; } - offset = Wads.GetLumpOffset (lumpnum); - length = Wads.LumpLength (lumpnum); + if (!Wads.IsUncompressedFile(lumpnum)) + { + // We must cache the music data and use it from memory. + + // shut down old music before reallocating and overwriting the cache! + S_StopMusic (true); + + offset = -1; // this tells the low level code that the music + // is being used from memory + length = Wads.LumpLength (lumpnum); + musiccache.Resize(length); + Wads.ReadLump(lumpnum, &musiccache[0]); + } + else + { + offset = Wads.GetLumpOffset (lumpnum); + length = Wads.LumpLength (lumpnum); + } } else { @@ -1480,13 +1498,27 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force) S_StopMusic (true); // load & register it + + // Note by Graf Zahl: S_StopMusic NULLs this variable so there's nothing to delete anymore! + /* if (mus_playing.name) { delete[] mus_playing.name; } - mus_playing.handle = I_RegisterSong (lumpnum != -1 ? - Wads.GetWadFullName (Wads.GetLumpFile (lumpnum)) : - musicname, offset, length); + */ + + if (offset!=-1) + { + mus_playing.handle = I_RegisterSong (lumpnum != -1 ? + Wads.GetWadFullName (Wads.GetLumpFile (lumpnum)) : + musicname, NULL, offset, length); + } + else + { + // musiccache is used globally because otherwise I'd have to pass + // it as a parameter through several layers of code. + mus_playing.handle = I_RegisterSong (NULL, &musiccache[0], -1, length); + } } mus_playing.loop = looping; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index f5e7accac..ee385b0eb 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -611,11 +611,19 @@ SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int return NULL; } -SoundStream *FMODSoundRenderer::OpenStream (const char *filename, int flags, int offset, int length) +SoundStream *FMODSoundRenderer::OpenStream (const char *filename_or_data, int flags, int offset, int length) { unsigned int mode = FSOUND_NORMAL | FSOUND_2D; if (flags & SoundStream::Loop) mode |= FSOUND_LOOP_NORMAL; - FSOUND_STREAM *stream = FSOUND_Stream_Open (filename, mode, offset, length); + FSOUND_STREAM *stream; + + if (offset==-1) + { + mode |= FSOUND_LOADMEMORY; + offset=0; + } + stream = FSOUND_Stream_Open (filename_or_data, mode, offset, length); + if (stream != NULL) { return new FMODStreamCapsule (stream); @@ -623,9 +631,19 @@ SoundStream *FMODSoundRenderer::OpenStream (const char *filename, int flags, int return NULL; } -SoundTrackerModule *FMODSoundRenderer::OpenModule (const char *filename, int offset, int length) +SoundTrackerModule *FMODSoundRenderer::OpenModule (const char *filename_or_data, int offset, int length) { - FMUSIC_MODULE *mod = FMUSIC_LoadSongEx (filename, offset, length, FSOUND_LOOP_NORMAL, NULL, 0); + FMUSIC_MODULE *mod; + + int mode = FSOUND_LOOP_NORMAL; + if (offset==-1) + { + mode |= FSOUND_LOADMEMORY; + offset=0; + } + + mod = FMUSIC_LoadSongEx (filename_or_data, offset, length, mode, NULL, 0); + if (mod != NULL) { return new FMUSICCapsule (mod); diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 5e215b1fc..42a54320e 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -84,6 +84,7 @@ static bool MusicDown = true; MusInfo *currSong; int nomusic = 0; float relative_volume = 1.f; +float saved_relative_volume = 1.0f; // this could be used to implement an ACS FadeMusic function //========================================================================== // @@ -159,7 +160,7 @@ void I_PlaySong (void *handle, int _looping, float rel_vol) if (!info || nomusic) return; - relative_volume = rel_vol; + saved_relative_volume = relative_volume = rel_vol; info->Stop (); info->Play (_looping ? true : false); @@ -207,7 +208,7 @@ void I_UnRegisterSong (void *handle) } } -void *I_RegisterSong (const char *filename, int offset, int len) +void *I_RegisterSong (const char *filename, char * musiccache, int offset, int len) { FILE *file; MusInfo *info = NULL; @@ -218,63 +219,72 @@ void *I_RegisterSong (const char *filename, int offset, int len) return 0; } - file = fopen (filename, "rb"); - if (file == NULL) + if (offset!=-1) { - return 0; - } + file = fopen (filename, "rb"); + if (file == NULL) + { + return 0; + } - if (len == 0 && offset == 0) - { - fseek (file, 0, SEEK_END); - len = ftell (file); - fseek (file, 0, SEEK_SET); - } - else - { - fseek (file, offset, SEEK_SET); - } + if (len == 0 && offset == 0) + { + fseek (file, 0, SEEK_END); + len = ftell (file); + fseek (file, 0, SEEK_SET); + } + else + { + fseek (file, offset, SEEK_SET); + } - if (fread (&id, 4, 1, file) != 1) - { - fclose (file); - return 0; + if (fread (&id, 4, 1, file) != 1) + { + fclose (file); + return 0; + } + fseek (file, -4, SEEK_CUR); + } + else + { + file = NULL; + memcpy(&id, &musiccache[0], 4); } - fseek (file, -4, SEEK_CUR); // Check for MUS format if (id == MAKE_ID('M','U','S',0x1a)) { if (GSnd != NULL && opl_enable) { - info = new OPLMUSSong (file, len); + info = new OPLMUSSong (file, musiccache, len); } if (info == NULL) { #ifdef _WIN32 if (snd_mididevice != -2) { - info = new MUSSong2 (file, len); + info = new MUSSong2 (file, musiccache, len); } else if (GSnd != NULL) #endif // _WIN32 { - info = new TimiditySong (file, len); + info = new TimiditySong (file, musiccache, len); } } } // Check for MIDI format else if (id == MAKE_ID('M','T','h','d')) { + // This is a midi file #ifdef _WIN32 if (snd_mididevice != -2) { - info = new MIDISong2 (file, len); + info = new MIDISong2 (file, musiccache, len); } else if (GSnd != NULL) #endif // _WIN32 { - info = new TimiditySong (file, len); + info = new TimiditySong (file, musiccache, len); } } // Check for SPC format @@ -283,22 +293,32 @@ void *I_RegisterSong (const char *filename, int offset, int len) { char header[0x23]; - if (fread (header, 1, 0x23, file) != 0x23) + if (file != NULL) { - fclose (file); - return 0; + if (fread (header, 1, 0x23, file) != 0x23) + { + fclose (file); + return 0; + } + fseek (file, -0x23, SEEK_CUR); } - fseek (file, -0x23, SEEK_CUR); - if (strncmp (header+4, "-SPC700 Sound File Data", 23) == 0) + else { - info = new SPCSong (file, len); + memcpy(header, musiccache, 0x23); + } + + if (strncmp (header+4, "-SPC700 Sound File Data", 23) == 0 && + header[0x21] == '\x1a' && + header[0x22] == '\x1a') + { + info = new SPCSong (file, musiccache, len); } } #endif // Check for FLAC format else if (id == MAKE_ID('f','L','a','C')) { - info = new FLACSong (file, len); + info = new FLACSong (file, musiccache, len); file = NULL; } // Check for RDosPlay raw OPL format @@ -306,15 +326,23 @@ void *I_RegisterSong (const char *filename, int offset, int len) { DWORD fullsig[2]; - if (fread (fullsig, 4, 2, file) != 2) + if (file != NULL) { - fclose (file); - return 0; + if (fread (fullsig, 4, 2, file) != 2) + { + fclose (file); + return 0; + } + fseek (file, -8, SEEK_CUR); } - fseek (file, -8, SEEK_CUR); + else + { + memcpy(fullsig, musiccache, 8); + } + if (fullsig[1] == MAKE_ID('D','A','T','A')) { - info = new OPLMUSSong (file, len); + info = new OPLMUSSong (file, musiccache, len); } } // Check for Martin Fernandez's modified IMF format @@ -322,15 +350,22 @@ void *I_RegisterSong (const char *filename, int offset, int len) { char fullhead[6]; - if (fread (fullhead, 1, 6, file) != 6) + if (file != NULL) { - fclose (file); - return 0; + if (fread (fullhead, 1, 6, file) != 6) + { + fclose (file); + return 0; + } + fseek (file, -6, SEEK_CUR); + } + else + { + memcpy(fullhead, musiccache, 6); } - fseek (file, -6, SEEK_CUR); if (fullhead[4] == 'B' && fullhead[5] == 1) { - info = new OPLMUSSong (file, len); + info = new OPLMUSSong (file, musiccache, len); } } @@ -339,20 +374,23 @@ void *I_RegisterSong (const char *filename, int offset, int len) // Check for CDDA "format" if (id == (('R')|(('I')<<8)|(('F')<<16)|(('F')<<24))) { - DWORD subid; - - fseek (file, 8, SEEK_CUR); - if (fread (&subid, 4, 1, file) != 1) + if (file != NULL) { - fclose (file); - return 0; - } - fseek (file, -12, SEEK_CUR); + DWORD subid; - if (subid == (('C')|(('D')<<8)|(('D')<<16)|(('A')<<24))) - { - // This is a CDDA file - info = new CDDAFile (file, len); + fseek (file, 8, SEEK_CUR); + if (fread (&subid, 4, 1, file) != 1) + { + fclose (file); + return 0; + } + fseek (file, -12, SEEK_CUR); + + if (subid == (('C')|(('D')<<8)|(('D')<<16)|(('A')<<24))) + { + // This is a CDDA file + info = new CDDAFile (file, len); + } } } @@ -363,13 +401,13 @@ void *I_RegisterSong (const char *filename, int offset, int len) if (info == NULL && GSnd != NULL && len >= 1024) { // First try loading it as MOD, then as a stream - fclose (file); + if (file != NULL) fclose (file); file = NULL; - info = new MODSong (filename, offset, len); + info = new MODSong (offset>=0? filename : musiccache, offset, len); if (!info->IsValid ()) { delete info; - info = new StreamSong (filename, offset, len); + info = new StreamSong (offset>=0? filename : musiccache, offset, len); } } } @@ -416,6 +454,17 @@ bool I_SetSongPosition (void *handle, int order) return info ? info->SetPosition (order) : false; } +// Sets relative music volume. Takes $musicvolume in SNDINFO into consideration +void I_SetMusicVolume (float factor) +{ + factor = clamp(factor, 0, 2.0f); + relative_volume = saved_relative_volume * factor; +#ifdef _WIN32 + snd_midivolume.Callback(); +#endif + snd_musicvolume.Callback(); +} + CCMD(testmusicvol) { if (argv.argc() > 1) diff --git a/src/sound/i_music.h b/src/sound/i_music.h index 95e4e0ba1..ae666503c 100644 --- a/src/sound/i_music.h +++ b/src/sound/i_music.h @@ -53,7 +53,7 @@ void I_PauseSong (void *handle); void I_ResumeSong (void *handle); // Registers a song handle to song data. -void *I_RegisterSong (const char *file, int offset, int length); +void *I_RegisterSong (const char *file, char * musiccache, int offset, int length); void *I_RegisterCDSong (int track, int cdid = 0); // Called by anything that wishes to start music. diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index e31a95d22..6b2e8b0e4 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -57,7 +57,7 @@ public: class MUSSong2 : public MusInfo { public: - MUSSong2 (FILE *file, int length); + MUSSong2 (FILE *file, char * musiccache, int length); ~MUSSong2 (); void SetVolume (float volume); @@ -102,7 +102,7 @@ protected: class MIDISong2 : public MusInfo { public: - MIDISong2 (FILE *file, int length); + MIDISong2 (FILE *file, char * musiccache, int length); ~MIDISong2 (); void SetVolume (float volume); @@ -204,7 +204,7 @@ typedef void *(__stdcall *EmuAPU_TYPE) (void *, DWORD, BYTE); class SPCSong : public StreamSong { public: - SPCSong (FILE *file, int length); + SPCSong (FILE *file, char * musiccache, int length); ~SPCSong (); void Play (bool looping); bool IsPlaying (); @@ -241,7 +241,7 @@ protected: class TimiditySong : public StreamSong { public: - TimiditySong (FILE *file, int length); + TimiditySong (FILE *file, char * musiccache, int length); ~TimiditySong (); void Play (bool looping); void Stop (); @@ -278,7 +278,7 @@ protected: class OPLMUSSong : public StreamSong { public: - OPLMUSSong (FILE *file, int length); + OPLMUSSong (FILE *file, char * musiccache, int length); ~OPLMUSSong (); void Play (bool looping); bool IsPlaying (); @@ -296,7 +296,7 @@ protected: class FLACSong : public StreamSong { public: - FLACSong (FILE *file, int length); + FLACSong (FILE *file, char * musiccache, int length); ~FLACSong (); void Play (bool looping); bool IsPlaying (); diff --git a/src/sound/music_flac.cpp b/src/sound/music_flac.cpp index 3b9fff4e6..f81779a29 100644 --- a/src/sound/music_flac.cpp +++ b/src/sound/music_flac.cpp @@ -9,7 +9,7 @@ class FLACSong::FLACStreamer : protected FLAC::Decoder::Stream { public: - FLACStreamer (FILE *file, int length); + FLACStreamer (FILE *file, char * musiccache, int length); ~FLACStreamer (); bool ServiceStream (void *buff, int len, bool loop); @@ -24,7 +24,7 @@ protected: void CopyToStream (void *&sbuff, FLAC__int32 **buffer, size_t ofs, size_t samples); - FileReader File; + FileReader *File; long StartPos, EndPos; FLAC__int32 *SamplePool[2]; @@ -36,10 +36,10 @@ protected: size_t SLen; }; -FLACSong::FLACSong (FILE *file, int length) +FLACSong::FLACSong (FILE *file, char * musiccache, int length) : State (NULL) { - State = new FLACStreamer (file, length); + State = new FLACStreamer (file, musiccache, length); if (State->NumChannels > 0 && State->SampleBits > 0 && State->SampleRate > 0) { @@ -107,17 +107,25 @@ bool FLACSong::FillStream (SoundStream *stream, void *buff, int len, void *userd return song->State->ServiceStream (buff, len, song->m_Looping); } -FLACSong::FLACStreamer::FLACStreamer (FILE *iofile, int length) +FLACSong::FLACStreamer::FLACStreamer (FILE *iofile, char * musiccache, int length) : NumChannels (0), SampleBits (0), SampleRate (0), - File (iofile, length), PoolSize (0), PoolUsed (0), PoolPos (0) { - StartPos = File.Tell(); - EndPos = StartPos + File.GetLength(); + if (iofile != NULL) + { + File = new FileReader (iofile, length); + } + else + { + File = new MemoryReader(musiccache, length); + } + + StartPos = File->Tell(); + EndPos = StartPos + File->GetLength(); init (); process_until_end_of_metadata (); } @@ -129,7 +137,8 @@ FLACSong::FLACStreamer::~FLACStreamer () delete[] SamplePool[0]; SamplePool[0] = NULL; } - fclose (File.GetFile()); + if (File->GetFile()!=NULL) fclose (File->GetFile()); + delete File; } bool FLACSong::FLACStreamer::ServiceStream (void *buff1, int len, bool loop) @@ -172,7 +181,7 @@ bool FLACSong::FLACStreamer::ServiceStream (void *buff1, int len, bool loop) { return FALSE; } - File.Seek (StartPos, SEEK_SET); + File->Seek (StartPos, SEEK_SET); reset (); } @@ -237,7 +246,7 @@ void FLACSong::FLACStreamer::CopyToStream (void *&sbuff, FLAC__int32 **buffer, s { if (*bytes > 0) { - long here = File.Tell(); + long here = File->Tell(); if (here == EndPos) { return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; @@ -248,7 +257,7 @@ void FLACSong::FLACStreamer::CopyToStream (void *&sbuff, FLAC__int32 **buffer, s { *bytes = EndPos - here; } - File.Read (buffer, *bytes); + File->Read (buffer, *bytes); return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } } diff --git a/src/sound/music_midi_midiout.cpp b/src/sound/music_midi_midiout.cpp index ac81e3819..103aa72f2 100644 --- a/src/sound/music_midi_midiout.cpp +++ b/src/sound/music_midi_midiout.cpp @@ -33,7 +33,7 @@ extern UINT mididevice; static BYTE EventLengths[7] = { 2, 2, 2, 2, 1, 1, 2 }; static BYTE CommonLengths[15] = { 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -MIDISong2::MIDISong2 (FILE *file, int len) +MIDISong2::MIDISong2 (FILE *file, char * musiccache, int len) : MidiOut (0), PlayerThread (0), PauseEvent (0), ExitEvent (0), VolumeChangeEvent (0), MusHeader (0) @@ -42,8 +42,15 @@ MIDISong2::MIDISong2 (FILE *file, int len) int i; MusHeader = new BYTE[len]; - if (fread (MusHeader, 1, len, file) != (size_t)len) - return; + if (file != NULL) + { + if (fread (MusHeader, 1, len, file) != (size_t)len) + return; + } + else + { + memcpy(MusHeader, musiccache, len); + } // Do some validation of the MIDI file if (MusHeader[4] != 0 || MusHeader[5] != 0 || MusHeader[6] != 0 || MusHeader[7] != 6) diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 672eff50c..b6c274b7e 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -160,7 +160,7 @@ TimiditySong::~TimiditySong () #endif } -TimiditySong::TimiditySong (FILE *file, int len) +TimiditySong::TimiditySong (FILE *file, char * musiccache, int len) : DiskName ("zmid"), #ifdef _WIN32 ReadWavePipe (INVALID_HANDLE_VALUE), WriteWavePipe (INVALID_HANDLE_VALUE), @@ -191,8 +191,15 @@ TimiditySong::TimiditySong (FILE *file, int len) return; } - BYTE *buf = new BYTE[len]; - fread (buf, 1, len, file); + BYTE *buf; + + if (file!=NULL) + { + buf = new BYTE[len]; + fread (buf, 1, len, file); + } + else buf = (BYTE*)musiccache; + // The file type has already been checked before this class instance was // created, so we only need to check one character to determine if this @@ -205,8 +212,11 @@ TimiditySong::TimiditySong (FILE *file, int len) { success = ProduceMIDI (buf, f); } - fclose (f); - delete[] buf; + if (file!=NULL) + { + fclose (f); + delete[] buf; + } if (success) { diff --git a/src/sound/music_mod.cpp b/src/sound/music_mod.cpp index c20815e40..f17915ec5 100644 --- a/src/sound/music_mod.cpp +++ b/src/sound/music_mod.cpp @@ -57,9 +57,9 @@ MODSong::~MODSong () } } -MODSong::MODSong (const char *file, int offset, int length) +MODSong::MODSong (const char *file_or_data, int offset, int length) { - m_Module = GSnd->OpenModule (file, offset, length); + m_Module = GSnd->OpenModule (file_or_data, offset, length); } bool MODSong::IsPlaying () diff --git a/src/sound/music_mus_midiout.cpp b/src/sound/music_mus_midiout.cpp index 27ed8aec5..b1a3bf0c4 100644 --- a/src/sound/music_mus_midiout.cpp +++ b/src/sound/music_mus_midiout.cpp @@ -28,14 +28,22 @@ static const BYTE CtrlTranslate[15] = 121, // reset all controllers }; -MUSSong2::MUSSong2 (FILE *file, int len) +MUSSong2::MUSSong2 (FILE *file, char * musiccache, int len) : MidiOut (0), PlayerThread (0), PauseEvent (0), ExitEvent (0), VolumeChangeEvent (0), MusBuffer (0), MusHeader (0) { MusHeader = (MUSHeader *)new BYTE[len]; - if (fread (MusHeader, 1, len, file) != (size_t)len) - return; + + if (file != NULL) + { + if (fread (MusHeader, 1, len, file) != (size_t)len) + return; + } + else + { + memcpy(MusHeader, musiccache, len); + } // Do some validation of the MUS file if (MusHeader->Magic != MAKE_ID('M','U','S','\x1a')) diff --git a/src/sound/music_mus_opl.cpp b/src/sound/music_mus_opl.cpp index 4c657fef5..8b51c520c 100644 --- a/src/sound/music_mus_opl.cpp +++ b/src/sound/music_mus_opl.cpp @@ -21,12 +21,12 @@ CUSTOM_CVAR (Bool, opl_onechip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } -OPLMUSSong::OPLMUSSong (FILE *file, int len) +OPLMUSSong::OPLMUSSong (FILE *file, char * musiccache, int len) { int rate = *opl_frequency; int samples = rate/14; - Music = new OPLmusicBlock (file, len, rate, samples); + Music = new OPLmusicBlock (file, musiccache, len, rate, samples); m_Stream = GSnd->CreateStream (FillStream, samples*2, SoundStream::Mono, rate, this); diff --git a/src/sound/music_spc.cpp b/src/sound/music_spc.cpp index 694940df0..889ca674c 100644 --- a/src/sound/music_spc.cpp +++ b/src/sound/music_spc.cpp @@ -46,15 +46,19 @@ CUSTOM_CVAR (Int, spc_frequency, 32000, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } } -SPCSong::SPCSong (FILE *iofile, int len) +SPCSong::SPCSong (FILE *iofile, char * musiccache, int len) { - FileReader file (iofile, len); if (!LoadEmu ()) { return; } + FileReader * file; + + if (iofile != NULL) file = new FileReader(iofile, len); + else file = new MemoryReader(musiccache, len); + // No sense in using a higher frequency than the final output int freq = MIN (*spc_frequency, *snd_samplerate); @@ -69,6 +73,7 @@ SPCSong::SPCSong (FILE *iofile, int len) { Printf (PRINT_BOLD, "Could not create music stream.\n"); CloseEmu (); + delete file; return; } @@ -78,7 +83,7 @@ SPCSong::SPCSong (FILE *iofile, int len) BYTE spcfile[66048]; - file.Read (spcfile, 66048); + file->Read (spcfile, 66048); if (LoadSPCFile != NULL) { @@ -104,19 +109,19 @@ SPCSong::SPCSong (FILE *iofile, int len) { DWORD id; - file.Read (&id, 4); + file->Read (&id, 4); if (id == MAKE_ID('x','i','d','6')) { DWORD size; - file >> size; + (*file) >> size; DWORD pos = 66056; while (pos < size) { XID6Tag tag; - file.Read (&tag, 4); + file->Read (&tag, 4); if (tag.Type == 0) { // Don't care about these @@ -128,7 +133,7 @@ SPCSong::SPCSong (FILE *iofile, int len) if (tag.Type == 4 && tag.ID == 0x36) { DWORD amp; - file >> amp; + (*file) >> amp; if (APUVersion < 98) { amp >>= 12; @@ -137,11 +142,12 @@ SPCSong::SPCSong (FILE *iofile, int len) break; } } - file.Seek (LittleShort(tag.Value), SEEK_CUR); + file->Seek (LittleShort(tag.Value), SEEK_CUR); } } } } + delete file; } SPCSong::~SPCSong () diff --git a/src/sound/music_stream.cpp b/src/sound/music_stream.cpp index 5c5de7597..5ff42e8ce 100644 --- a/src/sound/music_stream.cpp +++ b/src/sound/music_stream.cpp @@ -54,9 +54,9 @@ StreamSong::~StreamSong () } } -StreamSong::StreamSong (const char *filename, int offset, int len) +StreamSong::StreamSong (const char *filename_or_data, int offset, int len) { - m_Stream = GSnd->OpenStream (filename, SoundStream::Loop, offset, len); + m_Stream = GSnd->OpenStream (filename_or_data, SoundStream::Loop, offset, len); } bool StreamSong::IsPlaying () diff --git a/src/sound/sample_flac.h b/src/sound/sample_flac.h index a037ccd84..b4ebdf5af 100644 --- a/src/sound/sample_flac.h +++ b/src/sound/sample_flac.h @@ -3,6 +3,7 @@ #include #include "s_sound.h" #include "files.h" +#include "w_wad.h" class FLACSampleLoader : protected FLAC::Decoder::Stream { @@ -23,7 +24,7 @@ protected: void CopyToSample (size_t ofs, FLAC__int32 **buffer, size_t samples); - FileReader File; + FWadLump File; long StartPos, EndPos; void *SBuff, *SBuff2; diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 290840744..a254c6e6b 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1271,6 +1271,32 @@ const char *FWadCollection::GetWadFullName (int wadnum) const } +//========================================================================== +// +// IsUncompressedFile +// +// Returns true when the lump is available as an uncompressed portion of +// a file. The music player can play such lumps by streaming but anything +// else has to be loaded into memory first. +// +//========================================================================== + +bool FWadCollection::IsUncompressedFile(int lump) const +{ + /* + if ((unsigned)lump >= (unsigned)NumLumps) + { + I_Error ("IsUncompressedFile: %u >= NumLumps",lump); + } + + LumpRecord * l = &LumpInfo[lump]; + + if (l->flags & LUMPF_COMPRESSED) return false; + else if (Wads[l->wadnum]->MemoryData!=NULL) return false; + */ + return true; +} + //========================================================================== // // W_SkinHack diff --git a/src/w_wad.h b/src/w_wad.h index 20520d1ad..94b9c8404 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -30,10 +30,12 @@ #define IWAD_ID (('I'<<24)|('W'<<16)|('A'<<8)|('D')) #define PWAD_ID (('P'<<24)|('W'<<16)|('A'<<8)|('D')) #define RFF_ID (('R'<<24)|('F'<<16)|('F'<<8)|(0x1a)) +#define ZIP_ID (('P'<<24)|('K'<<16)|(3<<8)|(4)) #else #define IWAD_ID (('I')|('W'<<8)|('A'<<16)|('D'<<24)) #define PWAD_ID (('P')|('W'<<8)|('A'<<16)|('D'<<24)) #define RFF_ID (('R')|('F'<<8)|('F'<<16)|(0x1a<<24)) +#define ZIP_ID (('P')|('K'<<8)|(3<<16)|(4<<24)) #endif // [RH] Remove limit on number of WAD files @@ -167,6 +169,7 @@ public: int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match + bool IsUncompressedFile(int lump) const; int GetNumLumps () const; protected: