summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--raul/SMFReader.h5
-rw-r--r--src/SMFReader.cpp52
-rw-r--r--tests/smf_test.cpp29
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;