MusicTrackSetDestNode Reseting sound of sampler for old Musictracks

177 views Asked by At

I am making a music app where you can add new instruments to an existing sequencer. These instruments are separate AudioUnitSamplers stored in an array so when a new instrument and track is loaded, It is to load the sound which that track is going to use.

This how I currently add a track to the AUGraph.

// Return count as an id for the new track
- (int) addMusicTrack: (MusicTrack)musicTrack withNode:(AUNode)newSamplerNode withAudioUnit:(AudioUnit)newSamplerUnit {

    tracksCount++;
    int trackId = tracksCount;

    MusicPlayerStop(_musicPlayer);
    status = MusicSequenceNewTrack(sequence, &tracks[trackId]);
    MusicSequenceSetAUGraph(sequence, graph);

    if(status){
        printf("Error adding main track: %d", (int)status);
        status = 0;
    }

    timeDiff = 32.f/_tempo;

    [self setLoopDuration:DEFAULT_LOOP_DURATION forTrack:trackId];
    currentOctaveNumber = 59;

    AudioComponentDescription samplerNodeDesc;
    samplerNodeDesc.componentManufacturer = (OSType)kAudioUnitManufacturer_Apple;
    samplerNodeDesc.componentType = (OSType)kAudioUnitType_MusicDevice;
    samplerNodeDesc.componentSubType = (OSType)kAudioUnitSubType_Sampler;
    samplerNodeDesc.componentFlags = 0;
    samplerNodeDesc.componentFlagsMask = 0;
    status = AUGraphAddNode(graph, &samplerNodeDesc, &auSampleNodes[trackId]);

    AudioComponentDescription splitterNodeDesc;
    splitterNodeDesc.componentManufacturer = (OSType)kAudioUnitManufacturer_Apple;
    splitterNodeDesc.componentType = (OSType)kAudioUnitType_FormatConverter;
    splitterNodeDesc.componentSubType = (OSType)kAudioUnitSubType_Splitter;
    splitterNodeDesc.componentFlags = 0;
    splitterNodeDesc.componentFlagsMask = 0;
    status = AUGraphAddNode(graph, &splitterNodeDesc, &splitterNodes[trackId]);

    // node info
    status = AUGraphNodeInfo(graph, auSampleNodes[trackId], 0, &auSampleUnits[trackId]);
    status = AUGraphNodeInfo(graph, splitterNodes[trackId], 0, &splitterUnits[trackId]);

    // connecting nodes samplernode ==> Splitter ==> Mixer
    status = AUGraphConnectNodeInput(graph, auSampleNodes[trackId], 0, splitterNodes[trackId], 0);
    status = AUGraphConnectNodeInput(graph, splitterNodes[trackId], 0, mixerNode, trackId);

    status = MusicTrackSetDestNode(tracks[trackId], auSampleNodes[trackId]);

    status = AUGraphUpdate(graph, NULL);
    if (status) {printf("Error updating graph: %ld\n", status);}

    MusicPlayerStart(_musicPlayer);

    return trackId;
}

And this is how I load the sound for that track:

[self samplerUnit:auSampleUnits[trackId] loadFromDLSOrSoundFont:url withPatch:patchNumber];

soundfont Loading:

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

    OSStatus result = noErr;

    // Fill out the sampler instrument data structure
    AUSamplerInstrumentData insdata;
    insdata.fileURL = (__bridge CFURLRef) bankURL;
    insdata.bankMSB  = kAUSampler_DefaultMelodicBankMSB;
    insdata.bankLSB  = (UInt8)0;
    insdata.presetID = (UInt8) presetNumber;
    insdata.instrumentType = kInstrumentType_DLSPreset; // DLS and SF2 are the same enum values

    // Load the instrument
    result = AudioUnitSetProperty(sampler,
                                  kAUSamplerProperty_LoadInstrument,
                                  kAudioUnitScope_Global,
                                  0,
                                  &insdata,
                                  sizeof(insdata));

    NSCAssert (result == noErr,
               @"Unable to set the preset property on the Sampler. Error code: %d",
               (int) result);

    return result;
}

So currently, the appropriate sound is loaded for the track that was recently added but the sound for the older tracks is now the default AudioUnitSampler sine wave sound.

I have been trying to fix this for about a day now but haven't found a way around it, any solutions out there?

Cheers !!!

1

There are 1 answers

2
Gene De Lisa On

Did you compare trackCount with MusicSequenceGetTrackCount?

Look at the docs for MusicSequenceSetAUGraph. "By default, all music tracks in the sequence are directed to the first node in the graph that is an Instrument unit (of type DLSMusicDevice"

What do you want the splitter to do? It's not doing much right now.