MIDI:通过频道音量消息交叉淡入淡出?

时间:2012-01-01 11:07:44

标签: objective-c ios coremidi

使用FM8。

我想在第0卷的第2频道播放长笛,在第3频道播放全音量的风琴。 我想逐渐减少器官的音量,提高长笛的音量。

问题是我根本听不到长笛声音,但只有器官音量下降。

我可能误解了关于MIDI的一些非常基本的东西?

我用下面的'MUTE'的值来修改0替换为0(担心0可能被解释为某种“注释”)无济于事。

以下是代码的相关部分:

#define ORGAN   1
#define FLUTE   2

#define FULL    63
#define MUTE    1

#define BASE    0
#define M2nd    2
#define M3rd    4
#define M4th    5
#define M5th    7

#define FLUTE_CHANNEL       2
#define ORGAN_CHANNEL       3

#define CHANNEL_VOLUME      7

typedef enum {

    MIDIStatusBytesNotOff           =   0x80
,   MIDIStatusBytesNotOn            =   0x90
,   MIDIStatusBytesAfterTouch       =   0xa0
,   MIDIStatusBytesControlChange    =   0xb0
,   MIDIStatusBytesProgramChange    =   0xc0
,   MIDIStatusBytesChannelPressure  =   0xd0
,   MIDIStatusBytesPitchWheel       =   0xe0

} MIDIStatusBytes ;

- (void) sendSlowMo {

    const UInt8 baseNote = 69 ;
    const UInt8 start[]  = {
        MIDIStatusBytesProgramChange + FLUTE_CHANNEL,                   FLUTE
    ,   MIDIStatusBytesProgramChange + ORGAN_CHANNEL,                   ORGAN
    ,   MIDIStatusBytesNotOn + FLUTE_CHANNEL, baseNote+M4th,            MUTE
    ,   MIDIStatusBytesNotOn + ORGAN_CHANNEL, baseNote+BASE,            FULL
    } ;

    const UInt8 stop[]  = {
        MIDIStatusBytesNotOff + FLUTE_CHANNEL, baseNote+M4th,           MUTE
    ,   MIDIStatusBytesNotOff + ORGAN_CHANNEL, baseNote+BASE,           MUTE
    ,   MIDIStatusBytesControlChange + FLUTE_CHANNEL, CHANNEL_VOLUME,   FULL
    ,   MIDIStatusBytesControlChange + ORGAN_CHANNEL, CHANNEL_VOLUME,   FULL        
    } ;

    UInt8 stepUpDown[]  = {
        MIDIStatusBytesControlChange + FLUTE_CHANNEL, CHANNEL_VOLUME,   MUTE
    ,   MIDIStatusBytesControlChange + ORGAN_CHANNEL, CHANNEL_VOLUME,   FULL        
    } ;

    [midi sendBytes:start size:sizeof(start)];

    for (int i = 1 ; i < 128 ; ++i) {
        stepUpDown[2] = (UInt8) i ;
        stepUpDown[5] = (UInt8) (127 - i) ;

        [midi sendBytes:stepUpDown size:sizeof(stepUpDown)];
        [NSThread sleepForTimeInterval:0.10];
    }

    [midi sendBytes:stop size:sizeof(stop)];
}

我使用Pete Goodliffe's Excellent sample code作为起点。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

    ,   MIDIStatusBytesNotOn + FLUTE_CHANNEL, baseNote+M4th,            MUTE

如果我没弄错的话,你发送的NoteOn速度为0。这通常意味着NoteOff根据MIDI规范。你想要的是在发出具有最终速度的NoteOn之前将通道音量的控制器值设置为0。请注意,velocity参数表示您敲击键的力度。其他一切都必须通过触后(通道压力/按键压力)或使用像表达式这样的控制器来完成。

您可以将情况与音轨之间的渐弱进行比较:Velocity会说明音符的录音音量,而声道音量是您在执行渐变时使用的滑块的值。

编辑:我忽略了你将MUTE定义为等于1.但这并没有改变一般的讨论;它是一个(几乎)难以理解的音符,它不会因频道音量信息而变得更响亮。