MIDI MusicDevice AudioUnit: When playing two notes of the same tone, stop one?

I'm pretty new when it comes to AudioUnits, so please forgive me if my question is very simple.

I am using MusicDevice AudioUnit to play some notes. I use MusicDeviceMIDIEvent to send notes and notes. It works well. Sometimes several notes sound simultaneously, so I can send two messages for a note in a row. Sometimes these notes have the same step. Then, when I want to turn off one of the notes, I send an event for notes for this feed. But this message disables all pitch notes. Of course, this behavior makes a lot of sense, but I wanted to ask how people usually deal with this problem.

Should I use different channels for simultaneous notes? Or, manage notes manually, say, with a counted set that stores the pitches that are currently playing and send only the note event after the last tone instance has to stop playing? Or something else?

EDIT:

Since this is on iOS, I have to use kAudioUnitSubType_Sampler as a subtype of AudioUnit. Although the documentation only mentions that this type is monotimbral, I now suspect that it is also monophonic. This, of course, explains the behavior. Nevertheless, I wonder how I would do this if I had a polyphonic instrument.

EDIT 2:

I did some more tests, and now it seems to me that sending a message with a recording on any channel stops all notes with the same pitch on all channels. I took the apple example code at http://developer.apple.com/library/ios/#samplecode/LoadPresetDemo/Introduction/Intro.html and changed the stopPlay method [low / mid / high] Note to send messages with recording to some random channel (if you know, on channels 7.8 and 9, respectively). It still stops taking notes even though recorded messages are sent on channel 0. Is this the expected behavior?

Just to make sure I'm not making a stupid mistake, these are the methods that send messages with write and write:

- (IBAction) startPlayLowNote:(id)sender { UInt32 noteNum = kLowNote; UInt32 onVelocity = 127; UInt32 noteCommand = kMIDIMessage_NoteOn << 4 | 0; OSStatus result = noErr; require_noerr (result = MusicDeviceMIDIEvent (self.samplerUnit, noteCommand, noteNum, onVelocity, 0), logTheError); logTheError: if (result != noErr) NSLog (@"Unable to start playing the low note. Error code: %d '%.4s'\n", (int) result, (const char *)&result); } - (IBAction) stopPlayLowNote:(id)sender { //note the channel! UInt32 noteNum = kLowNote; UInt32 noteCommand = kMIDIMessage_NoteOff << 4 | 7; OSStatus result = noErr; require_noerr (result = MusicDeviceMIDIEvent (self.samplerUnit, noteCommand, noteNum, 0, 0), logTheError); logTheError: if (result != noErr) NSLog (@"Unable to stop playing the low note. Error code: %d '%.4s'\n", (int) result, (const char *)&result); } 
+4
source share
2 answers

I am sure that the behavior for a note after two notes on events of the same tone on the same channel is undefined. Some instruments may disable both notes, and some may disable one and require the second note to turn off in order to disable the other.

If you really need to have two simultaneous notes of the same tone, they should be on different channels.

Modify Existing Code

I tried the sample project in your link and changed the channel in the same way as in your published code. It turns out that kAudioUnitSubType_Sampler really monotimbral, so it ignores the MIDI channel parameter. Therefore, if you want to have two simultaneous notes of the same tone with kAudioUnitSubType_Sampler , you need to create two separate instances.

Please note that kAudioUnitSubType_Sampler not monaural. It is polyphonic, as it can play several steps at once.

+4
source

How about using MusicDevice.h MusicDeviceStartNote() and MusicDeviceStopNote() ? It uses a unique note token so you can distinguish between two identical tones.

0
source

Source: https://habr.com/ru/post/1435891/


All Articles