使用MIDINotes将音色字体添加到MusicTrack? CoreMIDI iOS

时间:2015-06-05 10:39:06

标签: ios objective-c coremidi musicsequence

当MusicSequence按文件(.mid)加载时,我成功地将一个声音字体(.sf2)加载到MusicSequence:

        //the interesting code ...

        NSString *midiFilePath = [[NSBundle mainBundle]
                                   pathForResource:@"song"
                                   ofType:@"mid"];

        // Create a new URL which points to the MIDI file
        NSURL * midiFileURL = [NSURL fileURLWithPath:filePath];


        MusicSequenceFileLoad(s, (__bridge CFURLRef) midiFileURL, 0, 0);

        // Create a new music player
        MusicPlayer  p;
        // Initialise the music player
        NewMusicPlayer(&p);

        // ************* Set the endpoint of the sequence to be our virtual endpoint
        MusicSequenceSetMIDIEndpoint(s, virtualEndpoint);

        // Load the sound font from file
        NSURL *presetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Full Grand Piano" ofType:@"sf2"]];

        // Initialise the sound font
        [self loadFromDLSOrSoundFont: (NSURL *)presetURL withPatch: (int)10];

        // Load the sequence into the music player
        MusicPlayerSetSequence(p, s);
        // Called to do some MusicPlayer setup. This just
        // reduces latency when MusicPlayerStart is called
        MusicPlayerPreroll(p);
        // Starts the music playing
        MusicPlayerStart(p);

        //code continues here ...


-(OSStatus) loadFromDLSOrSoundFont: (NSURL *)bankURL withPatch: (int)presetNumber {

    OSStatus result = noErr;

    // fill out a bank preset data structure
    AUSamplerBankPresetData bpdata;
    bpdata.bankURL  = (__bridge CFURLRef) bankURL;
    bpdata.bankMSB  = kAUSampler_DefaultMelodicBankMSB;
    bpdata.bankLSB  = kAUSampler_DefaultBankLSB;
    bpdata.presetID = (UInt8) presetNumber;

    // set the kAUSamplerProperty_LoadPresetFromBank property
    result = AudioUnitSetProperty(self.samplerUnit,
                          kAUSamplerProperty_LoadPresetFromBank,
                          kAudioUnitScope_Global,
                          0,
                          &bpdata,
                          sizeof(bpdata));

    // check for errors
    NSCAssert (result == noErr,
       @"Unable to set the preset property on the Sampler. Error code:%d '%.4s'",
       (int) result,
       (const char *)&result);

    return result;
    }

但是如果我想将相同的音色应用于带有MIDINoteMessages的MusicTrack构建的MusicSequence:

//the interesting code here

MusicSequenceNewTrack(musicSequence, &musicTrack);

MusicSequenceGetIndTrack(musicSequence, 0, &(musicTrack));

MIDINoteMessage aMessage;
aMessage.channel = 1;

aMessage.duration = 0.3f;
aMessage.velocity = 200;

for(int i=0; i<numerator; ++i)
{
    if (i==0) {
        aMessage.note = 80;
    }else {
        aMessage.note = 60;
    }

    MusicTrackNewMIDINoteEvent(musicTrack, i, &aMessage);
}

MusicSequenceSetMIDIEndpoint(musicSequence, virtualEndpoint);

// Load the sound font from file
NSURL *presetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Full Grand Piano" ofType:@"sf2"]];

// Initialise the sound font
[self loadFromDLSOrSoundFont: (NSURL *)presetURL withPatch: (int)10];

//code continues here

我收到了(lldb)错误。知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

这是我的github项目中的声音字体相关代码。这会将声音字体加载到您的采样器单元中。如果您需要更多关于设置augraph的信息,请参阅项目或阅读此post

(1,{(2)})
(3,{(4)})
(5,{(6),(7),(8)})
(6,{(8)})

您将augraph与MusicSequence关联,就像这样

func loadSF2Preset(preset:UInt8)  {

    // This is the MuseCore soundfont. Change it to the one you have.
    if let bankURL = NSBundle.mainBundle().URLForResource("GeneralUser GS MuseScore v1.442", withExtension: "sf2") {
        var instdata = AUSamplerInstrumentData(fileURL: Unmanaged.passUnretained(bankURL),
            instrumentType: UInt8(kInstrumentType_DLSPreset),
            bankMSB: UInt8(kAUSampler_DefaultMelodicBankMSB),
            bankLSB: UInt8(kAUSampler_DefaultBankLSB),
            presetID: preset)


        var status = AudioUnitSetProperty(
            self.samplerUnit,
            AudioUnitPropertyID(kAUSamplerProperty_LoadInstrument),
            AudioUnitScope(kAudioUnitScope_Global),
            0,
            &instdata,
            UInt32(sizeof(AUSamplerInstrumentData)))
        CheckError(status)
    }
}

答案 1 :(得分:0)

在我的blog post关于MIDI回调中,我已经包含了一个github项目,该项目具有在您尝试时动态创建MusicSequence的代码。