VocalEasel/Sources/VLMIDIWriter.cpp

119 lines
3.0 KiB
C++
Raw Normal View History

2008-05-29 18:54:30 +00:00
//
// File: VLMIDIWriter.cpp
//
// Author(s):
//
// (MN) Matthias Neeracher
//
2018-02-19 00:59:23 +00:00
// Copyright © 2008-2018 Matthias Neeracher
2008-05-29 18:54:30 +00:00
//
#include "VLMIDIWriter.h"
#include <AudioToolbox/AudioToolbox.h>
2011-09-11 21:27:53 +00:00
VLMIDIUtilities::VLMIDIUtilities(MusicSequence music)
: fMusic(music)
{
}
MusicTimeStamp VLMIDIUtilities::Length()
{
UInt32 ntracks;
MusicSequenceGetTrackCount(fMusic, &ntracks);
MusicTimeStamp sequenceLength = 0;
for (UInt32 i = 0; i < ntracks; ++i) {
MusicTrack track;
MusicTimeStamp trackLength;
UInt32 propsize = sizeof(MusicTimeStamp);
MusicSequenceGetIndTrack(fMusic, i, &track);
MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength,
&trackLength, &propsize);
sequenceLength = std::max(sequenceLength, trackLength);
}
return sequenceLength;
}
MusicTimeStamp VLMIDIUtilities::Find(VLLocation at)
{
UInt32 ntracks;
MusicSequenceGetTrackCount(fMusic, &ntracks);
MusicTrack track;
MusicSequenceGetIndTrack(fMusic, ntracks-1, &track);
MusicEventIterator iter;
NewMusicEventIterator(track, &iter);
Boolean hasEvent;
while (!MusicEventIteratorHasCurrentEvent(iter, &hasEvent) && hasEvent) {
MusicTimeStamp ts;
MusicEventType ty;
const VLMIDIUserEvent * data;
UInt32 sz;
MusicEventIteratorGetEventInfo(iter, &ts, &ty, (const void **)&data, &sz);
if (ty == kMusicEventType_User && data->fAt >= at)
return ts;
MusicEventIteratorNextEvent(iter);
}
return Length();
}
2008-05-29 18:54:30 +00:00
struct VLMetaEvent : MIDIMetaEvent {
char fPadding[32];
VLMetaEvent(const char * label)
{
metaEventType = 3;
dataLength = strlen(label);
memcpy(data, label, dataLength);
}
};
void VLMIDIWriter::Visit(VLSong & song)
{
fChordTime = 0.0f;
2008-07-05 13:55:41 +00:00
fVolta.clear();
2008-05-29 18:54:30 +00:00
MusicSequenceNewTrack(fMusic, &fTrack);
VLMetaEvent meta("VocalEasel");
MusicTrackNewMetaEvent(fTrack, 0.0, &meta);
VisitMeasures(song, true);
}
2018-02-19 00:59:23 +00:00
void VLMIDIWriter::VisitMeasure(uint32_t m, VLProperties & p, VLMeasure & meas)
2008-05-29 18:54:30 +00:00
{
2011-09-11 02:03:22 +00:00
const VLLocation kStartOfMeasure = {m, VLFraction(0)};
2008-07-05 13:55:41 +00:00
if (fVolta.size() <= m)
fVolta.push_back(0);
2008-05-29 18:54:30 +00:00
fTime = p.fTime;
2008-07-05 13:55:41 +00:00
fStanza = ++fVolta[m];
2008-05-29 18:54:30 +00:00
if (!fChordTime)
2008-05-29 18:54:30 +00:00
fChordTime = fNoteTime = fCountIn*fTime.fNum;
2011-09-11 02:03:22 +00:00
fAt = kStartOfMeasure;
2008-05-29 18:54:30 +00:00
VisitChords(meas);
2011-09-11 02:03:22 +00:00
fAt = kStartOfMeasure;
2008-05-29 18:54:30 +00:00
VisitNotes(meas, p, false);
}
void VLMIDIWriter::VisitNote(VLLyricsNote & n)
{
2008-07-06 11:08:54 +00:00
if (!(n.fTied & VLNote::kTiedWithPrev)) {
2018-02-19 00:59:23 +00:00
VLMIDIUserEvent event = {12, n.fPitch, static_cast<uint8_t>(fStanza), n.fVisual, fAt};
2008-05-29 18:54:30 +00:00
MusicTrackNewUserEvent(fTrack, fNoteTime,
reinterpret_cast<const MusicEventUserData *>(&event));
}
2011-09-11 02:03:22 +00:00
fAt.fAt = fAt.fAt+n.fDuration;
2008-05-29 18:54:30 +00:00
fNoteTime += n.fDuration * (float)fTime.fDenom;
}
void VLMIDIWriter::VisitChord(VLChord & c)
{
if (c.fPitch != VLNote::kNoPitch) {
2018-02-19 00:59:23 +00:00
VLMIDIUserEvent event = {12, 0, static_cast<uint8_t>(fStanza), 0, fAt};
2008-05-29 18:54:30 +00:00
MusicTrackNewUserEvent(fTrack, fChordTime,
reinterpret_cast<const MusicEventUserData *>(&event));
}
2011-09-11 02:03:22 +00:00
fAt.fAt = fAt.fAt+c.fDuration;
2008-05-29 18:54:30 +00:00
fChordTime += c.fDuration * (float)fTime.fDenom;
}