我正在尝试用二十一点等编写我的小midi音序器,但坚持将sysex数据写入MusicTrack。我使用以下代码插入sysex事件
// ---- Some code here --- //
PatternData pattern = { sizeof(PatternData), i, signature.numerator, signature.denominator };
CABarBeatTime beattime = CABarBeatTime((i * signature.numerator * signature.denominator) + 1, 1, 0, SUBBEAT_DIVISOR_DEFAULT);
// Convert beattime to timestamp
if ((MusicSequenceBarBeatTimeToBeats(sequence, &beattime, ×tamp)) != noErr)
{
return status;
}
// Add event
if ((status = MusicTrackNewMIDIRawDataEvent(track, timestamp, (MIDIRawData*)&pattern)) != noErr)
{
return status;
}
// ---- Some code here --- //
PatternData是
typedef struct PatternData
{
UInt32 length; // Struct length
UInt8 index; // Pattern index
UInt8 bars; // Number of bars in patten
UInt8 beats; // Number of beats in pattern
} PatternData;
我做错了,因为在调用MusicSequenceFileCreate后我得到了损坏的文件。 有人有一个如何将sysex数据添加到音乐曲目的示例吗?
答案 0 :(得分:0)
确定。我找到了正确的方法,就是这样:
UInt8 data[] = { 0xF0, manufacturerId, databyte1, databyte2, databyte3, 0xF7 };
MIDIRawData raw;
memcpy(raw.data, data, 0, sizeof(data));
raw.length = sizeof(data);
if ((status = MusicTrackNewMIDIRawDataEvent(track, timestamp, &raw)) != noErr)
{
return status;
}
答案 1 :(得分:0)
这是一个例子,如何在MIDI轨道中录制普通的MIDI和SYSEX消息,并将它们保存在共享iTunes文件夹中的MIDI文件中(设置"应用程序支持iTunes文件共享"到&#34 ;是"在.plist中): 特别见" calloc"在代码!!
#import "ViewController.h"
#import <CoreMIDI/MIDIServices.h>
#import <CoreMIDI/CoreMIDI.h>
#import "AppDelegate.h"
#include <sys/time.h>
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@end
@implementation ViewController
@synthesize SYSEX_8;
long secTempA = 0;
float secTempB = 0;
long secStartA = 0;
float secStartB = 0;
MusicTimeStamp timeStamp = 0;
MusicSequence recordSequence;
MusicTrack recordTrack;
MusicTimeStamp lenRec = 0;
MIDINoteMessage noteMessage;
MusicTrack track;
NSString *fileNameForSave = @"";
NSString *midiFileWritePath = @"";
NSString *documentsDirectoryPath = @"";
UIAlertView *infoStore;
UIAlertView *infoStoreError;
MIDIRawData *sysexData;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Get documents Directory
// (don't forget the ".plist" entry "Application supports iTunes file sharing YES"
NSArray *pathDocDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectoryPath = [pathDocDir objectAtIndex:0];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)SYSEX_8_touchdown:(id)sender {
NewMusicSequence(&recordSequence);
MusicSequenceNewTrack(recordSequence, &recordTrack);
MusicSequenceSetSequenceType(recordSequence, kMusicSequenceType_Beats);
timeStamp = 0;
struct timeval time;
gettimeofday(&time, NULL);
secStartA = time.tv_sec;
secStartB = time.tv_usec * 0.000001;
noteMessage.channel = 0x90; // Note ON
noteMessage.note = 0x3C;
noteMessage.velocity = 0x7F;
MusicTrackNewMIDINoteEvent(recordTrack, timeStamp, ¬eMessage);
NSLog(@"%02x %02x %02x", 0x90, 0x3C, 0x7F);
usleep(10000);
gettimeofday(&time, NULL);
secTempA = time.tv_sec;
secTempB = time.tv_usec * 0.000001;
secTempA = secTempA - secStartA;
secTempB = secTempB - secStartB;
timeStamp = (secTempA + secTempB) * 2;
noteMessage.channel = 0x90; // Note OFF
noteMessage.note = 0x3C;
noteMessage.velocity = 0x00;
MusicTrackNewMIDINoteEvent(recordTrack, timeStamp, ¬eMessage);
NSLog(@"%02x %02x %02x", 0x90, 0x3C, 0x00);
usleep(100000);
gettimeofday(&time, NULL);
secTempA = time.tv_sec;
secTempB = time.tv_usec * 0.000001;
secTempA = secTempA - secStartA;
secTempB = secTempB - secStartB;
timeStamp = (secTempA + secTempB) * 2;
Byte datatest[8];
UInt32 theSize = offsetof(MIDIRawData, data[0]) + (sizeof(UInt8) * sizeof(datatest));
sysexData = (MIDIRawData *)calloc(1, theSize);
sysexData->length = sizeof(datatest);
datatest[0] = 0xF0; // Start SYSEX
datatest[1] = 0x26;
datatest[2] = 0x79;
datatest[3] = 0x0E;
datatest[4] = 0x00;
datatest[5] = 0x00;
datatest[6] = 0x00;
datatest[7] = 0xF7; // End SYSEX
for (int j = 0; j < sizeof(datatest); j++) {
sysexData->data[j] = datatest[j];
NSLog(@"%02x", sysexData->data[j]);
}
int status;
if ((status = MusicTrackNewMIDIRawDataEvent(recordTrack, timeStamp, sysexData) != noErr)) {
NSLog(@"error %i", status);
}
else {
[self stopRecording];
}
}
- (void) stopRecording {
CAShow(recordSequence); // To show all MIDI events !!!
UInt32 sz = sizeof(MusicTimeStamp);
lenRec = 0;
MusicSequenceGetIndTrack(recordSequence, 0, &track);
MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &lenRec, &sz);
if (lenRec > 0.1){
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss +zzzz"];
NSDate *startDate = [NSDate date];
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:startDate];
startDate = [startDate dateByAddingTimeInterval:interval];
// NSLog(@"Date: %@", startDate);
NSString *strDate = [[NSString alloc] initWithFormat:@"%@", startDate];
NSArray *arr = [strDate componentsSeparatedByString:@" "];
NSString *str;
str = [arr objectAtIndex:0];
NSArray *arr_date = [str componentsSeparatedByString:@"-"];
int year = [[arr_date objectAtIndex:0] intValue];
int month = [[arr_date objectAtIndex:1] intValue];
int day = [[arr_date objectAtIndex:2] intValue];
str = [arr objectAtIndex:1];
NSArray *arr_time = [str componentsSeparatedByString:@":"];
int hours = [[arr_time objectAtIndex:0] intValue];
int minutes = [[arr_time objectAtIndex:1] intValue];
int seconds = [[arr_time objectAtIndex:2] intValue];
fileNameForSave = [NSString stringWithFormat:@"%@_%04d%02d%02d_%02d%02d%02d%@", @"$Record", year, month, day, hours, minutes, seconds, @".mid"];
midiFileWritePath = [documentsDirectoryPath stringByAppendingPathComponent:fileNameForSave];
infoStore = [[UIAlertView alloc]initWithTitle: @"Save as MIDI file ?"
message: [NSString stringWithFormat:@"\n%@", fileNameForSave]
delegate: self
cancelButtonTitle: @"YES"
otherButtonTitles: @"NO",nil];
[infoStore show]; // rest siehe unten !!!!!
}
else {
MusicSequenceDisposeTrack(recordSequence, track);
DisposeMusicSequence(recordSequence);
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(int)buttonIndex {
// deletion code here
if (alertView == infoStore) {
if (buttonIndex == 0) {
NSURL *midiURL = [NSURL fileURLWithPath:midiFileWritePath];
OSStatus status = 0;
status = MusicSequenceFileCreate(recordSequence, (__bridge CFURLRef)(midiURL), kMusicSequenceFile_MIDIType, kMusicSequenceFileFlags_EraseFile, 0);
if (status != noErr) {
infoStoreError = [[UIAlertView alloc]initWithTitle: @"Information"
message: [NSString stringWithFormat:@"\nError storing MIDI file in: %@", documentsDirectoryPath]
delegate: self
cancelButtonTitle: nil
otherButtonTitles:@"OK",nil];
[infoStoreError show];
}
}
MusicSequenceDisposeTrack(recordSequence, track);
DisposeMusicSequence(recordSequence);
}
}
@end