MIDINoteMessage 何时在 MusicTrack 中播放? iOS

Posted

技术标签:

【中文标题】MIDINoteMessage 何时在 MusicTrack 中播放? iOS【英文标题】:When is a MIDINoteMessage played in a MusicTrack? iOS 【发布时间】:2015-06-01 12:40:58 【问题描述】:

我正在创建一个使用

成功播放的 MIDI 音符的 MusicTrack

MusicPlayerStart(sequencePlayer)

但我想知道它们是什么时候播放的,所以我可以为每个播放的 MIDI 音符更新 UI。

// Creating MIDI Track
MusicTrack track;
UInt32 trackIndex = 0;
musicTrackAtIndex(trackIndex, &track);

//Adding Tempo
addTempoEvent(0.0, 120);

// Adding MIDI notes
const int channel = 0;
MIDINoteMessage note;
note.channel = channel;
note.velocity = 100.0;
note.duration = 0.3;
note.releaseVelocity = 0;

note.note = 68;
addMIDINoteToTrack(track, note, 1);

note.note = 78;
addMIDINoteToTrack(track, note, 2);

note.note = 88;
addMIDINoteToTrack(track, note, 3);

note.note = 98;
addMIDINoteToTrack(track, note, 4);

MusicTimeStamp trackEnd = 4;
addEndOfTrackAtTime(trackEnd);

setLoopTrack(true); 

playSequence();

编辑

更详细地展示了我是如何构建 MIDI 轨道的。

-(void) playing4NotesInLoop 

MusicTrack musicTrack;
MusicSequence musicSequence;
MusicPlayer musicPlayer;

const int loop_length = 4;

NewMusicSequence(&musicSequence);

// Create a client
MIDIClientRef virtualMidi;
MIDIClientCreate(CFSTR("Virtual Client"),
                          MyMIDINotifyProc,
                          NULL,
                          &virtualMidi);


// Create an endpoint
MIDIEndpointRef virtualEndpoint;
MIDIDestinationCreate(virtualMidi, @"Virtual Destination", MyMIDIReadProc, self.samplerUnit, &virtualEndpoint);


MusicSequenceNewTrack(musicSequence, &musicTrack);

MIDINoteMessage aMessage;
aMessage.channel = 1;

aMessage.duration = 0.5f;
aMessage.velocity = 100;

for(int i=0; i<4; ++i)

    if (i==0) 
        aMessage.note = 30;
    else 
        aMessage.note = 60;
    

    MusicTrackNewMIDINoteEvent(musicTrack, i, &aMessage);


MusicTrackLoopInfo loop_info;
loop_info.loopDuration = loop_length;
loop_info.numberOfLoops = 0;

MusicTrackSetProperty(musicTrack, kSequenceTrackProperty_LoopInfo, &loop_info, sizeof(MusicTrackLoopInfo));

MusicTimeStamp track_length;
track_length = loop_length;

MusicTrackSetProperty(musicTrack, kSequenceTrackProperty_TrackLength, &track_length, sizeof(MusicTimeStamp));

MusicSequenceSetMIDIEndpoint(musicSequence, virtualEndpoint);

NewMusicPlayer(&musicPlayer);
MusicPlayerSetSequence(musicPlayer, musicSequence);

MusicPlayerStart(musicPlayer);


通过这段代码,我成功地播放了一个 4 个音符的循环,一个 MusicSequenceSetMIDIEndpoint(musicSequence, virtualEndpoint) 已设置为指定读取过程。我使用了相同的代码,但加载了一个 MIDI 文件和为每个音符成功调用的读取过程。

【问题讨论】:

【参考方案1】:

您使用 MIDIDestinationCreate 创建一个虚拟端点,然后调用 MusicSequenceSetMIDIEndpoint 将您的序列连接到它。您指定的读取过程将在每个事件上调用。

【讨论】:

那么,它现在做你想做的事了吗? 不,MyMIDIRecProc 它永远不会被调用 应用程序需要在其 UIBackgroundModes 中有音频键才能使用 CoreMIDI 的 MIDISourceCreate 和 MIDIDestinationCreate 函数。您是否将 plist 中的键设置为音频? 哇!就是这样!我完全忘记了在我需要的背景模式下添加应用程序播放音频!惊人的!现在它工作正常,非常感谢! 让我们continue this discussion in chat。

以上是关于MIDINoteMessage 何时在 MusicTrack 中播放? iOS的主要内容,如果未能解决你的问题,请参考以下文章

music21 --> stream.chordify() 不工作

TemplateDoesNotExist 位于 /music/1/favourite/music/details.html

保存到 MIDI 文件时,Music21 一次播放所有音符

Music21 Python 库将只输出钢琴声音

Music21:获取音符的曲目索引

使用ESPRIT,LS-ESPRIT,Music以及Root-Music四种算法进行角度估计matlab仿真