| 559 | } |
| 560 | |
| 561 | void NoteCanvas::LoadMidi() |
| 562 | { |
| 563 | using namespace juce; |
| 564 | String file_pattern = "*.mid;*.midi"; |
| 565 | if (File::areFileNamesCaseSensitive()) |
| 566 | file_pattern += ";" + file_pattern.toUpperCase(); |
| 567 | FileChooser chooser("Load midi", File(ofToDataPath("")), file_pattern, true, false, TheSynth->GetFileChooserParent()); |
| 568 | if (chooser.browseForFileToOpen()) |
| 569 | { |
| 570 | bool wasPlaying = mPlay; |
| 571 | mPlay = false; |
| 572 | |
| 573 | Clear(NextBufferTime(false)); |
| 574 | SetNumMeasures(1); |
| 575 | File file = chooser.getResult(); |
| 576 | FileInputStream inputStream(file); |
| 577 | MidiFile midifile; |
| 578 | if (midifile.readFrom(inputStream)) |
| 579 | { |
| 580 | midifile.convertTimestampTicksToSeconds(); |
| 581 | int ticksPerQuarterNote = midifile.getTimeFormat(); |
| 582 | int trackToGet = 0; |
| 583 | if (midifile.getNumTracks() > 1) |
| 584 | trackToGet = mLoadMidiTrack; |
| 585 | const MidiMessageSequence* trackSequence = midifile.getTrack(trackToGet); |
| 586 | for (int eventIndex = 0; eventIndex < trackSequence->getNumEvents(); eventIndex++) |
| 587 | { |
| 588 | MidiMessageSequence::MidiEventHolder* noteEvent = trackSequence->getEventPointer(eventIndex); |
| 589 | if (noteEvent->noteOffObject) |
| 590 | { |
| 591 | int note = noteEvent->message.getNoteNumber(); |
| 592 | int veloc = noteEvent->message.getVelocity() * 1.27; |
| 593 | double start = noteEvent->message.getTimeStamp() / ticksPerQuarterNote / TheTransport->CountInStandardMeasure(kInterval_4n); |
| 594 | double end = noteEvent->noteOffObject->message.getTimeStamp() / ticksPerQuarterNote / TheTransport->CountInStandardMeasure(kInterval_4n); |
| 595 | double length = end - start; |
| 596 | AddNote(start, note, veloc, length, -1, ModulationParameters()); |
| 597 | } |
| 598 | } |
| 599 | float latest = 0.0; |
| 600 | for (auto* element : mCanvas->GetElements()) |
| 601 | { |
| 602 | if (element->GetEnd() > latest) |
| 603 | latest = element->GetEnd(); |
| 604 | } |
| 605 | mNumMeasuresSlider->SetExtents(0, static_cast<int>(std::ceil(latest))); |
| 606 | FitNotes(); |
| 607 | } |
| 608 | |
| 609 | mPlay = wasPlaying; |
| 610 | } |
| 611 | } |
| 612 | |
| 613 | void NoteCanvas::SaveMidi() |
| 614 | { |
nothing calls this directly
no test coverage detected