Minor changes.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@654 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f221d365d8
commit
bc96256164
@ -2,6 +2,7 @@ SubDir OBOS_TOP src tests kits midi synth_file_reader ;
|
|||||||
|
|
||||||
SimpleTest sfr
|
SimpleTest sfr
|
||||||
: SynthFileReader.cpp
|
: SynthFileReader.cpp
|
||||||
|
SynthFile.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
: be root game
|
: be root game
|
||||||
;
|
;
|
||||||
|
@ -9,16 +9,26 @@ chunks:
|
|||||||
-------
|
-------
|
||||||
next[4] | tag[4]
|
next[4] | tag[4]
|
||||||
|
|
||||||
tag:
|
tags:
|
||||||
----
|
-----
|
||||||
|
|
||||||
|
'INST'
|
||||||
|
'snd '
|
||||||
|
'CACH'
|
||||||
|
|
||||||
|
|
||||||
|
'INST'
|
||||||
|
------
|
||||||
'INST' | instr[4] | nameLen[1] | name[nameLen] | dataSize[4] | data[dataSize]
|
'INST' | instr[4] | nameLen[1] | name[nameLen] | dataSize[4] | data[dataSize]
|
||||||
| sndId[2] | ???[10] | size[2] | ???[size*8+21] | rest[dataSize-...] |
|
| sndId[2] | ???[10] | size[2] | insts[size*8+21] | rest[dataSize-...] |
|
||||||
|
|
||||||
'snd ' | sndId[4] | nameLen[1] | name[nameLen] | dataSize[4] | [28] |
|
|
||||||
rate[2] | ...
|
|
||||||
|
|
||||||
data[dataSize]:
|
insts[size*8+21]:
|
||||||
----------------
|
noteStart[1] | noteEnd[1] | sndId[2] | ??[4] | repeats number of size times
|
||||||
|
??[21]
|
||||||
|
|
||||||
|
rest[dataSize]:
|
||||||
|
|
||||||
ADSR | [1] | [4] | [4] |
|
ADSR | [1] | [4] | [4] |
|
||||||
LINE | [4] | [4] |
|
LINE | [4] | [4] |
|
||||||
SUST | [4] | [4] |
|
SUST | [4] | [4] |
|
||||||
@ -33,4 +43,13 @@ VOLU | [1] | [4] | [4] |
|
|||||||
SPAN | [1] | [4] | [4] |
|
SPAN | [1] | [4] | [4] |
|
||||||
TRIA | [4] | [4] |
|
TRIA | [4] | [4] |
|
||||||
SQU2 | [8] |
|
SQU2 | [8] |
|
||||||
SQUA | [8] |
|
SQUA | [8] |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'snd '
|
||||||
|
------
|
||||||
|
'snd ' | sndId[4] | nameLen[1] | name[nameLen] | dataSize[4] | [28] |
|
||||||
|
rate[2] | ?[10] | 255 | drumId | ...
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,13 +29,14 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SynthFileReader.h"
|
#include "SynthFileReader.h"
|
||||||
|
#include "SynthFile.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
|
|
||||||
SynthFileReader::SynthFileReader(const char* synthFile) {
|
SSynthFileReader::SSynthFileReader(const char* synthFile) {
|
||||||
fFile = fopen(synthFile, "r+b");
|
fFile = fopen(synthFile, "r+b");
|
||||||
tag tag;
|
tag tag;
|
||||||
if (fFile) {
|
if (fFile) {
|
||||||
@ -47,29 +48,29 @@ SynthFileReader::SynthFileReader(const char* synthFile) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SynthFileReader::~SynthFileReader() {
|
SSynthFileReader::~SSynthFileReader() {
|
||||||
if (fFile) {
|
if (fFile) {
|
||||||
fclose(fFile); fFile = NULL;
|
fclose(fFile); fFile = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::InitCheck() const {
|
status_t SSynthFileReader::InitCheck() const {
|
||||||
return fFile != NULL;
|
return fFile != NULL ? B_OK : B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::TagEquals(const char* tag1, const char* tag2) const {
|
bool SSynthFileReader::TagEquals(const char* tag1, const char* tag2) const {
|
||||||
return strncmp(tag1, tag2, 4) == 0;
|
return strncmp(tag1, tag2, 4) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Read(void* data, uint32 size) {
|
bool SSynthFileReader::Read(void* data, uint32 size) {
|
||||||
return 1 == fread(data, size, 1, fFile);
|
return 1 == fread(data, size, 1, fFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Read(tag &tag) {
|
bool SSynthFileReader::Read(tag &tag) {
|
||||||
return Read((void*)tag, sizeof(tag));
|
return Read((void*)tag, sizeof(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Read(uint64 &n, uint32 size) {
|
bool SSynthFileReader::Read(uint64 &n, uint32 size) {
|
||||||
uint8 number[8];
|
uint8 number[8];
|
||||||
ASSERT(size <= sizeof(number));
|
ASSERT(size <= sizeof(number));
|
||||||
if (Read((void*)number, size)) {
|
if (Read((void*)number, size)) {
|
||||||
@ -83,7 +84,7 @@ bool SynthFileReader::Read(uint64 &n, uint32 size) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Read(uint32 &n) {
|
bool SSynthFileReader::Read(uint32 &n) {
|
||||||
uint64 num;
|
uint64 num;
|
||||||
bool ok = Read(num, 4);
|
bool ok = Read(num, 4);
|
||||||
n = num;
|
n = num;
|
||||||
@ -91,7 +92,7 @@ bool SynthFileReader::Read(uint32 &n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SynthFileReader::Read(uint16 &n) {
|
bool SSynthFileReader::Read(uint16 &n) {
|
||||||
uint64 num;
|
uint64 num;
|
||||||
bool ok = Read(num, 2);
|
bool ok = Read(num, 2);
|
||||||
n = num;
|
n = num;
|
||||||
@ -99,11 +100,11 @@ bool SynthFileReader::Read(uint16 &n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SynthFileReader::Read(uint8 &n) {
|
bool SSynthFileReader::Read(uint8 &n) {
|
||||||
return Read((void*)&n, 1);
|
return Read((void*)&n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Read(BString& s, uint32 len) {
|
bool SSynthFileReader::Read(BString& s, uint32 len) {
|
||||||
char* str = s.LockBuffer(len+1);
|
char* str = s.LockBuffer(len+1);
|
||||||
str[len] = 0;
|
str[len] = 0;
|
||||||
bool ok = Read((void*)str, len);
|
bool ok = Read((void*)str, len);
|
||||||
@ -111,18 +112,115 @@ bool SynthFileReader::Read(BString& s, uint32 len) {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynthFileReader::Skip(uint32 bytes) {
|
bool SSynthFileReader::Skip(uint32 bytes) {
|
||||||
fseek(fFile, bytes, SEEK_CUR);
|
fseek(fFile, bytes, SEEK_CUR);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSynthFileReader::ReadHeader(uint32& version, uint32& chunks, uint32& nextChunk) {
|
||||||
|
tag tag;
|
||||||
|
fseek(fFile, 0, SEEK_SET);
|
||||||
|
if (Read(tag) && TagEquals(tag, "IREZ") && Read(version) && Read(chunks)) {
|
||||||
|
nextChunk = ftell(fFile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSynthFileReader::NextChunk(tag& tag, uint32& nextChunk) {
|
||||||
|
fseek(fFile, nextChunk, SEEK_SET);
|
||||||
|
return Read(nextChunk) && Read(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSynthFileReader::ReadInstHeader(uint16& inst, uint16& snd, uint16& snds, BString& name, uint32& size) {
|
||||||
|
uint8 len;
|
||||||
|
|
||||||
|
if (Skip(2) && Read(inst) && Read(len) && Read(name, len) && Read(size) && Read(snd) && Skip(10) && Read(snds)) {
|
||||||
|
size -= 14;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSynthFileReader::ReadSoundInRange(uint8& start, uint8& end, uint16& snd, uint32& size) {
|
||||||
|
size -= 4;
|
||||||
|
return Read(start) && Read(end) && Read(snd) && Skip(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SSynthFileReader::ReadSoundHeader(uint16& inst, BString& name, uint32& size) {
|
||||||
|
uint8 len;
|
||||||
|
return Skip(2) && Read(inst) && Read(len) && Read(name, len) && Read(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t SSynthFileReader::Initialize(SSynthFile* synth) {
|
||||||
|
uint32 version;
|
||||||
|
uint32 chunks;
|
||||||
|
uint32 nextChunk;
|
||||||
|
tag t;
|
||||||
|
|
||||||
|
if (ReadHeader(version, chunks, nextChunk)) {
|
||||||
|
for (uint32 chunk = 0; chunk < chunks; chunk ++) {
|
||||||
|
if (NextChunk(t, nextChunk)) {
|
||||||
|
if (TagEquals(t, "INST")) {
|
||||||
|
uint32 offset = Tell();
|
||||||
|
uint16 inst;
|
||||||
|
uint16 snd;
|
||||||
|
uint16 snds;
|
||||||
|
BString name;
|
||||||
|
uint32 size;
|
||||||
|
if (ReadInstHeader(inst, snd, snds, name, size)) {
|
||||||
|
SInstrument* instr = synth->GetInstrument(inst);
|
||||||
|
instr->SetOffset(offset);
|
||||||
|
instr->SetName(name.String());
|
||||||
|
instr->SetDefaultSound(synth->GetSound(snd));
|
||||||
|
for (int s = 0; s < snds; s ++) {
|
||||||
|
uint8 start, end;
|
||||||
|
if (ReadSoundInRange(start, end, snd, size)) {
|
||||||
|
instr->Sounds()->AddItem(new SSoundInRange(start, end, synth->GetSound(snd)));
|
||||||
|
} else {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
} else if (TagEquals(t, "snd ")) {
|
||||||
|
uint32 offset = Tell();
|
||||||
|
uint16 inst;
|
||||||
|
BString name;
|
||||||
|
uint32 size;
|
||||||
|
if (ReadSoundHeader(inst, name, size)) {
|
||||||
|
SSound* s = synth->GetSound(inst);
|
||||||
|
s->SetOffset(offset);
|
||||||
|
s->SetName(name.String());
|
||||||
|
} else {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
void SynthFileReader::Print(tag tag) {
|
void SSynthFileReader::Print(tag tag) {
|
||||||
printf("%.*s", 4, tag);
|
printf("%.*s", 4, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SynthFileReader::Dump(uint32 bytes) {
|
void SSynthFileReader::Dump(uint32 bytes) {
|
||||||
uint8 byte;
|
uint8 byte;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
const int cols = 16;
|
const int cols = 16;
|
||||||
@ -141,7 +239,7 @@ void SynthFileReader::Dump(uint32 bytes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynthFileReader::Dump(bool play, uint32 instrOnly) {
|
void SSynthFileReader::Dump(bool play, uint32 instrOnly) {
|
||||||
tag tag;
|
tag tag;
|
||||||
uint32 version;
|
uint32 version;
|
||||||
uint32 nEntries;
|
uint32 nEntries;
|
||||||
@ -164,7 +262,7 @@ void SynthFileReader::Dump(bool play, uint32 instrOnly) {
|
|||||||
cur = ftell(fFile);
|
cur = ftell(fFile);
|
||||||
if (Read(tag)) {
|
if (Read(tag)) {
|
||||||
Print(tag);
|
Print(tag);
|
||||||
if (TagEquals(tag, "INST")) {
|
if (!play && TagEquals(tag, "INST")) {
|
||||||
uint32 inst;
|
uint32 inst;
|
||||||
uint8 len;
|
uint8 len;
|
||||||
BString name;
|
BString name;
|
||||||
@ -207,7 +305,7 @@ void SynthFileReader::Dump(bool play, uint32 instrOnly) {
|
|||||||
} else if (TagEquals(tag, "LAST")) {
|
} else if (TagEquals(tag, "LAST")) {
|
||||||
s = 0;
|
s = 0;
|
||||||
if (rest > 0) {
|
if (rest > 0) {
|
||||||
SynthFileReader::tag tag2;
|
SSynthFileReader::tag tag2;
|
||||||
long pos = ftell(fFile);
|
long pos = ftell(fFile);
|
||||||
Read(tag2);
|
Read(tag2);
|
||||||
fseek(fFile, pos, SEEK_SET);
|
fseek(fFile, pos, SEEK_SET);
|
||||||
@ -291,7 +389,7 @@ void SynthFileReader::Dump(bool play, uint32 instrOnly) {
|
|||||||
#include <GameSoundDefs.h>
|
#include <GameSoundDefs.h>
|
||||||
#include <SimpleGameSound.h>
|
#include <SimpleGameSound.h>
|
||||||
|
|
||||||
void SynthFileReader::Play(uint16 rate, uint32 offset, uint32 size) {
|
void SSynthFileReader::Play(uint16 rate, uint32 offset, uint32 size) {
|
||||||
uint8* samples = new uint8[size];
|
uint8* samples = new uint8[size];
|
||||||
fseek(fFile, offset, SEEK_CUR);
|
fseek(fFile, offset, SEEK_CUR);
|
||||||
Read((void*)samples, size);
|
Read((void*)samples, size);
|
||||||
|
@ -34,8 +34,11 @@ THE SOFTWARE.
|
|||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
class SynthFileReader {
|
class SSynthFile;
|
||||||
FILE* fFile;
|
|
||||||
|
class SSynthFileReader {
|
||||||
|
private:
|
||||||
|
FILE* fFile;
|
||||||
|
|
||||||
typedef char tag[4];
|
typedef char tag[4];
|
||||||
|
|
||||||
@ -48,6 +51,14 @@ class SynthFileReader {
|
|||||||
bool Read(uint16 &n);
|
bool Read(uint16 &n);
|
||||||
bool Read(uint8 &n);
|
bool Read(uint8 &n);
|
||||||
bool Skip(uint32 bytes);
|
bool Skip(uint32 bytes);
|
||||||
|
uint32 Tell() { return ftell(fFile); }
|
||||||
|
void Seek(uint32 pos) { fseek(fFile, pos, SEEK_SET); }
|
||||||
|
|
||||||
|
bool ReadHeader(uint32& version, uint32& chunks, uint32& nextChunk);
|
||||||
|
bool NextChunk(tag& tag, uint32& nextChunk);
|
||||||
|
bool ReadInstHeader(uint16& inst, uint16& snd, uint16& snds, BString& name, uint32& size);
|
||||||
|
bool ReadSoundInRange(uint8& start, uint8& end, uint16& snd, uint32& size);
|
||||||
|
bool ReadSoundHeader(uint16& inst, BString& name, uint32& size);
|
||||||
|
|
||||||
// debugging support
|
// debugging support
|
||||||
void Print(tag tag);
|
void Print(tag tag);
|
||||||
@ -55,9 +66,11 @@ class SynthFileReader {
|
|||||||
void Play(uint16 rate, uint32 offset, uint32 size);
|
void Play(uint16 rate, uint32 offset, uint32 size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SynthFileReader(const char* synthFile);
|
SSynthFileReader(const char* synthFile);
|
||||||
~SynthFileReader();
|
~SSynthFileReader();
|
||||||
bool InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
|
status_t Initialize(SSynthFile* synth);
|
||||||
|
|
||||||
void Dump(bool play, uint32 instrOnly);
|
void Dump(bool play, uint32 instrOnly);
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SynthFileReader.h"
|
#include "SynthFileReader.h"
|
||||||
|
#include "SynthFile.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
|
|
||||||
@ -38,18 +39,26 @@ void start_be_app() {
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("%s <synth file> [play [instr]]\n", argv[0]);
|
printf("%s <synth file> [play [instr] | dump]\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
const char* fileName = argv[1];
|
const char* fileName = argv[1];
|
||||||
bool play = argc >= 3 ? strcmp(argv[2], "play") == 0 : false;
|
bool play = argc >= 3 ? strcmp(argv[2], "play") == 0 : false;
|
||||||
|
bool dump = argc >= 3 ? strcmp(argv[2], "dump") == 0 : false;
|
||||||
uint32 instr = argc >= 4 ? atol(argv[3]) : 0xffff;
|
uint32 instr = argc >= 4 ? atol(argv[3]) : 0xffff;
|
||||||
|
|
||||||
SynthFileReader reader(fileName);
|
if (dump) {
|
||||||
if (reader.InitCheck()) {
|
SSynthFile synth(fileName);
|
||||||
start_be_app();
|
if (synth.InitCheck() == B_OK) {
|
||||||
reader.Dump(play, instr);
|
synth.Dump();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("could not open '%s' or not a valid synth file!\n", fileName);
|
SSynthFileReader reader(fileName);
|
||||||
}
|
if (reader.InitCheck() == B_OK) {
|
||||||
|
start_be_app();
|
||||||
|
reader.Dump(play, instr);
|
||||||
|
} else {
|
||||||
|
printf("could not open '%s' or not a valid synth file!\n", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user