他们似乎没有与他们相关的蜱虫
他们是否我们只需要一些数学来使用下面的逻辑在正确的时间和地点添加这些事件
如何将时间(以微秒为单位)转换为刻度,反之亦然?
这取决于2个因素
序列的格式 [PPQ 或 SMTP]
曲目的节奏[BPM]
这是这些转换的代码
//convert tick's to Microseconds
static long toMicroSeconds(float ticksPerSecond,long tick){return (long)((1E6/ticksPerSecond)*tick);}
/*
get resolution of the track
->if format is PPQ[Pulses per quater note] then this value depends on the tempo of the Sequencer
->Temp scale is nothing but tempoInBPM() & tempoScale() see Sequencer documentation for more details
*/
static float ticksPerSecond(Sequence sequence,float tempoScale)
{
float divisionType=sequence.getDivisionType();
int resolution=sequence.getResolution();
if(divisionType==Sequence.PPQ){return resolution*(tempoScale/60.0f);}
else
{
float framesPerSecond;
if(divisionType==Sequence.SMPTE_24){framesPerSecond=24;}
else if(divisionType==Sequence.SMPTE_25){framesPerSecond=25;}
else if(divisionType==Sequence.SMPTE_30){framesPerSecond=30;}
else{framesPerSecond=29.97f;}
return resolution * framesPerSecond;
}
}
//Convert time[micro second] to ticks
static long toTicks(float ticksPerSecond,long microSeconds){return (long)((ticksPerSecond/1E6)*microSeconds);}
这些转换的数学可以在这里找到
使用上述方法,您应该能够在正确的时间捕获包括程序更改在内的任何事件
我可能面临的主要问题之一就是以错误的方式获取程序更改事件
程序更改事件实际上由 2 个事件组成
更改音序器库的控制器事件
实际程序 ID
这两个信息都可以从仪器的补丁中获得
想想位于网格中的每个工具,它的 X 坐标是程序 ID,它的 Y 坐标是它的银行 ID
程序 ID 范围从 0 到 128,因此它可以通过程序更改事件进行注册,但存储库范围从 0 16385[some what close],即 2 个字节,但 ShortMessage 只能保存 1 个字节,因此需要 2 个控制更改事件来更改银行
这个实用功能应该做到这一点
void registerInstrument(Track track,Instrument instrument,int channel,int tick)
{
Patch patch=instrument.getPatch();
int
programID=patch.getProgram(),
bank=patch.getBank()
//bank is usually 0 for the first 128 instruments after which an controller event is required
if(bank>0)
{
MidiEvent c1=new MidiEvent(new ShortMessage(ShortMessage.CONTROL_CHANGE,channel,0,bank>>7),tick);
track.add(c1);
MidiEvent c2=new MidiEvent(new ShortMessage(ShortMessage.CONTROL_CHANGE,channel,32,bank&0x7f),tick);
track.add(c2);
}
track.add(new MidiEvent(new ShortMessage(ShortMessage.PROGRAM_CHANGE,channel,progrmID,0),tick));
}
我面临的一个问题是,有时我会在 MIDI 文件中获得一些没有分配任何乐器的轨道(没有程序更改事件)
某些曲目仅包含歌曲的元数据,例如版权信息或文本/速度更改事件。程序更改事件通常在同一音轨中后跟音符,因此每个音轨不必包含这些事件