Revisión | 145 (tree) |
---|---|
Tiempo | 2017-11-11 22:52:18 |
Autor | toshinagata1964 |
MIDI note transpose is implemented for MIDI thru and recording
@@ -57,9 +57,10 @@ | ||
57 | 57 | *MyRecordingInfoRecordingModeKey, // int; kRecordingMode{CountOff, WaitForNote} |
58 | 58 | *MyRecordingInfoCountOffNumberKey, // int; count off number |
59 | 59 | *MyRecordingInfoBarBeatFlagKey, // bool; countOffNumber is bar (YES) or beat (NO) |
60 | + *MyRecordingInfoMIDITransposeKey, // int; MIDI transpose | |
60 | 61 | *MyRecordingInfoAudioRecordingFormatKey, // int; kAudioRecording{AIFF,WAV}Format |
61 | 62 | *MyRecordingInfoAudioBitRateKey, // float; audio bit rate |
62 | - *MyRecordingInfoAudioChannelFormatKey; // int; kAudioRecording{Mono,Stereo}Format | |
63 | + *MyRecordingInfoAudioChannelFormatKey; // int; kAudioRecording{Mono,Stereo}Format | |
63 | 64 | |
64 | 65 | extern NSString *MyRecordingInfoFileExtensionForFormat(int format); |
65 | 66 |
@@ -40,7 +40,8 @@ | ||
40 | 40 | *MyRecordingInfoRecordingModeKey = @"recordingMode", |
41 | 41 | *MyRecordingInfoCountOffNumberKey = @"countOffNumber", |
42 | 42 | *MyRecordingInfoBarBeatFlagKey = @"barBeatFlag", |
43 | - *MyRecordingInfoAudioRecordingFormatKey = @"audioRecordingFormat", | |
43 | + *MyRecordingInfoMIDITransposeKey = @"MIDItranspose", | |
44 | + *MyRecordingInfoAudioRecordingFormatKey = @"audioRecordingFormat", | |
44 | 45 | *MyRecordingInfoAudioBitRateKey = @"audioBitRate", |
45 | 46 | *MyRecordingInfoAudioChannelFormatKey = @"audioChannelFormat"; |
46 | 47 |
@@ -104,6 +105,7 @@ | ||
104 | 105 | [NSNumber numberWithInt: 0], MyRecordingInfoRecordingModeKey, |
105 | 106 | [NSNumber numberWithInt: 0], MyRecordingInfoCountOffNumberKey, |
106 | 107 | [NSNumber numberWithBool: NO], MyRecordingInfoBarBeatFlagKey, |
108 | + [NSNumber numberWithInt: 0], MyRecordingInfoMIDITransposeKey, | |
107 | 109 | [NSNumber numberWithInt: kAudioRecordingAIFFFormat], MyRecordingInfoAudioRecordingFormatKey, |
108 | 110 | [NSNumber numberWithFloat: 44100.0], MyRecordingInfoAudioBitRateKey, |
109 | 111 | [NSNumber numberWithInt: kAudioRecordingStereoFormat], MyRecordingInfoAudioChannelFormatKey, |
@@ -392,7 +394,7 @@ | ||
392 | 394 | - (MDStatus)startMIDIRecording |
393 | 395 | { |
394 | 396 | int32_t dev; |
395 | - int ch; | |
397 | + int ch, trans; | |
396 | 398 | MDTickType tick; |
397 | 399 | NSString *destDevice; |
398 | 400 | if (mySequence == NULL || myPlayer == NULL) |
@@ -405,6 +407,8 @@ | ||
405 | 407 | else dev = -1; |
406 | 408 | ch = [[recordingInfo valueForKey: MyRecordingInfoDestinationChannelKey] intValue]; |
407 | 409 | MDPlayerSetMIDIThruDeviceAndChannel(dev, ch); |
410 | + trans = [[recordingInfo valueForKey: MyRecordingInfoMIDITransposeKey] intValue]; | |
411 | + MDPlayerSetMIDIThruTranspose(trans); | |
408 | 412 | tick = (MDTickType)[[recordingInfo valueForKey: MyRecordingInfoStartTickKey] doubleValue]; |
409 | 413 | if (tick >= 0 && tick < kMDMaxTick) |
410 | 414 | MDPlayerJumpToTick(myPlayer, tick); |
@@ -43,7 +43,9 @@ | ||
43 | 43 | IBOutlet NSSlider *audioVolumeSlider; |
44 | 44 | IBOutlet NSLevelIndicator *audioLeftLevel; |
45 | 45 | IBOutlet NSLevelIndicator *audioRightLevel; |
46 | - | |
46 | + IBOutlet NSPopUpButton *transposeOctavePopUp; | |
47 | + IBOutlet NSPopUpButton *transposeNotePopUp; | |
48 | + | |
47 | 49 | BOOL stopModalFlag; |
48 | 50 | BOOL isAudio; |
49 | 51 | MyDocument *myDocument; |
@@ -67,23 +67,12 @@ | ||
67 | 67 | } |
68 | 68 | |
69 | 69 | if (!isAudio) { |
70 | - [destinationDevicePopUp selectItemWithTitle: [info valueForKey: MyRecordingInfoDestinationDeviceKey]]; | |
71 | - } | |
72 | -// [destinationDevicePopUp selectItemWithTitle: [info valueForKey: (isAudio ? MyRecordingInfoDestinationAudioDeviceKey : MyRecordingInfoDestinationDeviceKey)]]; | |
73 | -/* if (isAudio) { | |
74 | - [playThruCheckbox setState: [[info valueForKey: MyRecordingInfoAudioPlayThroughKey] boolValue]]; | |
75 | - } */ | |
76 | - | |
77 | - if (!isAudio) { | |
70 | + [destinationDevicePopUp selectItemWithTitle: [info valueForKey: MyRecordingInfoDestinationDeviceKey]]; | |
78 | 71 | ival = [[info valueForKey: MyRecordingInfoTargetTrackKey] intValue]; |
79 | 72 | if (ival > 0 && ival < [seq trackCount]) { |
80 | 73 | [destinationTrackPopUp selectItemAtIndex: ival - 1]; |
81 | - // [destinationDevicePopUp setEnabled: NO]; | |
82 | - // [midiChannelPopUp setEnabled: NO]; | |
83 | 74 | } else { |
84 | 75 | [destinationTrackPopUp selectItemAtIndex: [destinationTrackPopUp numberOfItems] - 1]; |
85 | - // [destinationDevicePopUp setEnabled: YES]; | |
86 | - // [midiChannelPopUp setEnabled: YES]; | |
87 | 76 | } |
88 | 77 | ival = [[info valueForKey: MyRecordingInfoDestinationChannelKey] intValue]; |
89 | 78 | [midiChannelPopUp selectItemAtIndex: ival]; |
@@ -98,6 +87,9 @@ | ||
98 | 87 | [barBeatPopUp setEnabled: NO]; |
99 | 88 | [barBeatText setEnabled: NO]; |
100 | 89 | } |
90 | + ival = [[info valueForKey: MyRecordingInfoMIDITransposeKey] intValue]; | |
91 | + [transposeOctavePopUp selectItemAtIndex:8 - ((ival + 48) / 12)]; | |
92 | + [transposeNotePopUp selectItemAtIndex:((ival + 48) % 12)]; | |
101 | 93 | } |
102 | 94 | |
103 | 95 | theTick = [[info valueForKey: MyRecordingInfoStartTickKey] doubleValue]; |
@@ -398,7 +390,12 @@ | ||
398 | 390 | [info setValue: [NSNumber numberWithInt: tag] forKey: MyRecordingInfoRecordingModeKey]; |
399 | 391 | } else if (sender == barBeatPopUp) { |
400 | 392 | [info setValue: [NSNumber numberWithBool: (tag == 0)] forKey: MyRecordingInfoBarBeatFlagKey]; |
401 | - } else if (sender == audioFormatPopUp) { | |
393 | + } else if (sender == transposeOctavePopUp || sender == transposeNotePopUp) { | |
394 | + tag = (4 - [transposeOctavePopUp indexOfSelectedItem]) * 12; | |
395 | + tag += [transposeNotePopUp indexOfSelectedItem]; | |
396 | + [info setValue: [NSNumber numberWithInt: tag] forKey: MyRecordingInfoMIDITransposeKey]; | |
397 | + MDPlayerSetMIDIThruTranspose(tag); | |
398 | + } else if (sender == audioFormatPopUp) { | |
402 | 399 | [info setValue: [NSNumber numberWithInt: tag] forKey: MyRecordingInfoAudioRecordingFormatKey]; |
403 | 400 | } else if (sender == audioSampleRatePopUp) { |
404 | 401 | float fval = [[sender titleOfSelectedItem] floatValue]; |
@@ -507,7 +504,7 @@ | ||
507 | 504 | |
508 | 505 | - (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor |
509 | 506 | { |
510 | - editingText = control; | |
507 | + editingText = (NSTextField *)control; | |
511 | 508 | return YES; |
512 | 509 | } |
513 | 510 |
@@ -203,6 +203,7 @@ | ||
203 | 203 | //static MDDestinationInfo *sMIDIThruDestination = NULL; |
204 | 204 | static int32_t sMIDIThruDevice = -1; |
205 | 205 | static int sMIDIThruChannel = 0; /* 0..15; if 16, then incoming channel number is kept */ |
206 | +static int sMIDIThruTranspose = 0; | |
206 | 207 | |
207 | 208 | /* Minimum interval of interrupts */ |
208 | 209 | #define kMDPlayerMinimumInterval 50000 /* 50 msec */ |
@@ -1050,6 +1051,16 @@ | ||
1050 | 1051 | } |
1051 | 1052 | packet = (MIDIPacket *)pktlist->packet; |
1052 | 1053 | for (i = 0; i < pktlist->numPackets; i++, packet = MIDIPacketNext(packet)) { |
1054 | + if (sMIDIThruTranspose != 0) { | |
1055 | + /* Transpose */ | |
1056 | + for (j = 0; j < packet->length; j++) { | |
1057 | + if (packet->data[j] >= 0x80 && packet->data[j] <= 0x9f) { | |
1058 | + n = packet->data[j + 1] + sMIDIThruTranspose; | |
1059 | + if (n >= 0 && n < 128) | |
1060 | + packet->data[j + 1] = n; | |
1061 | + } | |
1062 | + } | |
1063 | + } | |
1053 | 1064 | if (recordingFlag) { |
1054 | 1065 | if (packet->timeStamp != 0) { |
1055 | 1066 | myTimeStamp = ConvertHostTimeToMDTimeType(packet->timeStamp) - sRecordingPlayer->startTime; |
@@ -1894,7 +1905,7 @@ | ||
1894 | 1905 | if (MDSequenceCreateMutex(inPlayer->sequence)) |
1895 | 1906 | return kMDErrorOnSequenceMutex; |
1896 | 1907 | |
1897 | - inPlayer->startTime = GetHostTimeInMDTimeType() - inPlayer->time + inPlayer->countOffDuration; | |
1908 | + inPlayer->startTime = GetHostTimeInMDTimeType() - inPlayer->time; | |
1898 | 1909 | inPlayer->countOffEndTime = inPlayer->time; |
1899 | 1910 | if (inPlayer->isRecording && inPlayer->countOffDuration > 0) { |
1900 | 1911 | /* Look for the earliest metronome tick after start time */ |
@@ -1904,6 +1915,7 @@ | ||
1904 | 1915 | MDEvent *ep = MDCalibratorGetEvent(inPlayer->calib, NULL, kMDEventTimeSignature, -1); |
1905 | 1916 | MDTickType sigtick = (ep == NULL ? 0 : MDGetTick(ep)); |
1906 | 1917 | int32_t timebase = MDSequenceGetTimebase(inPlayer->sequence); |
1918 | + inPlayer->startTime += inPlayer->countOffDuration; | |
1907 | 1919 | MDEventCalculateMetronomeBarAndBeat(ep, timebase, &bar, &beat); |
1908 | 1920 | tick -= sigtick; |
1909 | 1921 | barnum = tick / bar; |
@@ -2152,14 +2164,20 @@ | ||
2152 | 2164 | void |
2153 | 2165 | MDPlayerSetMIDIThruDeviceAndChannel(int32_t dev, int ch) |
2154 | 2166 | { |
2155 | - // if (sMIDIThruDestination != NULL) | |
2156 | - // MDPlayerReleaseDestinationInfo(sMIDIThruDestination); | |
2157 | - // sMIDIThruDestination = MDPlayerNewDestinationInfo(dev); | |
2158 | 2167 | sMIDIThruDevice = dev; |
2159 | 2168 | sMIDIThruChannel = ch; |
2160 | 2169 | } |
2161 | 2170 | |
2162 | 2171 | /* -------------------------------------- |
2172 | + ・ MDPlayerSetMIDIThruTranspose | |
2173 | + -------------------------------------- */ | |
2174 | +void | |
2175 | +MDPlayerSetMIDIThruTranspose(int transpose) | |
2176 | +{ | |
2177 | + sMIDIThruTranspose = transpose; | |
2178 | +} | |
2179 | + | |
2180 | +/* -------------------------------------- | |
2163 | 2181 | ・ MDPlayerSetCountOffSettings |
2164 | 2182 | -------------------------------------- */ |
2165 | 2183 | void |
@@ -81,6 +81,7 @@ | ||
81 | 81 | MDTickType MDPlayerGetTick(MDPlayer *inPlayer); |
82 | 82 | |
83 | 83 | void MDPlayerSetMIDIThruDeviceAndChannel(int32_t dev, int ch); |
84 | +void MDPlayerSetMIDIThruTranspose(int transpose); | |
84 | 85 | void MDPlayerSetCountOffSettings(MDPlayer *inPlayer, MDTimeType duration, MDTimeType bar, MDTimeType beat); |
85 | 86 | MDStatus MDPlayerBacktrackEvents(MDPlayer *inPlayer, MDTickType inTick, const int32_t *inEventType, const int32_t *inEventTypeLastOnly); |
86 | 87 | int MDPlayerSendRawMIDI(MDPlayer *player, const unsigned char *p, int size, int destDevice, MDTimeType scheduledTime); |