mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-28 23:02:07 +00:00
- made WildMidi a library.
This commit is contained in:
parent
a562d69ec3
commit
4ba8da290c
17 changed files with 396 additions and 12 deletions
|
@ -387,6 +387,7 @@ set( ADL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/adlmidi" )
|
||||||
set( OPN_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/opnmidi" )
|
set( OPN_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/opnmidi" )
|
||||||
set( TIMIDITYPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/timidityplus" )
|
set( TIMIDITYPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/timidityplus" )
|
||||||
set( TIMIDITY_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/timidity" )
|
set( TIMIDITY_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/timidity" )
|
||||||
|
set( WILDMIDI_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/wildmidi" )
|
||||||
|
|
||||||
if( NOT CMAKE_CROSSCOMPILING )
|
if( NOT CMAKE_CROSSCOMPILING )
|
||||||
if( NOT CROSS_EXPORTS )
|
if( NOT CROSS_EXPORTS )
|
||||||
|
@ -412,6 +413,7 @@ add_subdirectory( libraries/adlmidi )
|
||||||
add_subdirectory( libraries/opnmidi )
|
add_subdirectory( libraries/opnmidi )
|
||||||
add_subdirectory( libraries/timidity )
|
add_subdirectory( libraries/timidity )
|
||||||
add_subdirectory( libraries/timidityplus )
|
add_subdirectory( libraries/timidityplus )
|
||||||
|
add_subdirectory( libraries/wildmidi )
|
||||||
add_subdirectory( wadsrc )
|
add_subdirectory( wadsrc )
|
||||||
add_subdirectory( wadsrc_bm )
|
add_subdirectory( wadsrc_bm )
|
||||||
add_subdirectory( wadsrc_lights )
|
add_subdirectory( wadsrc_lights )
|
||||||
|
|
24
libraries/wildmidi/CMakeLists.txt
Normal file
24
libraries/wildmidi/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
cmake_minimum_required( VERSION 2.8.7 )
|
||||||
|
|
||||||
|
make_release_only()
|
||||||
|
|
||||||
|
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
|
||||||
|
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" )
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ZD_FASTMATH_FLAG}")
|
||||||
|
|
||||||
|
include_directories( wildmidi )
|
||||||
|
|
||||||
|
file( GLOB HEADER_FILES
|
||||||
|
wildmidi/*.h
|
||||||
|
)
|
||||||
|
add_library( wildmidi STATIC
|
||||||
|
file_io.cpp
|
||||||
|
gus_pat.cpp
|
||||||
|
reverb.cpp
|
||||||
|
wildmidi_lib.cpp
|
||||||
|
wm_error.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries( wildmidi )
|
|
@ -37,7 +37,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "wm_error.h"
|
#include "wm_error.h"
|
|
@ -468,7 +468,7 @@ set( ZDOOM_LIBS ${ZDOOM_LIBS} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_L
|
||||||
if (HAVE_VULKAN)
|
if (HAVE_VULKAN)
|
||||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} "glslang" "SPIRV" "OGLCompiler")
|
set( ZDOOM_LIBS ${ZDOOM_LIBS} "glslang" "SPIRV" "OGLCompiler")
|
||||||
endif()
|
endif()
|
||||||
include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" "${ADL_INCLUDE_DIR}" "${OPN_INCLUDE_DIR}" "${TIMIDITYPP_INCLUDE_DIR}" "${TIMIDITY_INCLUDE_DIR}" )
|
include_directories( "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${GME_INCLUDE_DIR}" "${ADL_INCLUDE_DIR}" "${OPN_INCLUDE_DIR}" "${TIMIDITYPP_INCLUDE_DIR}" "${TIMIDITY_INCLUDE_DIR}" "${WILDMIDI_INCLUDE_DIR}" )
|
||||||
|
|
||||||
if( ${HAVE_VM_JIT} )
|
if( ${HAVE_VM_JIT} )
|
||||||
add_definitions( -DHAVE_VM_JIT )
|
add_definitions( -DHAVE_VM_JIT )
|
||||||
|
@ -693,7 +693,6 @@ file( GLOB HEADER_FILES
|
||||||
sound/oplsynth/*.h
|
sound/oplsynth/*.h
|
||||||
sound/oplsynth/dosbox/*.h
|
sound/oplsynth/dosbox/*.h
|
||||||
sound/thirdparty/*.h
|
sound/thirdparty/*.h
|
||||||
sound/wildmidi/*.h
|
|
||||||
rendering/*.h
|
rendering/*.h
|
||||||
rendering/2d/*.h
|
rendering/2d/*.h
|
||||||
rendering/swrenderer/*.h
|
rendering/swrenderer/*.h
|
||||||
|
@ -1219,11 +1218,6 @@ set (PCH_SOURCES
|
||||||
sound/oplsynth/dosbox/opl.cpp
|
sound/oplsynth/dosbox/opl.cpp
|
||||||
sound/oplsynth/OPL3.cpp
|
sound/oplsynth/OPL3.cpp
|
||||||
sound/oplsynth/nukedopl3.cpp
|
sound/oplsynth/nukedopl3.cpp
|
||||||
sound/wildmidi/file_io.cpp
|
|
||||||
sound/wildmidi/gus_pat.cpp
|
|
||||||
sound/wildmidi/reverb.cpp
|
|
||||||
sound/wildmidi/wildmidi_lib.cpp
|
|
||||||
sound/wildmidi/wm_error.cpp
|
|
||||||
rendering/swrenderer/textures/r_swtexture.cpp
|
rendering/swrenderer/textures/r_swtexture.cpp
|
||||||
rendering/swrenderer/textures/warptexture.cpp
|
rendering/swrenderer/textures/warptexture.cpp
|
||||||
rendering/swrenderer/textures/swcanvastexture.cpp
|
rendering/swrenderer/textures/swcanvastexture.cpp
|
||||||
|
@ -1320,7 +1314,7 @@ if( UNIX )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma adl opn timidity timidityplus )
|
target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma adl opn timidity timidityplus wildmidi )
|
||||||
|
|
||||||
include_directories( .
|
include_directories( .
|
||||||
g_statusbar
|
g_statusbar
|
||||||
|
@ -1338,7 +1332,6 @@ include_directories( .
|
||||||
sound/music
|
sound/music
|
||||||
sound/backend
|
sound/backend
|
||||||
sound/oplsynth
|
sound/oplsynth
|
||||||
sound/wildmidi
|
|
||||||
xlat
|
xlat
|
||||||
utility
|
utility
|
||||||
utility/nodebuilder
|
utility/nodebuilder
|
||||||
|
@ -1450,7 +1443,6 @@ source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/soun
|
||||||
source_group("Audio Files\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/backend/.+")
|
source_group("Audio Files\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/backend/.+")
|
||||||
source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/oplsynth/.+")
|
source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/oplsynth/.+")
|
||||||
source_group("Audio Files\\OPL Synth\\DOSBox" FILES sound/oplsynth/dosbox/opl.cpp sound/oplsynth/dosbox/opl.h)
|
source_group("Audio Files\\OPL Synth\\DOSBox" FILES sound/oplsynth/dosbox/opl.cpp sound/oplsynth/dosbox/opl.h)
|
||||||
source_group("Audio Files\\WildMidi" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/wildmidi/.+")
|
|
||||||
source_group("Audio Files\\MIDI Devices" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/mididevices/.+")
|
source_group("Audio Files\\MIDI Devices" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/mididevices/.+")
|
||||||
source_group("Audio Files\\MIDI Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/midisources/.+")
|
source_group("Audio Files\\MIDI Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/midisources/.+")
|
||||||
source_group("Audio Files\\Music formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/musicformats/.+")
|
source_group("Audio Files\\Music formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/musicformats/.+")
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "timiditypp/timidity_file.h"
|
#include "timiditypp/timidity_file.h"
|
||||||
#include "timidity/timidity_file.h"
|
#include "timidity/timidity_file.h"
|
||||||
#include "wildmidi_file.h"
|
#include "wildmidi/wildmidi_file.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
366
src/sound/musicformats/music_xa.cpp
Normal file
366
src/sound/musicformats/music_xa.cpp
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
#include "i_musicinterns.h"
|
||||||
|
/**
|
||||||
|
* PlayStation XA (ADPCM) source support for MultiVoc
|
||||||
|
* Adapted and remixed from superxa2wav (taken from EDuke32)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//#define NO_XA_HEADER
|
||||||
|
|
||||||
|
#define kNumOfSamples 224
|
||||||
|
#define kNumOfSGs 18
|
||||||
|
#define TTYWidth 80
|
||||||
|
|
||||||
|
#define kBufSize (kNumOfSGs*kNumOfSamples)
|
||||||
|
#define kSamplesMono (kNumOfSGs*kNumOfSamples)
|
||||||
|
#define kSamplesStereo (kNumOfSGs*kNumOfSamples/2)
|
||||||
|
|
||||||
|
/* ADPCM */
|
||||||
|
#define XA_DATA_START (0x44-48)
|
||||||
|
|
||||||
|
#define DblToPCMF(dt) ((dt) / 32768.f)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FileReader reader;
|
||||||
|
size_t committed;
|
||||||
|
bool blockIsMono;
|
||||||
|
bool blockIs18K;
|
||||||
|
bool finished;
|
||||||
|
|
||||||
|
double t1, t2;
|
||||||
|
double t1_x, t2_x;
|
||||||
|
|
||||||
|
float block[kBufSize];
|
||||||
|
} xa_data;
|
||||||
|
|
||||||
|
typedef int8_t SoundGroup[128];
|
||||||
|
|
||||||
|
typedef struct XASector {
|
||||||
|
int8_t sectorFiller[48];
|
||||||
|
SoundGroup SoundGroups[18];
|
||||||
|
} XASector;
|
||||||
|
|
||||||
|
static double K0[4] = {
|
||||||
|
0.0,
|
||||||
|
0.9375,
|
||||||
|
1.796875,
|
||||||
|
1.53125
|
||||||
|
};
|
||||||
|
static double K1[4] = {
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
-0.8125,
|
||||||
|
-0.859375
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int8_t getSoundData(int8_t *buf, int32_t unit, int32_t sample)
|
||||||
|
{
|
||||||
|
int8_t ret;
|
||||||
|
int8_t *p;
|
||||||
|
int32_t offset, shift;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
shift = (unit%2) * 4;
|
||||||
|
|
||||||
|
offset = 16 + (unit / 2) + (sample * 4);
|
||||||
|
p += offset;
|
||||||
|
|
||||||
|
ret = (*p >> shift) & 0x0F;
|
||||||
|
|
||||||
|
if (ret > 7) {
|
||||||
|
ret -= 16;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t getFilter(const int8_t *buf, int32_t unit)
|
||||||
|
{
|
||||||
|
return (*(buf + 4 + unit) >> 4) & 0x03;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int8_t getRange(const int8_t *buf, int32_t unit)
|
||||||
|
{
|
||||||
|
return *(buf + 4 + unit) & 0x0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void decodeSoundSectMono(XASector *ssct, xa_data * xad)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
int8_t snddat, filt, range;
|
||||||
|
int32_t unit, sample;
|
||||||
|
int32_t sndgrp;
|
||||||
|
double tmp2, tmp3, tmp4, tmp5;
|
||||||
|
int8_t &decodeBuf = xad->block;
|
||||||
|
|
||||||
|
for (sndgrp = 0; sndgrp < kNumOfSGs; sndgrp++)
|
||||||
|
{
|
||||||
|
for (unit = 0; unit < 8; unit++)
|
||||||
|
{
|
||||||
|
range = getRange(ssct->SoundGroups[sndgrp], unit);
|
||||||
|
filt = getFilter(ssct->SoundGroups[sndgrp], unit);
|
||||||
|
for (sample = 0; sample < 28; sample++)
|
||||||
|
{
|
||||||
|
snddat = getSoundData(ssct->SoundGroups[sndgrp], unit, sample);
|
||||||
|
tmp2 = (double)(1 << (12 - range));
|
||||||
|
tmp3 = (double)snddat * tmp2;
|
||||||
|
tmp4 = xad->t1 * K0[filt];
|
||||||
|
tmp5 = xad->t2 * K1[filt];
|
||||||
|
xad->t2 = xad->t1;
|
||||||
|
xad->t1 = tmp3 + tmp4 + tmp5;
|
||||||
|
decodeBuf[count++] = DblToPCM(xad->t1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decodeSoundSectStereo(XASector *ssct, xa_data * xad)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
int8_t snddat, filt, range;
|
||||||
|
int8_t filt1, range1;
|
||||||
|
int16_t decoded;
|
||||||
|
int32_t unit, sample;
|
||||||
|
int32_t sndgrp;
|
||||||
|
double tmp2, tmp3, tmp4, tmp5;
|
||||||
|
int8_t &decodeBuf = xad->block;
|
||||||
|
|
||||||
|
for (sndgrp = 0; sndgrp < kNumOfSGs; sndgrp++)
|
||||||
|
{
|
||||||
|
for (unit = 0; unit < 8; unit+= 2)
|
||||||
|
{
|
||||||
|
range = getRange(ssct->SoundGroups[sndgrp], unit);
|
||||||
|
filt = getFilter(ssct->SoundGroups[sndgrp], unit);
|
||||||
|
range1 = getRange(ssct->SoundGroups[sndgrp], unit+1);
|
||||||
|
filt1 = getFilter(ssct->SoundGroups[sndgrp], unit+1);
|
||||||
|
|
||||||
|
for (sample = 0; sample < 28; sample++)
|
||||||
|
{
|
||||||
|
// Channel 1
|
||||||
|
snddat = getSoundData(ssct->SoundGroups[sndgrp], unit, sample);
|
||||||
|
tmp2 = (double)(1 << (12 - range));
|
||||||
|
tmp3 = (double)snddat * tmp2;
|
||||||
|
tmp4 = xad->t1 * K0[filt];
|
||||||
|
tmp5 = xad->t2 * K1[filt];
|
||||||
|
xad->t2 = xad->t1;
|
||||||
|
xad->t1 = tmp3 + tmp4 + tmp5;
|
||||||
|
decodeBuf[count++] = DblToPCMF(xad->t1);
|
||||||
|
|
||||||
|
// Channel 2
|
||||||
|
snddat = getSoundData(ssct->SoundGroups[sndgrp], unit+1, sample);
|
||||||
|
tmp2 = (double)(1 << (12 - range1));
|
||||||
|
tmp3 = (double)snddat * tmp2;
|
||||||
|
tmp4 = xad->t1_x * K0[filt1];
|
||||||
|
tmp5 = xad->t2_x * K1[filt1];
|
||||||
|
xad->t2_x = xad->t1_x;
|
||||||
|
xad->t1_x = tmp3 + tmp4 + tmp5;
|
||||||
|
decodeBuf[count++] = DblToPCMF(xad->t1_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Get one decoded block of data
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static bool getNextXABlock(xa_data *xad, bool looping )
|
||||||
|
{
|
||||||
|
XASector ssct;
|
||||||
|
int coding;
|
||||||
|
const int SUBMODE_REAL_TIME_SECTOR = (1 << 6);
|
||||||
|
const int SUBMODE_FORM = (1 << 5);
|
||||||
|
const int SUBMODE_AUDIO_DATA = (1 << 2);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
size_t bytes = xad->reader.GetLength() - xad->reader.Tell();
|
||||||
|
|
||||||
|
if (sizeof(XASector) < bytes)
|
||||||
|
bytes = sizeof(XASector);
|
||||||
|
|
||||||
|
xad->reader.Read(&ssct, bytes);
|
||||||
|
}
|
||||||
|
while (ssct.sectorFiller[46] != (SUBMODE_REAL_TIME_SECTOR | SUBMODE_FORM | SUBMODE_AUDIO_DATA));
|
||||||
|
|
||||||
|
coding = ssct.sectorFiller[47];
|
||||||
|
|
||||||
|
xa->blockIsMono = (coding & 3) == 0;
|
||||||
|
xa->blockIs18K = (((coding >> 2) & 3) == 1);
|
||||||
|
|
||||||
|
uint32_t samples;
|
||||||
|
|
||||||
|
if (!xa->blockIsMono)
|
||||||
|
{
|
||||||
|
decodeSoundSectStereo(&ssct, xad);
|
||||||
|
samples = kSamplesStereo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decodeSoundSectMono(&ssct, xad);
|
||||||
|
samples = kSamplesMono;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xad->GetLength() == xad->Tell())
|
||||||
|
{
|
||||||
|
if (looping)
|
||||||
|
{
|
||||||
|
xad->pos = XA_DATA_START;
|
||||||
|
xad->t1 = xad->t2 = xad->t1_x = xad->t2_x = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
xa->finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
xa->finished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class XASong : public StreamSong
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GMESong(FileReader & readr);
|
||||||
|
~GMESong();
|
||||||
|
bool SetSubsong(int subsong);
|
||||||
|
void Play(bool looping, int subsong);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
xa_data xad;
|
||||||
|
|
||||||
|
static bool Read(SoundStream *stream, void *buff, int len, void *userdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong - Constructor
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
XASong::XASong(FileReader &reader)
|
||||||
|
{
|
||||||
|
ChannelConfig iChannels;
|
||||||
|
SampleType Type;
|
||||||
|
|
||||||
|
|
||||||
|
xad.ptr = std::move(reader);
|
||||||
|
xad.pos = XA_DATA_START;
|
||||||
|
xad.t1 = xad.t2 = xad.t1_x = xad.t2_x = 0;
|
||||||
|
getNextXABlock(&xad, false);
|
||||||
|
auto SampleRate = xad.blockIs18K? 18900 : 37800;
|
||||||
|
|
||||||
|
const uint32_t sampleLength = (uint32_t)decoder->getSampleLength();
|
||||||
|
Reader = std::move(reader);
|
||||||
|
Decoder = decoder;
|
||||||
|
Channels = 2; // Since the format can theoretically switch between mono and stereo we need to output everything as stereo.
|
||||||
|
m_Stream = GSnd->CreateStream(Read, 64 * 1024, 0, SampleRate, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong - Destructor
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
XASong::~XASong()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
if (m_Stream != nullptr)
|
||||||
|
{
|
||||||
|
delete m_Stream;
|
||||||
|
m_Stream = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong :: Play
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void XASong::Play(bool looping, int track)
|
||||||
|
{
|
||||||
|
m_Status = STATE_Stopped;
|
||||||
|
m_Looping = looping;
|
||||||
|
if (xad.finished && looping)
|
||||||
|
{
|
||||||
|
xad.pos = XA_DATA_START;
|
||||||
|
xad.t1 = xad.t2 = xad.t1_x = xad.t2_x = 0;
|
||||||
|
xad.reader.Seek(0, FileReader::SeekSet);
|
||||||
|
xad.finished = false;
|
||||||
|
}
|
||||||
|
if (m_Stream->Play(looping, 1))
|
||||||
|
{
|
||||||
|
m_Status = STATE_Playing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong :: SetSubsong
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool XASong::SetSubsong(int track)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XASong :: Read STATIC
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool XASong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdata)
|
||||||
|
{
|
||||||
|
auto self = (XASong*)userdata;
|
||||||
|
while (ilen > 0)
|
||||||
|
{
|
||||||
|
if (self->xad.committed < kBufSize)
|
||||||
|
{
|
||||||
|
// commit the data
|
||||||
|
if (self->xad.blockIsMono)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self->xad.finished)
|
||||||
|
{
|
||||||
|
// fill the rest with 0's.
|
||||||
|
}
|
||||||
|
if (ilen > 0)
|
||||||
|
{
|
||||||
|
// we ran out of data and need more
|
||||||
|
getNextXABlock(&self->xad, m_Looping);
|
||||||
|
// repeat until done.
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return !self->xad.finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// XA_OpenSong
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
MusInfo *XA_OpenSong(FileReader &reader)
|
||||||
|
{
|
||||||
|
return new XASong(reader);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue