mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 06:42:12 +00:00
- replaced the C++ based file access wrapper in ZMusic with a C compatible version.
This commit is contained in:
parent
527fb40a5f
commit
0d000344ca
13 changed files with 144 additions and 52 deletions
|
@ -60,8 +60,7 @@ protected:
|
||||||
virtual ~FileInterface() {}
|
virtual ~FileInterface() {}
|
||||||
public:
|
public:
|
||||||
virtual char* gets(char* buff, int n) = 0;
|
virtual char* gets(char* buff, int n) = 0;
|
||||||
virtual long read(void* buff, int32_t size, int32_t nitems) = 0;
|
virtual long read(void* buff, int32_t size) = 0;
|
||||||
long read(void* buff, int32_t size) { return read(buff, 1, size); }
|
|
||||||
virtual long seek(long offset, int whence) = 0;
|
virtual long seek(long offset, int whence) = 0;
|
||||||
virtual long tell() = 0;
|
virtual long tell() = 0;
|
||||||
virtual void close()
|
virtual void close()
|
||||||
|
@ -101,10 +100,10 @@ struct StdioFileReader : public FileInterface
|
||||||
if (!f) return nullptr;
|
if (!f) return nullptr;
|
||||||
return fgets(buff, n, f);
|
return fgets(buff, n, f);
|
||||||
}
|
}
|
||||||
long read(void* buff, int32_t size, int32_t nitems) override
|
long read(void* buff, int32_t size) override
|
||||||
{
|
{
|
||||||
if (!f) return 0;
|
if (!f) return 0;
|
||||||
return (long)fread(buff, size, nitems, f);
|
return (long)fread(buff, 1, size, f);
|
||||||
}
|
}
|
||||||
long seek(long offset, int whence) override
|
long seek(long offset, int whence) override
|
||||||
{
|
{
|
||||||
|
@ -165,9 +164,9 @@ struct MemoryReader : public FileInterface
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
return strbuf;
|
return strbuf;
|
||||||
}
|
}
|
||||||
long read(void* buff, int32_t size, int32_t nitems) override
|
long read(void* buff, int32_t size) override
|
||||||
{
|
{
|
||||||
long len = long(size) * nitems;
|
long len = long(size);
|
||||||
if (len > mLength - mPos) len = mLength - mPos;
|
if (len > mLength - mPos) len = mLength - mPos;
|
||||||
if (len < 0) len = 0;
|
if (len < 0) len = 0;
|
||||||
memcpy(buff, mData + mPos, len);
|
memcpy(buff, mData + mPos, len);
|
||||||
|
@ -217,8 +216,11 @@ struct VectorReader : public MemoryReader
|
||||||
mLength = (long)mVector.size();
|
mLength = (long)mVector.size();
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
}
|
}
|
||||||
|
VectorReader(uint8_t* data, size_t size)
|
||||||
|
{
|
||||||
|
mVector.resize(size);
|
||||||
|
memcpy(mVector.data(), data, size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ void skip(timidity_file *tf, size_t len)
|
||||||
int tf_getc(timidity_file *tf)
|
int tf_getc(timidity_file *tf)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
auto read = tf_read(&c, 1, 1, tf);
|
auto read = tf_read(&c, 1, tf);
|
||||||
return read == 0 ? EOF : c;
|
return read == 0 ? EOF : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -545,21 +545,21 @@ void Instruments::apply_bank_parameter(Instrument *ip, ToneBankElement *tone)
|
||||||
#define READ_CHAR(thing) { \
|
#define READ_CHAR(thing) { \
|
||||||
uint8_t tmpchar; \
|
uint8_t tmpchar; \
|
||||||
\
|
\
|
||||||
if (tf_read(&tmpchar, 1, 1, tf) != 1) \
|
if (tf_read(&tmpchar, 1, tf) != 1) \
|
||||||
goto fail; \
|
goto fail; \
|
||||||
thing = tmpchar; \
|
thing = tmpchar; \
|
||||||
}
|
}
|
||||||
#define READ_SHORT(thing) { \
|
#define READ_SHORT(thing) { \
|
||||||
uint16_t tmpshort; \
|
uint16_t tmpshort; \
|
||||||
\
|
\
|
||||||
if (tf_read(&tmpshort, 2, 1, tf) != 1) \
|
if (tf_read(&tmpshort, 2, tf) != 2) \
|
||||||
goto fail; \
|
goto fail; \
|
||||||
thing = LE_SHORT(tmpshort); \
|
thing = LE_SHORT(tmpshort); \
|
||||||
}
|
}
|
||||||
#define READ_LONG(thing) { \
|
#define READ_LONG(thing) { \
|
||||||
int32_t tmplong; \
|
int32_t tmplong; \
|
||||||
\
|
\
|
||||||
if (tf_read(&tmplong, 4, 1, tf) != 1) \
|
if (tf_read(&tmplong, 4, tf) != 4) \
|
||||||
goto fail; \
|
goto fail; \
|
||||||
thing = LE_LONG(tmplong); \
|
thing = LE_LONG(tmplong); \
|
||||||
}
|
}
|
||||||
|
@ -661,7 +661,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
|
||||||
skip(tf, 127);
|
skip(tf, 127);
|
||||||
tmp[0] = tf_getc(tf);
|
tmp[0] = tf_getc(tf);
|
||||||
}
|
}
|
||||||
if ((tf_read(tmp + 1, 1, 238, tf) != 238)
|
if ((tf_read(tmp + 1, 238, tf) != 238)
|
||||||
|| (memcmp(tmp, "GF1PATCH110\0ID#000002", 22)
|
|| (memcmp(tmp, "GF1PATCH110\0ID#000002", 22)
|
||||||
&& memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) {
|
&& memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) {
|
||||||
/* don't know what the differences are */
|
/* don't know what the differences are */
|
||||||
|
@ -689,7 +689,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
|
||||||
memset(ip->sample, 0, sizeof(Sample) * ip->samples);
|
memset(ip->sample, 0, sizeof(Sample) * ip->samples);
|
||||||
for (i = 0; i < ip->samples; i++) {
|
for (i = 0; i < ip->samples; i++) {
|
||||||
skip(tf, 7); /* Skip the wave name */
|
skip(tf, 7); /* Skip the wave name */
|
||||||
if (tf_read(&fractions, 1, 1, tf) != 1) {
|
if (tf_read(&fractions, 1, tf) != 1) {
|
||||||
fail:
|
fail:
|
||||||
printMessage(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
|
printMessage(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i);
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
|
@ -738,7 +738,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
|
||||||
else
|
else
|
||||||
sp->panning = (uint8_t)(panning & 0x7f);
|
sp->panning = (uint8_t)(panning & 0x7f);
|
||||||
/* envelope, tremolo, and vibrato */
|
/* envelope, tremolo, and vibrato */
|
||||||
if (tf_read(tmp, 1, 18, tf) != 18)
|
if (tf_read(tmp, 18, tf) != 18)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!tmp[13] || !tmp[14]) {
|
if (!tmp[13] || !tmp[14]) {
|
||||||
sp->tremolo_sweep_increment = sp->tremolo_phase_increment = 0;
|
sp->tremolo_sweep_increment = sp->tremolo_phase_increment = 0;
|
||||||
|
@ -845,7 +845,7 @@ Instrument *Instruments::load_gus_instrument(char *name, ToneBank *bank, int dr,
|
||||||
/* Then read the sample data */
|
/* Then read the sample data */
|
||||||
sp->data = (sample_t *)safe_malloc(sp->data_length + 4);
|
sp->data = (sample_t *)safe_malloc(sp->data_length + 4);
|
||||||
sp->data_alloced = 1;
|
sp->data_alloced = 1;
|
||||||
if ((j = tf_read(sp->data, 1, sp->data_length, tf)) != (int)sp->data_length) {
|
if ((j = tf_read(sp->data, sp->data_length, tf)) != (int)sp->data_length) {
|
||||||
printMessage(CMSG_ERROR, VERB_NORMAL, "Too small this patch length: %d < %d", j, sp->data_length);
|
printMessage(CMSG_ERROR, VERB_NORMAL, "Too small this patch length: %d < %d", j, sp->data_length);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace TimidityPlus
|
||||||
|
|
||||||
static int READCHUNK(SFChunk *vp, timidity_file *tf)
|
static int READCHUNK(SFChunk *vp, timidity_file *tf)
|
||||||
{
|
{
|
||||||
if (tf_read(vp, 8, 1, tf) != 1)
|
if (tf_read(vp, 8, tf) != 8)
|
||||||
return -1;
|
return -1;
|
||||||
vp->size = LE_LONG(vp->size);
|
vp->size = LE_LONG(vp->size);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -74,7 +74,7 @@ static int READCHUNK(SFChunk *vp, timidity_file *tf)
|
||||||
|
|
||||||
static int READDW(uint32_t *vp, timidity_file *tf)
|
static int READDW(uint32_t *vp, timidity_file *tf)
|
||||||
{
|
{
|
||||||
if (tf_read(vp, 4, 1, tf) != 1)
|
if (tf_read(vp, 4, tf) != 4)
|
||||||
return -1;
|
return -1;
|
||||||
*vp = LE_LONG(*vp);
|
*vp = LE_LONG(*vp);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -82,7 +82,7 @@ static int READDW(uint32_t *vp, timidity_file *tf)
|
||||||
|
|
||||||
static int READW(uint16_t *vp, timidity_file *tf)
|
static int READW(uint16_t *vp, timidity_file *tf)
|
||||||
{
|
{
|
||||||
if (tf_read(vp, 2, 1, tf) != 1)
|
if (tf_read(vp, 2, tf) != 2)
|
||||||
return -1;
|
return -1;
|
||||||
*vp = LE_SHORT(*vp);
|
*vp = LE_SHORT(*vp);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -92,7 +92,7 @@ static int READSTR(char *str, timidity_file *tf)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (tf_read(str, 20, 1, tf) != 1)
|
if (tf_read(str, 20, tf) != 20)
|
||||||
return -1;
|
return -1;
|
||||||
str[19] = '\0';
|
str[19] = '\0';
|
||||||
n = (int)strlen(str);
|
n = (int)strlen(str);
|
||||||
|
@ -102,8 +102,8 @@ static int READSTR(char *str, timidity_file *tf)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READID(var,tf) tf_read(var, 4, 1, tf)
|
#define READID(var,tf) tf_read(var, 4, tf)
|
||||||
#define READB(var,tf) tf_read(&var, 1, 1, tf)
|
#define READB(var,tf) tf_read(&var, 1, tf)
|
||||||
#define SKIPB(tf) skip(tf, 1)
|
#define SKIPB(tf) skip(tf, 1)
|
||||||
#define SKIPW(tf) skip(tf, 2)
|
#define SKIPW(tf) skip(tf, 2)
|
||||||
#define SKIPDW(tf) skip(tf, 4)
|
#define SKIPDW(tf) skip(tf, 4)
|
||||||
|
@ -327,7 +327,7 @@ int Instruments::process_info(int size, SFInfo *sf, timidity_file *fd)
|
||||||
case INAM_ID:
|
case INAM_ID:
|
||||||
/* name of the font */
|
/* name of the font */
|
||||||
sf->sf_name = (char*)safe_malloc(chunk.size + 1);
|
sf->sf_name = (char*)safe_malloc(chunk.size + 1);
|
||||||
tf_read(sf->sf_name, 1, chunk.size, fd);
|
tf_read(sf->sf_name, chunk.size, fd);
|
||||||
sf->sf_name[chunk.size] = 0;
|
sf->sf_name[chunk.size] = 0;
|
||||||
printMessage(CMSG_INFO, VERB_DEBUG,
|
printMessage(CMSG_INFO, VERB_DEBUG,
|
||||||
" name %s", sf->sf_name);
|
" name %s", sf->sf_name);
|
||||||
|
|
|
@ -204,20 +204,20 @@ int Instruments::get_next_importer(char *sample_file, int start, int count, Samp
|
||||||
|
|
||||||
/* from instrum.c */
|
/* from instrum.c */
|
||||||
#define READ_CHAR(thing) \
|
#define READ_CHAR(thing) \
|
||||||
if (1 != tf_read(&tmpchar, 1, 1, tf)) goto fail; \
|
if (1 != tf_read(&tmpchar, 1, tf)) goto fail; \
|
||||||
thing = tmpchar;
|
thing = tmpchar;
|
||||||
|
|
||||||
#define READ_SHORT_LE(thing) \
|
#define READ_SHORT_LE(thing) \
|
||||||
if (1 != tf_read(&tmpshort, 2, 1, tf)) goto fail; \
|
if (2 != tf_read(&tmpshort, 2, tf)) goto fail; \
|
||||||
thing = LE_SHORT(tmpshort);
|
thing = LE_SHORT(tmpshort);
|
||||||
#define READ_LONG_LE(thing) \
|
#define READ_LONG_LE(thing) \
|
||||||
if (1 != tf_read(&tmplong, 4, 1, tf)) goto fail; \
|
if (4 != tf_read(&tmplong, 4, tf)) goto fail; \
|
||||||
thing = LE_LONG(tmplong);
|
thing = LE_LONG(tmplong);
|
||||||
#define READ_SHORT_BE(thing) \
|
#define READ_SHORT_BE(thing) \
|
||||||
if (1 != tf_read(&tmpshort, 2, 1, tf)) goto fail; \
|
if (2 != tf_read(&tmpshort, 2, tf)) goto fail; \
|
||||||
thing = BE_SHORT(tmpshort);
|
thing = BE_SHORT(tmpshort);
|
||||||
#define READ_LONG_BE(thing) \
|
#define READ_LONG_BE(thing) \
|
||||||
if (1 != tf_read(&tmplong, 4, 1, tf)) goto fail; \
|
if (4 != tf_read(&tmplong, 4, tf)) goto fail; \
|
||||||
thing = BE_LONG(tmplong);
|
thing = BE_LONG(tmplong);
|
||||||
|
|
||||||
const uint8_t pan_mono[] = {64}; /* center */
|
const uint8_t pan_mono[] = {64}; /* center */
|
||||||
|
@ -280,7 +280,7 @@ int Instruments::import_wave_discriminant(char *sample_file)
|
||||||
|
|
||||||
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (tf_read(buf, 12, 1, tf) != 1
|
if (tf_read(buf, 12, tf) != 12
|
||||||
|| memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0)
|
|| memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0)
|
||||||
{
|
{
|
||||||
tf_close(tf);
|
tf_close(tf);
|
||||||
|
@ -311,7 +311,7 @@ int Instruments::import_wave_load(char *sample_file, Instrument *inst)
|
||||||
|
|
||||||
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (tf_read(buf, 12, 1, tf) != 1
|
if (tf_read(buf, 12, tf) != 12
|
||||||
|| memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0)
|
|| memcmp(&buf[0], "RIFF", 4) != 0 || memcmp(&buf[8], "WAVE", 4) != 0)
|
||||||
{
|
{
|
||||||
tf_close(tf);
|
tf_close(tf);
|
||||||
|
@ -321,7 +321,7 @@ int Instruments::import_wave_load(char *sample_file, Instrument *inst)
|
||||||
state = chunk_flags = 0;
|
state = chunk_flags = 0;
|
||||||
type_index = 4, type_size = 8;
|
type_index = 4, type_size = 8;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (tf_read(&buf[type_index], type_size, 1, tf) != 1)
|
if (tf_read(&buf[type_index], type_size, tf) != type_size)
|
||||||
break;
|
break;
|
||||||
chunk_size = LE_LONG(xbuf.i[2]);
|
chunk_size = LE_LONG(xbuf.i[2]);
|
||||||
if (memcmp(&buf[4 + 0], "fmt ", 4) == 0)
|
if (memcmp(&buf[4 + 0], "fmt ", 4) == 0)
|
||||||
|
@ -553,7 +553,7 @@ int Instruments::import_aiff_discriminant(char *sample_file)
|
||||||
|
|
||||||
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (tf_read(buf, 12, 1, tf) != 1
|
if (tf_read(buf, 12, tf) != 12
|
||||||
|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0
|
|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0
|
||||||
|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))
|
|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))
|
||||||
{
|
{
|
||||||
|
@ -593,7 +593,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst)
|
||||||
|
|
||||||
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
if ((tf = open_file(sample_file, sfreader)) == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (tf_read(buf, 12, 1, tf) != 1
|
if (tf_read(buf, 12, tf) != 12
|
||||||
|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0
|
|| memcmp(&buf[0], "FORM", 4) != 0 || memcmp(&buf[8], "AIF", 3) != 0
|
||||||
|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))
|
|| (buf[8 + 3] != 'F' && buf[8 + 3] != 'C'))
|
||||||
{
|
{
|
||||||
|
@ -608,7 +608,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst)
|
||||||
sound.common = &common;
|
sound.common = &common;
|
||||||
marker_data = NULL;
|
marker_data = NULL;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (tf_read(&buf[type_index], type_size, 1, tf) != 1)
|
if (tf_read(&buf[type_index], type_size, tf) != type_size)
|
||||||
break;
|
break;
|
||||||
chunk_size = BE_LONG(xbuf.i[2]);
|
chunk_size = BE_LONG(xbuf.i[2]);
|
||||||
if (memcmp(&buf[4 + 0], "COMM", 4) == 0)
|
if (memcmp(&buf[4 + 0], "COMM", 4) == 0)
|
||||||
|
@ -666,7 +666,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst)
|
||||||
else if (inst->instname == NULL && memcmp(&buf[4 + 0], "NAME", 4) == 0)
|
else if (inst->instname == NULL && memcmp(&buf[4 + 0], "NAME", 4) == 0)
|
||||||
{
|
{
|
||||||
inst->instname = (char*)malloc(chunk_size + 1);
|
inst->instname = (char*)malloc(chunk_size + 1);
|
||||||
if (tf_read(inst->instname, chunk_size, 1, tf) != 1)
|
if (tf_read(inst->instname, chunk_size, tf) != chunk_size)
|
||||||
{
|
{
|
||||||
chunk_flags |= AIFF_CHUNKFLAG_READERR;
|
chunk_flags |= AIFF_CHUNKFLAG_READERR;
|
||||||
break;
|
break;
|
||||||
|
@ -744,7 +744,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst)
|
||||||
READ_SHORT_BE(comm->numChannels);
|
READ_SHORT_BE(comm->numChannels);
|
||||||
READ_LONG_BE(comm->numSampleFrames);
|
READ_LONG_BE(comm->numSampleFrames);
|
||||||
READ_SHORT_BE(comm->sampleSize);
|
READ_SHORT_BE(comm->sampleSize);
|
||||||
if (tf_read(sampleRate, 10, 1, tf) != 1)
|
if (tf_read(sampleRate, 10, tf) != 10)
|
||||||
goto fail;
|
goto fail;
|
||||||
comm->sampleRate = ConvertFromIeeeExtended(sampleRate);
|
comm->sampleRate = ConvertFromIeeeExtended(sampleRate);
|
||||||
csize -= 8 + 10;
|
csize -= 8 + 10;
|
||||||
|
@ -758,7 +758,7 @@ int Instruments::import_aiff_load(char *sample_file, Instrument *inst)
|
||||||
uint8_t compressionNameLength;
|
uint8_t compressionNameLength;
|
||||||
|
|
||||||
READ_CHAR(compressionNameLength);
|
READ_CHAR(compressionNameLength);
|
||||||
if (tf_read(compressionName, compressionNameLength, 1, tf) != 1)
|
if (tf_read(compressionName, compressionNameLength, tf) != compressionNameLength)
|
||||||
goto fail;
|
goto fail;
|
||||||
compressionName[compressionNameLength] = '\0';
|
compressionName[compressionNameLength] = '\0';
|
||||||
printMessage(CMSG_WARNING, VERB_VERBOSE, "AIFF-C unknown compression type: %s", compressionName);
|
printMessage(CMSG_WARNING, VERB_VERBOSE, "AIFF-C unknown compression type: %s", compressionName);
|
||||||
|
@ -924,7 +924,7 @@ static int AIFFGetMarkerPosition(int16_t id, const AIFFMarkerData *markers, uint
|
||||||
|
|
||||||
#define WAVE_BUF_SIZE (1 << 11) /* should be power of 2 */
|
#define WAVE_BUF_SIZE (1 << 11) /* should be power of 2 */
|
||||||
#define READ_WAVE_SAMPLE(dest, b, s) \
|
#define READ_WAVE_SAMPLE(dest, b, s) \
|
||||||
if (tf_read(dest, (b) * (s), 1, tf) != 1) \
|
if (tf_read(dest, (b) * (s), tf) != (b) * (s)) \
|
||||||
goto fail
|
goto fail
|
||||||
#define READ_WAVE_FRAME(dest, b, f) \
|
#define READ_WAVE_FRAME(dest, b, f) \
|
||||||
READ_WAVE_SAMPLE(dest, b, (f) * channels)
|
READ_WAVE_SAMPLE(dest, b, (f) * channels)
|
||||||
|
|
|
@ -550,7 +550,7 @@ Instrument *Instruments::load_from_file(SFInsts *rec, InstList *ip)
|
||||||
sample->data_alloced = 1;
|
sample->data_alloced = 1;
|
||||||
|
|
||||||
tf_seek(rec->tf, sp->start, SEEK_SET);
|
tf_seek(rec->tf, sp->start, SEEK_SET);
|
||||||
tf_read(sample->data, sp->len, 1, rec->tf);
|
tf_read(sample->data, sp->len, rec->tf);
|
||||||
|
|
||||||
#ifdef _BIG_ENDIAN_
|
#ifdef _BIG_ENDIAN_
|
||||||
tmp = (int16_t*)sample->data;
|
tmp = (int16_t*)sample->data;
|
||||||
|
|
|
@ -39,9 +39,9 @@ inline char* tf_gets(char* buff, int n, timidity_file* tf)
|
||||||
return tf->gets(buff, n);
|
return tf->gets(buff, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long tf_read(void* buff, int32_t size, int32_t nitems, timidity_file* tf)
|
inline long tf_read(void* buff, int32_t size, timidity_file* tf)
|
||||||
{
|
{
|
||||||
return (long)tf->read(buff, size, nitems);
|
return (long)tf->read(buff, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline long tf_seek(timidity_file* tf, long offset, int whence)
|
inline long tf_seek(timidity_file* tf, long offset, int whence)
|
||||||
|
|
|
@ -149,7 +149,7 @@ static bool ungzip(uint8_t *data, int complen, std::vector<uint8_t> &newdata)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
DLL_EXPORT MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args)
|
static MusInfo *ZMusic_OpenSongInternal (MusicIO::FileInterface *reader, EMidiDevice device, const char *Args)
|
||||||
{
|
{
|
||||||
MusInfo *info = nullptr;
|
MusInfo *info = nullptr;
|
||||||
StreamSource *streamsource = nullptr;
|
StreamSource *streamsource = nullptr;
|
||||||
|
@ -294,6 +294,60 @@ DLL_EXPORT MusInfo *ZMusic_OpenSong (MusicIO::FileInterface *reader, EMidiDevice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char* filename, EMidiDevice device, const char* Args)
|
||||||
|
{
|
||||||
|
auto f = MusicIO::utf8_fopen(filename, "rb");
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
SetError("File not found");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto fr = new MusicIO::StdioFileReader;
|
||||||
|
fr->f = f;
|
||||||
|
return ZMusic_OpenSongInternal(fr, device, Args);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void* mem, size_t size, EMidiDevice device, const char* Args)
|
||||||
|
{
|
||||||
|
if (!mem || !size)
|
||||||
|
{
|
||||||
|
SetError("Invalid data");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// Data must be copied because it may be used as a streaming source and we cannot guarantee that the client memory stays valid. We also have no means to free it.
|
||||||
|
auto mr = new MusicIO::VectorReader((uint8_t*)mem, (long)size);
|
||||||
|
return ZMusic_OpenSongInternal(mr, device, Args);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CustomFileReader : public MusicIO::FileInterface
|
||||||
|
{
|
||||||
|
ZMusicCustomReader* cr;
|
||||||
|
|
||||||
|
CustomFileReader(ZMusicCustomReader* zr) : cr(zr) {}
|
||||||
|
virtual char* gets(char* buff, int n) { return cr->gets(cr, buff, n); }
|
||||||
|
virtual long read(void* buff, int32_t size) { return cr->read(cr, buff, size); }
|
||||||
|
virtual long seek(long offset, int whence) { return cr->seek(cr, offset, whence); }
|
||||||
|
virtual long tell() { return cr->tell(cr); }
|
||||||
|
virtual void close()
|
||||||
|
{
|
||||||
|
cr->close(cr);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
DLL_EXPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args)
|
||||||
|
{
|
||||||
|
if (!reader)
|
||||||
|
{
|
||||||
|
SetError("No reader protocol specified");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto cr = new CustomFileReader(reader); // Oh no! We just put another wrapper around the client's wrapper!
|
||||||
|
return ZMusic_OpenSongInternal(cr, device, Args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// play CD music
|
// play CD music
|
||||||
|
|
|
@ -128,11 +128,17 @@ struct Callbacks
|
||||||
MusicIO::SoundFontReaderInterface *(*OpenSoundFont)(const char* name, int type) = nullptr;
|
MusicIO::SoundFontReaderInterface *(*OpenSoundFont)(const char* name, int type) = nullptr;
|
||||||
|
|
||||||
// Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion.
|
// Used to handle client-specific path macros. If not set, the path may not contain any special tokens that may need expansion.
|
||||||
std::string (*NicePath)(const char *path) = nullptr;
|
const char *(*NicePath)(const char* path) = nullptr;
|
||||||
|
};
|
||||||
// For playing modules with compressed samples.
|
|
||||||
short* (*DumbVorbisDecode)(int outlen, const void* oggstream, int sizebytes);
|
|
||||||
|
|
||||||
|
struct ZMusicCustomReader
|
||||||
|
{
|
||||||
|
void* handle;
|
||||||
|
char* (*gets)(ZMusicCustomReader*handle, char* buff, int n);
|
||||||
|
long (*read)(ZMusicCustomReader* handle, void* buff, int32_t size);
|
||||||
|
long (*seek)(ZMusicCustomReader* handle, long offset, int whence);
|
||||||
|
long (*tell)(ZMusicCustomReader* handle);
|
||||||
|
void (*close)(ZMusicCustomReader* handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,7 +168,9 @@ extern "C"
|
||||||
DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype);
|
DLL_IMPORT ZMusic_MidiSource ZMusic_CreateMIDISource(const uint8_t* data, size_t length, EMIDIType miditype);
|
||||||
DLL_IMPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
|
DLL_IMPORT bool ZMusic_MIDIDumpWave(ZMusic_MidiSource source, EMidiDevice devtype, const char* devarg, const char* outname, int subsong, int samplerate);
|
||||||
|
|
||||||
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(MusicIO::FileInterface* reader, EMidiDevice device, const char* Args);
|
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSong(ZMusicCustomReader* reader, EMidiDevice device, const char* Args);
|
||||||
|
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongFile(const char *filename, EMidiDevice device, const char* Args);
|
||||||
|
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenSongMem(const void *mem, size_t size, EMidiDevice device, const char* Args);
|
||||||
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0);
|
DLL_IMPORT ZMusic_MusicStream ZMusic_OpenCDSong(int track, int cdid = 0);
|
||||||
|
|
||||||
DLL_IMPORT bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
|
DLL_IMPORT bool ZMusic_FillStream(ZMusic_MusicStream stream, void* buff, int len);
|
||||||
|
|
|
@ -180,9 +180,10 @@ static void wm_printfunc(const char* wmfmt, va_list args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::string mus_NicePath(const char* str)
|
static FString strv;
|
||||||
|
static const char *mus_NicePath(const char* str)
|
||||||
{
|
{
|
||||||
FString strv = NicePath(str);
|
strv = NicePath(str);
|
||||||
return strv.GetChars();
|
return strv.GetChars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -509,7 +509,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto mreader = new FileReaderMusicInterface(reader);
|
auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper.
|
||||||
mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : "");
|
mus_playing.handle = ZMusic_OpenSong(mreader, devp? (EMidiDevice)devp->device : MDEV_DEFAULT, devp? devp->args.GetChars() : "");
|
||||||
if (mus_playing.handle == nullptr)
|
if (mus_playing.handle == nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../libraries/music_common/fileio.h"
|
#include "../libraries/music_common/fileio.h"
|
||||||
|
#include "zmusic/zmusic.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
|
|
||||||
struct FileReaderMusicInterface : public MusicIO::FileInterface
|
struct FileReaderMusicInterface : public MusicIO::FileInterface
|
||||||
{
|
{
|
||||||
FileReader fr;
|
FileReader fr;
|
||||||
|
@ -16,10 +18,10 @@ struct FileReaderMusicInterface : public MusicIO::FileInterface
|
||||||
if (!fr.isOpen()) return nullptr;
|
if (!fr.isOpen()) return nullptr;
|
||||||
return fr.Gets(buff, n);
|
return fr.Gets(buff, n);
|
||||||
}
|
}
|
||||||
long read(void* buff, int32_t size, int32_t nitems) override
|
long read(void* buff, int32_t size) override
|
||||||
{
|
{
|
||||||
if (!fr.isOpen()) return 0;
|
if (!fr.isOpen()) return 0;
|
||||||
return (long)fr.Read(buff, size * nitems) / size;
|
return (long)fr.Read(buff, size);
|
||||||
}
|
}
|
||||||
long seek(long offset, int whence) override
|
long seek(long offset, int whence) override
|
||||||
{
|
{
|
||||||
|
@ -37,3 +39,20 @@ struct FileReaderMusicInterface : public MusicIO::FileInterface
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline ZMusicCustomReader *GetMusicReader(FileReader& fr)
|
||||||
|
{
|
||||||
|
auto zcr = new ZMusicCustomReader;
|
||||||
|
|
||||||
|
zcr->handle = fr.GetInterface();
|
||||||
|
zcr->gets = [](ZMusicCustomReader* zr, char* buff, int n) { return reinterpret_cast<FileReaderInterface*>(zr->handle)->Gets(buff, n); };
|
||||||
|
zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) { return reinterpret_cast<FileReaderInterface*>(zr->handle)->Read(buff, (long)size); };
|
||||||
|
zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) { return reinterpret_cast<FileReaderInterface*>(zr->handle)->Seek(offset, whence); };
|
||||||
|
zcr->tell = [](ZMusicCustomReader* zr) { return reinterpret_cast<FileReaderInterface*>(zr->handle)->Tell(); };
|
||||||
|
zcr->close = [](ZMusicCustomReader* zr)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<FileReaderInterface*>(zr->handle);
|
||||||
|
delete zr;
|
||||||
|
};
|
||||||
|
return zcr;
|
||||||
|
}
|
|
@ -154,6 +154,14 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is for wrapping the actual reader for custom access where a managed FileReader won't work.
|
||||||
|
FileReaderInterface* GetInterface()
|
||||||
|
{
|
||||||
|
auto i = mReader;
|
||||||
|
mReader = nullptr;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
~FileReader()
|
~FileReader()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue