Mercurial > hg > svcore
comparison data/fileio/MIDIFileWriter.cpp @ 874:862fe7b20df7 tony_integration
Merge from tonioni branch
| author | Chris Cannam |
|---|---|
| date | Tue, 28 Jan 2014 15:01:54 +0000 |
| parents | d6bd5751b8f6 |
| children | 59e7fe1b1003 |
comparison
equal
deleted
inserted
replaced
| 862:786ee8d1f30e | 874:862fe7b20df7 |
|---|---|
| 21 */ | 21 */ |
| 22 | 22 |
| 23 #include "MIDIFileWriter.h" | 23 #include "MIDIFileWriter.h" |
| 24 | 24 |
| 25 #include "data/midi/MIDIEvent.h" | 25 #include "data/midi/MIDIEvent.h" |
| 26 | 26 #include "model/NoteData.h" |
| 27 #include "model/NoteModel.h" | |
| 28 | 27 |
| 29 #include "base/Pitch.h" | 28 #include "base/Pitch.h" |
| 30 | 29 |
| 31 #include <algorithm> | 30 #include <algorithm> |
| 32 #include <fstream> | 31 #include <fstream> |
| 35 using std::string; | 34 using std::string; |
| 36 using std::ios; | 35 using std::ios; |
| 37 | 36 |
| 38 using namespace MIDIConstants; | 37 using namespace MIDIConstants; |
| 39 | 38 |
| 40 MIDIFileWriter::MIDIFileWriter(QString path, NoteModel *model, float tempo) : | 39 MIDIFileWriter::MIDIFileWriter(QString path, const NoteExportable *exportable, |
| 40 int sampleRate, float tempo) : | |
| 41 m_path(path), | 41 m_path(path), |
| 42 m_model(model), | 42 m_exportable(exportable), |
| 43 m_modelUsesHz(false), | 43 m_sampleRate(sampleRate), |
| 44 m_tempo(tempo) | 44 m_tempo(tempo) |
| 45 { | 45 { |
| 46 if (model->getScaleUnits().toLower() == "hz") m_modelUsesHz = true; | |
| 47 | |
| 48 if (!convert()) { | 46 if (!convert()) { |
| 49 m_error = "Conversion from model to internal MIDI format failed"; | 47 m_error = "Conversion from model to internal MIDI format failed"; |
| 50 } | 48 } |
| 51 } | 49 } |
| 52 | 50 |
| 340 tempoString); | 338 tempoString); |
| 341 m_midiComposition[track].push_back(event); | 339 m_midiComposition[track].push_back(event); |
| 342 | 340 |
| 343 // Omit time signature | 341 // Omit time signature |
| 344 | 342 |
| 345 const NoteModel::PointList ¬es = | 343 NoteList notes = m_exportable->getNotes(); |
| 346 static_cast<SparseModel<Note> *>(m_model)->getPoints(); | 344 |
| 347 | 345 for (NoteList::const_iterator i = notes.begin(); i != notes.end(); ++i) { |
| 348 for (NoteModel::PointList::const_iterator i = notes.begin(); | 346 |
| 349 i != notes.end(); ++i) { | 347 size_t frame = i->start; |
| 350 | |
| 351 long frame = i->frame; | |
| 352 float value = i->value; | |
| 353 size_t duration = i->duration; | 348 size_t duration = i->duration; |
| 354 | 349 int pitch = i->midiPitch; |
| 355 int pitch; | 350 int velocity = i->velocity; |
| 356 | |
| 357 if (m_modelUsesHz) { | |
| 358 pitch = Pitch::getPitchForFrequency(value); | |
| 359 } else { | |
| 360 pitch = lrintf(value); | |
| 361 } | |
| 362 | 351 |
| 363 if (pitch < 0) pitch = 0; | 352 if (pitch < 0) pitch = 0; |
| 364 if (pitch > 127) pitch = 127; | 353 if (pitch > 127) pitch = 127; |
| 365 | 354 |
| 366 // Convert frame to MIDI time | 355 // Convert frame to MIDI time |
| 367 | 356 |
| 368 double seconds = double(frame) / double(m_model->getSampleRate()); | 357 double seconds = double(frame) / double(m_sampleRate); |
| 369 double quarters = (seconds * m_tempo) / 60.0; | 358 double quarters = (seconds * m_tempo) / 60.0; |
| 370 unsigned long midiTime = lrint(quarters * m_timingDivision); | 359 unsigned long midiTime = int(quarters * m_timingDivision + 0.5); |
| 371 | |
| 372 int velocity = 100; | |
| 373 if (i->level > 0.f && i->level <= 1.f) { | |
| 374 velocity = lrintf(i->level * 127.f); | |
| 375 } | |
| 376 | 360 |
| 377 // Get the sounding time for the matching NOTE_OFF | 361 // Get the sounding time for the matching NOTE_OFF |
| 378 seconds = double(frame + duration) / double(m_model->getSampleRate()); | 362 seconds = double(frame + duration) / double(m_sampleRate); |
| 379 quarters = (seconds * m_tempo) / 60.0; | 363 quarters = (seconds * m_tempo) / 60.0; |
| 380 unsigned long endTime = lrint(quarters * m_timingDivision); | 364 unsigned long endTime = int(quarters * m_timingDivision + 0.5); |
| 381 | 365 |
| 382 // At this point all the notes we insert have absolute times | 366 // At this point all the notes we insert have absolute times |
| 383 // in the delta time fields. We resolve these into delta | 367 // in the delta time fields. We resolve these into delta |
| 384 // times further down (can't do it until all the note offs are | 368 // times further down (can't do it until all the note offs are |
| 385 // in place). | 369 // in place). |
