void MidiStorage::readMidiData(const char *filePath) { File *filePtr = new File (filePath); bool fileExists = filePtr->existsAsFile(); int NumEvents; if (fileExists) { ScopedPointer<FileInputStream> fileInputStream = filePtr->createInputStream(); //delete the stream! MidiFile fileMIDI; const MidiMessageSequence *midiSequence; MidiMessageSequence::MidiEventHolder *midiEvent; fileMIDI.readFrom(*fileInputStream); // read the MIDI file fileMIDI.convertTimestampTicksToSeconds(); midiSequence = fileMIDI.getTrack(1); //Track indices start from 1; Also we want only one track to exist NumEvents = midiSequence->getNumEvents(); noteNumber = new float[NumEvents]; timeStamps = new float[NumEvents]; for (int i=0; i<NumEvents; i++) { midiEvent = midiSequence->getEventPointer(i); //Make sure the index doesn't exceed your no. of timeStamps. It starts from 0. if ( midiEvent->message.isNoteOn() ) { noteNumber[i] = midiEvent->message.getNoteNumber(); timeStamps[i] = midiEvent->message.getTimeStamp(); } else { noteNumber[i] = -1.f; timeStamps[i] = midiEvent->message.getTimeStamp(); } } } else { Logger::writeToLog("Error in Reading Midi File - It doesn't exist"); } midiLen = NumEvents; //std::cout<<"noteNumber: "<<midiLen<<std::endl; FileRW::fileWrite( noteNumber, NumEvents, (char *)"/Users/Rithesh/Documents/Learn C++/ASE/notes/Matlab_ASE/midiIn.txt"); FileRW::fileWrite( timeStamps, NumEvents, (char *)"/Users/Rithesh/Documents/Learn C++/ASE/notes/Matlab_ASE/tStmpIn.txt"); }
void MainWindow::OpenMidiFile(LPCTSTR fileName) { Controls::Reset(); FileInputStream inputFile( File::getCurrentWorkingDirectory().getChildFile(String(fileName)).getFullPathName()); if (inputFile.failedToOpen()) { OnMidiError((wstring(TEXT("Could not open file:\r\n")) + fileName).c_str()); return; } MidiFile midi; if (!midi.readFrom(inputFile)) { OnMidiError((wstring(TEXT("Not a MIDI-file:\r\n")) + fileName).c_str()); return; } midi.convertTimestampTicksToSeconds(); Piano::notes.assign(static_cast<size_t>(midi.getNumTracks()), vector<set<int16_t>>()); Piano::milliSeconds.assign(static_cast<size_t>(midi.getNumTracks()), vector<pair<unsigned, unsigned>>()); vector<wstring> trackNames(static_cast<size_t>(midi.getNumTracks())); wstring log; for (auto i(0); i < midi.getNumTracks(); ++i) { unsigned lastTime(0); const auto track(midi.getTrack(i)); for (auto j(0); j < track->getNumEvents(); ++j) { const auto message(track->getEventPointer(j)->message); const auto milliSeconds(static_cast<unsigned>(message.getTimeStamp() * 1'000)); if (message.isTextMetaEvent()) if (message.isTrackNameEvent()) trackNames.at(static_cast<size_t>(i)) = message.getTextFromTextMetaEvent().toWideCharPointer(); else log.append(wstring(TEXT("\t")) + message.getTextFromTextMetaEvent().toWideCharPointer() + TEXT("\r\n")); else if (message.isTempoMetaEvent()) log.append((wformat{ TEXT("Time %02d:%02d:%02d Tempo %d BPM\r\n") } % (milliSeconds / 1'000 / 60) % (milliSeconds / 1'000 % 60) % (milliSeconds % 1'000 / 10) % static_cast<int>(60 / message.getTempoSecondsPerQuarterNote() + 0.5)).str()); else if (message.isKeySignatureMetaEvent()) { log.append(TEXT("Key signature: ")); const auto nSharpsOrFlats(message.getKeySignatureNumberOfSharpsOrFlats()); switch (nSharpsOrFlats) { case 0: log.append(TEXT("Natural key signature, ")); break; case -7: case -6: case -5: case -4: case -3: case -2: case -1: log.append(lexical_cast<wstring>(-nSharpsOrFlats) + TEXT(" flats, ")); break; case 7: case 6: case 5: case 4: case 3: case 2: case 1: log.append(lexical_cast<wstring>(nSharpsOrFlats) + TEXT(" sharps, ")); break; default: assert("Wrong key signature"); } log.append(message.isKeySignatureMajorKey() ? nSharpsOrFlats ? TEXT("Major key\r\n") : TEXT("C-Major\r\n") : nSharpsOrFlats ? TEXT("Minor key\r\n") : TEXT("A-Minor\r\n")); } else if (message.isNoteOn()) { if (milliSeconds - lastTime < Piano::timerTick && !Piano::notes.at(static_cast<size_t>(i)).empty()) { Piano::notes.at(static_cast<size_t>(i)).back().insert( static_cast<int16_t>(message.getNoteNumber())); Piano::milliSeconds.at(static_cast<size_t>(i)).back().second = milliSeconds; } else { Piano::notes.at(static_cast<size_t>(i)).push_back({ static_cast<int16_t>(message.getNoteNumber()) }); Piano::milliSeconds.at(static_cast<size_t>(i)).emplace_back( make_pair(milliSeconds, milliSeconds)); } lastTime = milliSeconds; } } } Edit_SetText(Controls::midiLog, log.c_str()); for (size_t i(0); i < trackNames.size(); ++i) if (!Piano::notes.at(i).empty()) { trackNames.at(i).insert(0, lexical_cast<wstring>(i) + TEXT(' ')); ComboBox_AddString(Controls::leftHand, trackNames.at(i).c_str()); ComboBox_AddString(Controls::rightHand, trackNames.at(i).c_str()); ListBox_AddString(Controls::trackList, trackNames.at(i).c_str()); ComboBox_SetItemData(Controls::leftHand, ComboBox_GetCount(Controls::leftHand) - 1, i); ComboBox_SetItemData(Controls::rightHand, ComboBox_GetCount(Controls::rightHand) - 1, i); ListBox_SetItemData(Controls::trackList, ListBox_GetCount(Controls::trackList) - 1, i); } SendMessage(Controls::progressLeft, PBM_SETPOS, 0, 0); SendMessage(Controls::progressRight, PBM_SETPOS, 0, 0); Piano::tracks.clear(); Piano::indexes.assign(Piano::notes.size(), 0); Piano::leftTrack.reset(); Piano::rightTrack.reset(); Piano::fingersLeft.assign(Piano::notes.size(), vector<vector<string>>()); Piano::fingersRight.assign(Piano::notes.size(), vector<vector<string>>()); const auto maxElement(max_element(Piano::milliSeconds.cbegin(), Piano::milliSeconds.cend(), [](const vector<pair<unsigned, unsigned>>& left, const vector<pair<unsigned, unsigned>>& right) { return right.empty() ? false : left.empty() ? true : left.back().second < right.back().second; })); if (maxElement->empty()) { OnMidiError(TEXT("Midi file does not contain any time data")); return; } ScrollBar_SetRange(Controls::scrollBar, 0, static_cast<int>(maxElement->back().second), false); ScrollBar_SetPos(Controls::scrollBar, 0, true); Button_Enable(Controls::playButton, true); }
void _loadMidiFile(const char* const filename) { fMidiOut.clear(); using namespace juce; const String jfilename = String(CharPointer_UTF8(filename)); File file(jfilename); if (! file.existsAsFile()) return; FileInputStream fileStream(file); MidiFile midiFile; if (! midiFile.readFrom(fileStream)) return; midiFile.convertTimestampTicksToSeconds(); const double sampleRate(getSampleRate()); for (int i=0, numTracks = midiFile.getNumTracks(); i<numTracks; ++i) { const MidiMessageSequence* const track(midiFile.getTrack(i)); CARLA_SAFE_ASSERT_CONTINUE(track != nullptr); for (int j=0, numEvents = track->getNumEvents(); j<numEvents; ++j) { const MidiMessageSequence::MidiEventHolder* const midiEventHolder(track->getEventPointer(j)); CARLA_SAFE_ASSERT_CONTINUE(midiEventHolder != nullptr); const MidiMessage& midiMessage(midiEventHolder->message); //const double time(track->getEventTime(i)*sampleRate); const int dataSize(midiMessage.getRawDataSize()); if (dataSize <= 0 || dataSize > MAX_EVENT_DATA_SIZE) continue; if (midiMessage.isActiveSense()) continue; if (midiMessage.isMetaEvent()) continue; if (midiMessage.isMidiStart()) continue; if (midiMessage.isMidiContinue()) continue; if (midiMessage.isMidiStop()) continue; if (midiMessage.isMidiClock()) continue; if (midiMessage.isSongPositionPointer()) continue; if (midiMessage.isQuarterFrame()) continue; if (midiMessage.isFullFrame()) continue; if (midiMessage.isMidiMachineControlMessage()) continue; if (midiMessage.isSysEx()) continue; const double time(midiMessage.getTimeStamp()*sampleRate); CARLA_SAFE_ASSERT_CONTINUE(time >= 0.0); fMidiOut.addRaw(static_cast<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); } } fNeedsAllNotesOff = true; }