Mercurial > hg > svcore
comparison data/fileio/MIDIFileWriter.cpp @ 852:d6bd5751b8f6 tonioni_multi_transform
Add NoteExportable base class, use it in MIDI export (and also elsewhere in playback)
author | Chris Cannam |
---|---|
date | Mon, 02 Dec 2013 17:11:20 +0000 |
parents | 2e50d95cf621 |
children | 59e7fe1b1003 |
comparison
equal
deleted
inserted
replaced
850:dba8a02b0413 | 852:d6bd5751b8f6 |
---|---|
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). |