diff options
-rw-r--r-- | raul/SMFReader.h | 5 | ||||
-rw-r--r-- | src/SMFReader.cpp | 52 | ||||
-rw-r--r-- | tests/smf_test.cpp | 29 |
3 files changed, 72 insertions, 14 deletions
diff --git a/raul/SMFReader.h b/raul/SMFReader.h index 53a9927..771f139 100644 --- a/raul/SMFReader.h +++ b/raul/SMFReader.h @@ -34,6 +34,8 @@ public: bool open(const std::string& filename); + bool seek_to_track(unsigned track); + uint16_t type() const { return _type; } uint16_t ppqn() const { return _ppqn; } size_t num_tracks() { return _num_tracks; } @@ -53,8 +55,9 @@ protected: std::string _filename; FILE* _fd; uint16_t _type; - uint16_t _num_tracks; uint16_t _ppqn; + uint16_t _num_tracks; + //uint32_t _track; uint32_t _track_size; /* Raul::BeatTime _start_time; Raul::BeatTime _last_ev_time; ///< Time last event was written relative to _start_time diff --git a/src/SMFReader.cpp b/src/SMFReader.cpp index bb28f0e..4c03229 100644 --- a/src/SMFReader.cpp +++ b/src/SMFReader.cpp @@ -113,14 +113,64 @@ SMFReader::open(const string& filename) fread(&ppqn_be, 2, 1, _fd); _ppqn = GUINT16_FROM_BE(ppqn_be); + seek_to_track(1); // Read Track size (skip bytes 14..17 'Mtrk') // FIXME: first track read only - fseek(_fd, 18, SEEK_SET); + /*fseek(_fd, 18, SEEK_SET); uint32_t track_size_be = 0; fread(&track_size_be, 4, 1, _fd); _track_size = GUINT32_FROM_BE(track_size_be); std::cerr << "SMF - read track size " << _track_size << std::endl; + */ + + return true; + } else { + return false; + } +} + + +/** Seek to the start of a given track, starting from 1. + * Returns true if specified track was found. + */ +bool +SMFReader::seek_to_track(unsigned track) +{ + assert(track > 0); + + if (!_fd) + throw logic_error("Attempt to seek to track on unopen SMF file."); + + unsigned track_pos = 0; + + fseek(_fd, 14, SEEK_SET); + char id[5]; + id[4] = '\0'; + uint32_t chunk_size = 0; + + while (!feof(_fd)) { + fread(id, 1, 4, _fd); + + if (!strcmp(id, "MTrk")) { + ++track_pos; + std::cerr << "Found track " << track_pos << endl; + } else { + std::cerr << "Unknown chunk ID " << id << endl; + } + + uint32_t chunk_size_be; + fread(&chunk_size_be, 4, 1, _fd); + chunk_size = GUINT32_FROM_BE(chunk_size_be); + + if (track_pos == track) + break; + + fseek(_fd, chunk_size, SEEK_CUR); + } + if (!feof(_fd) && track_pos == track) { + //_track = track; + _track_size = chunk_size; return true; } else { return false; diff --git a/tests/smf_test.cpp b/tests/smf_test.cpp index adcb641..d4e5411 100644 --- a/tests/smf_test.cpp +++ b/tests/smf_test.cpp @@ -38,19 +38,24 @@ main(int argc, char** argv) cout << "Num tracks: " << reader.num_tracks() << endl; cout << "PPQN: " << reader.ppqn() << endl; - unsigned char buf[4]; - uint32_t ev_size; - uint32_t ev_delta_time; - while (reader.read_event(4, buf, &ev_size, &ev_delta_time) >= 0) { - - cerr << "\n\nEvent, size = " << ev_size << ", time = " << ev_delta_time << endl; - cerr << "Data: "; - cerr.flags(ios::hex); - for (uint32_t i=0; i < ev_size; ++i) { - cerr << "0x" << (int)buf[i] << " "; + for (unsigned t=1; t <= reader.num_tracks(); ++t) { + cout << "******** Track " << t << " ********" << endl; + reader.seek_to_track(t); + + unsigned char buf[4]; + uint32_t ev_size; + uint32_t ev_delta_time; + while (reader.read_event(4, buf, &ev_size, &ev_delta_time) >= 0) { + + cout << "\n\nEvent, size = " << ev_size << ", time = " << ev_delta_time; + cout << ", data = "; + cout.flags(ios::hex); + for (uint32_t i=0; i < ev_size; ++i) { + cout << "0x" << (int)buf[i] << " "; + } + cout.flags(ios::dec); + cout << endl; } - cerr.flags(ios::dec); - cerr << endl; } return 0; |