diff options
Diffstat (limited to 'src/engine/SMFReader.cpp')
-rw-r--r-- | src/engine/SMFReader.cpp | 124 |
1 files changed, 70 insertions, 54 deletions
diff --git a/src/engine/SMFReader.cpp b/src/engine/SMFReader.cpp index cba1fb0..62cdd26 100644 --- a/src/engine/SMFReader.cpp +++ b/src/engine/SMFReader.cpp @@ -1,5 +1,5 @@ /* - This file is part of Raul. + This file is part of Machina. Copyright 2007-2012 David Robillard <http://drobilla.net> Raul is free software: you can redistribute it and/or modify it under the @@ -40,31 +40,31 @@ midi_event_size(unsigned char status) } switch (status) { - case LV2_MIDI_MSG_NOTE_OFF: - case LV2_MIDI_MSG_NOTE_ON: - case LV2_MIDI_MSG_NOTE_PRESSURE: - case LV2_MIDI_MSG_CONTROLLER: - case LV2_MIDI_MSG_BENDER: - case LV2_MIDI_MSG_SONG_POS: - return 2; - - case LV2_MIDI_MSG_PGM_CHANGE: - case LV2_MIDI_MSG_CHANNEL_PRESSURE: - case LV2_MIDI_MSG_MTC_QUARTER: - case LV2_MIDI_MSG_SONG_SELECT: - return 1; - - case LV2_MIDI_MSG_TUNE_REQUEST: - case LV2_MIDI_MSG_CLOCK: - case LV2_MIDI_MSG_START: - case LV2_MIDI_MSG_CONTINUE: - case LV2_MIDI_MSG_STOP: - case LV2_MIDI_MSG_ACTIVE_SENSE: - case LV2_MIDI_MSG_RESET: - return 0; + case LV2_MIDI_MSG_NOTE_OFF: + case LV2_MIDI_MSG_NOTE_ON: + case LV2_MIDI_MSG_NOTE_PRESSURE: + case LV2_MIDI_MSG_CONTROLLER: + case LV2_MIDI_MSG_BENDER: + case LV2_MIDI_MSG_SONG_POS: + return 2; + + case LV2_MIDI_MSG_PGM_CHANGE: + case LV2_MIDI_MSG_CHANNEL_PRESSURE: + case LV2_MIDI_MSG_MTC_QUARTER: + case LV2_MIDI_MSG_SONG_SELECT: + return 1; + + case LV2_MIDI_MSG_TUNE_REQUEST: + case LV2_MIDI_MSG_CLOCK: + case LV2_MIDI_MSG_START: + case LV2_MIDI_MSG_CONTINUE: + case LV2_MIDI_MSG_STOP: + case LV2_MIDI_MSG_ACTIVE_SENSE: + case LV2_MIDI_MSG_RESET: + return 0; - case LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: - return -1; + case LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: + return -1; } return -1; @@ -76,21 +76,26 @@ SMFReader::SMFReader(const std::string filename) , _track(0) , _track_size(0) { - if (filename.length() > 0) + if (filename.length() > 0) { open(filename); + } } SMFReader::~SMFReader() { - if (_fd) + if (_fd) { close(); + } } bool -SMFReader::open(const std::string& filename) throw (std::logic_error, UnsupportedTime) +SMFReader::open(const std::string& filename) + throw (std::logic_error, UnsupportedTime) { - if (_fd) - throw std::logic_error("Attempt to start new read while write in progress."); + if (_fd) { + throw std::logic_error( + "Attempt to start new read while write in progress."); + } std::cout << "Opening SMF file " << filename << " for reading." << endl; @@ -126,8 +131,9 @@ SMFReader::open(const std::string& filename) throw (std::logic_error, Unsupporte _ppqn = GUINT16_FROM_BE(ppqn_be); // TODO: Absolute (SMPTE seconds) time support - if ((_ppqn & 0x8000) != 0) + if ((_ppqn & 0x8000) != 0) { throw UnsupportedTime(); + } seek_to_track(1); @@ -143,11 +149,13 @@ SMFReader::open(const std::string& filename) throw (std::logic_error, Unsupporte bool SMFReader::seek_to_track(unsigned track) throw (std::logic_error) { - if (track == 0) + if (track == 0) { throw std::logic_error("Seek to track 0 out of range (must be >= 1)"); + } - if (!_fd) + if (!_fd) { throw std::logic_error("Attempt to seek to track on unopened SMF file."); + } unsigned track_pos = 0; @@ -169,14 +177,15 @@ SMFReader::seek_to_track(unsigned track) throw (std::logic_error) fread(&chunk_size_be, 4, 1, _fd); chunk_size = GUINT32_FROM_BE(chunk_size_be); - if (track_pos == track) + if (track_pos == track) { break; + } fseek(_fd, chunk_size, SEEK_CUR); } - if (!feof(_fd) && track_pos == track) { - _track = track; + if (!feof(_fd) && ( track_pos == track) ) { + _track = track; _track_size = chunk_size; return true; } else { @@ -204,8 +213,9 @@ SMFReader::read_event(size_t buf_len, uint32_t* delta_time) throw (std::logic_error, PrematureEOF, CorruptFile) { - if (_track == 0) + if (_track == 0) { throw std::logic_error("Attempt to read from unopened SMF file"); + } if (!_fd || feof(_fd)) { return -1; @@ -222,30 +232,33 @@ SMFReader::read_event(size_t buf_len, *delta_time = read_var_len(_fd); int status = fgetc(_fd); - if (status == EOF) + if (status == EOF) { throw PrematureEOF(); - else if (status > 0xFF) + } else if (status > 0xFF) { throw CorruptFile(); + } if (status < 0x80) { - if (last_status == 0) + if (last_status == 0) { throw CorruptFile(); - status = last_status; + } + status = last_status; *ev_size = last_size; fseek(_fd, -1, SEEK_CUR); } else { last_status = status; - *ev_size = midi_event_size(status) + 1; - last_size = *ev_size; + *ev_size = midi_event_size(status) + 1; + last_size = *ev_size; } buf[0] = static_cast<uint8_t>(status); if (status == 0xFF) { *ev_size = 0; - if (feof(_fd)) + if (feof(_fd)) { throw PrematureEOF(); - uint8_t type = fgetc(_fd); + } + uint8_t type = fgetc(_fd); const uint32_t size = read_var_len(_fd); if (type == 0x2F) { @@ -256,18 +269,19 @@ SMFReader::read_event(size_t buf_len, } } - if (*ev_size > buf_len || *ev_size == 0 || feof(_fd)) { + if ((*ev_size > buf_len) || (*ev_size == 0) || feof(_fd)) { // Skip event, return 0 fseek(_fd, *ev_size - 1, SEEK_CUR); return 0; } else { // Read event, return size - if (ferror(_fd)) + if (ferror(_fd)) { throw CorruptFile(); + } - fread(buf+1, 1, *ev_size - 1, _fd); + fread(buf + 1, 1, *ev_size - 1, _fd); - if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) { + if (((buf[0] & 0xF0) == 0x90) && (buf[2] == 0) ) { buf[0] = (0x80 | (buf[0] & 0x0F)); buf[2] = 0x40; } @@ -279,8 +293,9 @@ SMFReader::read_event(size_t buf_len, void SMFReader::close() { - if (_fd) + if (_fd) { fclose(_fd); + } _fd = NULL; } @@ -288,17 +303,19 @@ SMFReader::close() uint32_t SMFReader::read_var_len(FILE* fd) throw (PrematureEOF) { - if (feof(fd)) + if (feof(fd)) { throw PrematureEOF(); + } uint32_t value; uint8_t c; - if ( (value = getc(fd)) & 0x80 ) { + if ( (value = getc(fd)) & 0x80) { value &= 0x7F; do { - if (feof(fd)) + if (feof(fd)) { throw PrematureEOF(); + } value = (value << 7) + ((c = getc(fd)) & 0x7F); } while (c & 0x80); } @@ -307,4 +324,3 @@ SMFReader::read_var_len(FILE* fd) throw (PrematureEOF) } } // namespace Machina - |