2

I'm currently developing an app that needs to create a MusicSequence based on user input, and I'm currently getting a -1 error on MusicSequenceFileCreate(). And -1 isn't listed as an error in the MusicSequence reference - am I using the wrong format to print OSStatus?

Any help is greatly appreciated! I haven't been able to find much reference online for saving a MusicSequence to a .mid file...

I get the error at the very end.

OSStatus status = 0;

MusicSequence newSeq;
status = NewMusicSequence(&newSeq);
if(status){
    printf("Error new sequence: %ld\n", status);
    status = 0;
} else {
    MusicSequenceSetSequenceType(newSeq, kMusicSequenceType_Seconds);
}

MusicTrack tempoTrack;
status = MusicSequenceGetTempoTrack(newSeq, &tempoTrack);
if(status){
    printf("Error getting tempo track: %ld\n", status);
    status = 0;
}
status = MusicTrackNewExtendedTempoEvent(tempoTrack, 0, 120);
if(status){
    printf("Error adding tempo to track: %ld\n", status);
    status = 0;
}

MusicTrack thisTrack;
status = MusicSequenceNewTrack(newSeq, &thisTrack);
if(status){
    printf("Error adding main track: %ld\n", status);
    status = 0;
}

for(int i = 0; i<convertThis.melodyPoints.count; i++) {
    MIDINoteMessage thisMessage;
    thisMessage.note = thisNote.midiNoteNumber;
    thisMessage.duration = thisNote.duration;
    thisMessage.velocity = 120;
    thisMessage.releaseVelocity = 0;
    thisMessage.channel = 1;
    status = MusicTrackNewMIDINoteEvent(thisTrack, thisNoteBegin, &thisMessage);
    if(status){
        printf("Error adding midi note: %ld\n", status);
        status = 0;
    }
}

NSURL *thisurl = [NSURL URLWithString:[@"~/Documents" stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mid", convertThis.title]]];
status = MusicSequenceFileCreate(newSeq, (__bridge CFURLRef) thisurl, kMusicSequenceFile_MIDIType, kMusicSequenceFileFlags_EraseFile, 0);
if(status != noErr){
    printf("Error on create: %ld\n", status);
    status = 0;
}
Kpmurphy91
  • 554
  • 5
  • 15

1 Answers1

3

Access to your documents directory like this

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                         NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

and if you'd like to create a folder inside that one to store your MIDIs you'll need to check first if it is valid or create it like this Create a folder inside documents folder in iOS apps

And add the string to a CFURLRef to use in MusicSequenceFileCreate directly

NSString *midiPath = [documentsDirectory
                               stringByAppendingPathComponent:[NSString stringWithFormat:@"/MIDIs/%@.mid",convertThis.title]];
CFURLRef midiURL = (CFURLRef)[[NSURL alloc] initFileURLWithPath:midiPath];

then just

status = MusicSequenceFileCreate(newSeq, midiURL, kMusicSequenceFile_MIDIType, kMusicSequenceFileFlags_EraseFile, 0);
Community
  • 1
  • 1
fdiaz
  • 2,430
  • 17
  • 27
  • Beware, ARC users. You might want to just __bridge that (CFURLRef) cast, but that's wrong. The CFURLRef line can cause a crash because xcode decides the NSURL isn't needed anymore since it's not actually stored in an NSURL *, so ios lets it get destroyed. You need to either give the NSURL * to its own declared object, or use a different bridging method. – Ben Wheeler Jul 30 '13 at 18:14
  • patchdiaz, this is really helpful but I'm getting an error value of -10846 for the final status. any idea what might be wrong? – Ben Wheeler Jul 30 '13 at 18:15
  • Seems that error is kAudioToolboxErr_InvalidSequenceType I believe it could be a problem with the MusicSequence? You can always use CAShow to print your sequence and see if everything is ok. – fdiaz Aug 06 '13 at 17:22
  • `MusicSequenceFileCreate` gives me an error like this `Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)` – Bijoy Thangaraj Jul 17 '18 at 05:28