修订版 | 27 (tree) |
---|---|
时间 | 2012-08-15 17:05:13 |
作者 | toshinagata1964 |
Handling of MIDI/Audio recording is improved; specifically, policy of stop MIDI play is made clear
@@ -96,7 +96,7 @@ | ||
96 | 96 | [view selectItemWithTag: n + 1]; |
97 | 97 | if (n >= 0 || !isInput) { |
98 | 98 | view = [self viewWithTag: kPanKnobBase + tagOffset]; |
99 | - [view setEnabled: YES]; | |
99 | + [view setEnabled: (isInput != 0)]; | |
100 | 100 | view = [self viewWithTag: kVolumeSliderBase + tagOffset]; |
101 | 101 | [view setEnabled: YES]; |
102 | 102 | view = [self viewWithTag: kLeftLevelIndicatorBase + tagOffset]; |
@@ -142,7 +142,11 @@ | ||
142 | 142 | [pauseButton setEnabled: YES]; |
143 | 143 | [ffButton setEnabled: YES]; |
144 | 144 | [rewindButton setEnabled: YES]; |
145 | - recordingPlayer = MDPlayerRecordingPlayer(); | |
145 | + if (isRecording) | |
146 | + [recordButton setState:NSOnState]; | |
147 | + else | |
148 | + [recordButton setState:NSOffState]; | |
149 | + /* recordingPlayer = MDPlayerRecordingPlayer(); | |
146 | 150 | if (recordingPlayer == NULL) { |
147 | 151 | [recordButton setEnabled: YES]; |
148 | 152 | [recordButton setState: NSOffState]; |
@@ -151,7 +155,7 @@ | ||
151 | 155 | [recordButton setState: (MDPlayerIsRecording(player) ? NSOnState : NSOffState)]; |
152 | 156 | } else { |
153 | 157 | [recordButton setEnabled: NO]; |
154 | - } | |
158 | + } */ | |
155 | 159 | if (status == kMDPlayer_playing || status == kMDPlayer_exhausted) { |
156 | 160 | playingOrRecording = YES; |
157 | 161 | [playButton setState: NSOnState]; |
@@ -399,25 +403,28 @@ | ||
399 | 403 | if (status == kMDPlayer_playing || status == kMDPlayer_exhausted) { |
400 | 404 | currentTime = MDPlayerGetTime(player); /* Update the current time */ |
401 | 405 | [self refreshTimeDisplay]; |
402 | - #if 0 | |
403 | 406 | if (isRecording) { |
404 | 407 | NSDictionary *info = [seq recordingInfo]; |
405 | - if (isPlayerRecording) { | |
408 | + // if (isPlayerRecording) { | |
406 | 409 | // Check for automatic stop recording |
407 | 410 | if ([[info valueForKey: MyRecordingInfoStopFlagKey] boolValue]) { |
408 | 411 | MDTickType currentTick = MDCalibratorTimeToTick(calibrator, currentTime); |
409 | 412 | if (currentTick > [[info valueForKey: MyRecordingInfoStopTickKey] doubleValue]) { |
410 | 413 | // Stop recording (but continue to play) |
411 | - MDPlayerStopRecording(player); | |
414 | + if (isAudioRecording) | |
415 | + [myDocument finishAudioRecording]; | |
416 | + else | |
417 | + [myDocument finishRecording]; | |
418 | + isRecording = NO; | |
419 | + [recordButton setState:NSOffState]; | |
412 | 420 | } |
413 | 421 | } |
414 | - } | |
422 | + // } | |
415 | 423 | } |
416 | - #endif | |
417 | 424 | } |
418 | 425 | // if (status != kMDPlayer_playing && !(status == kMDPlayer_exhausted && isRecording && !isAudioRecording)) { |
419 | 426 | // if (status != kMDPlayer_playing && status != kMDPlayer_suspended) { |
420 | - if (status == kMDPlayer_exhausted && !isRecording && !isAudioRecording) { | |
427 | + if (status == kMDPlayer_exhausted && (!isRecording || isAudioRecording)) { | |
421 | 428 | // If not playing, then self stop |
422 | 429 | [self pressStopButton: self]; |
423 | 430 | } |
@@ -596,6 +603,7 @@ | ||
596 | 603 | return; |
597 | 604 | } |
598 | 605 | isRecording = YES; |
606 | + [recordButton setState:NSOnState]; | |
599 | 607 | } else |
600 | 608 | MDPlayerStart(player); |
601 | 609 |
@@ -688,6 +696,7 @@ | ||
688 | 696 | [myDocument finishRecording]; |
689 | 697 | isRecording = NO; |
690 | 698 | isAudioRecording = NO; |
699 | + [recordButton setState:NSOnState]; | |
691 | 700 | } |
692 | 701 | MDPlayerStop(player); |
693 | 702 | /* MDPlayerRefreshTrackDestinations(player); *//* Refresh internal track list */ |
@@ -408,10 +408,10 @@ | ||
408 | 408 | tick = (MDTickType)[[recordingInfo valueForKey: MyRecordingInfoStartTickKey] doubleValue]; |
409 | 409 | if (tick >= 0 && tick < kMDMaxTick) |
410 | 410 | MDPlayerJumpToTick(myPlayer, tick); |
411 | - if ([[recordingInfo valueForKey: MyRecordingInfoStopFlagKey] boolValue]) { | |
411 | +/* if ([[recordingInfo valueForKey: MyRecordingInfoStopFlagKey] boolValue]) { | |
412 | 412 | tick = (MDTickType)[[recordingInfo valueForKey: MyRecordingInfoStopTickKey] doubleValue]; |
413 | 413 | MDPlayerScheduleStopTick(myPlayer, tick); |
414 | - } | |
414 | + } */ | |
415 | 415 | MDPlayerStartRecording(myPlayer); |
416 | 416 | return kMDNoError; |
417 | 417 | } |
@@ -546,10 +546,10 @@ | ||
546 | 546 | |
547 | 547 | /* #error "Maybe need to set up audio thru device here" */ |
548 | 548 | |
549 | - if ([[recordingInfo valueForKey: MyRecordingInfoStopFlagKey] boolValue]) { | |
549 | +/* if ([[recordingInfo valueForKey: MyRecordingInfoStopFlagKey] boolValue]) { | |
550 | 550 | tick = (MDTickType)[[recordingInfo valueForKey: MyRecordingInfoStopTickKey] doubleValue]; |
551 | 551 | MDPlayerScheduleStopTick(myPlayer, tick); |
552 | - } | |
552 | + } */ | |
553 | 553 | |
554 | 554 | MDPlayerStart(myPlayer); |
555 | 555 | MDAudioStartRecording(); |
@@ -1023,7 +1023,7 @@ | ||
1023 | 1023 | if (nextTick > now_tick) |
1024 | 1024 | break; /* Should be processed in the next interrupt cycle */ |
1025 | 1025 | code = MDGetCode(ep); |
1026 | - if (code == kMDSpecialEndOfSequence || code == kMDSpecialStopPlaying) { | |
1026 | + if ((code == kMDSpecialEndOfSequence && !inPlayer->isRecording) || code == kMDSpecialStopPlaying) { | |
1027 | 1027 | if (inPlayer->isRecording) |
1028 | 1028 | MDPlayerStopRecording(inPlayer); |
1029 | 1029 | if (MDAudioIsRecording()) |
@@ -1136,13 +1136,15 @@ | ||
1136 | 1136 | /* Ring metronome */ |
1137 | 1137 | if (gMetronomeInfo.enableWhenPlay || (gMetronomeInfo.enableWhenRecord && inPlayer->isRecording)) { |
1138 | 1138 | int isPrincipal = 0; |
1139 | + MDTickType metTick; | |
1140 | + MDTimeType metTime; | |
1139 | 1141 | if (inPlayer->nextMetronomeBeat < 0) { |
1140 | 1142 | PrepareMetronomeForTick(inPlayer, now_tick); |
1141 | 1143 | } |
1142 | - while (inPlayer->nextMetronomeBeat < nextTick) { | |
1144 | + while (inPlayer->nextMetronomeBeat < prefetch_tick) { | |
1143 | 1145 | if (inPlayer->nextMetronomeBeat >= inPlayer->nextMetronomeBar) { |
1144 | 1146 | /* Ring the bell */ |
1145 | - nextTick = inPlayer->nextMetronomeBar; | |
1147 | + metTick = inPlayer->nextMetronomeBar; | |
1146 | 1148 | isPrincipal = 1; |
1147 | 1149 | if (inPlayer->nextMetronomeBar == inPlayer->nextTimeSignature) { |
1148 | 1150 | /* Update the new beat/bar */ |
@@ -1169,17 +1171,18 @@ | ||
1169 | 1171 | inPlayer->nextMetronomeBar = inPlayer->nextTimeSignature; |
1170 | 1172 | } else { |
1171 | 1173 | /* Ring the click */ |
1172 | - nextTick = inPlayer->nextMetronomeBeat; | |
1174 | + metTick = inPlayer->nextMetronomeBeat; | |
1173 | 1175 | isPrincipal = 0; |
1174 | 1176 | inPlayer->nextMetronomeBeat += inPlayer->metronomeBeat; |
1175 | 1177 | } |
1176 | 1178 | if (inPlayer->nextMetronomeBeat > inPlayer->nextMetronomeBar) |
1177 | 1179 | inPlayer->nextMetronomeBeat = inPlayer->nextMetronomeBar; |
1178 | - nextTime = MDCalibratorTickToTime(inPlayer->calib, nextTick); | |
1179 | - MDPlayerRingMetronomeClick(inPlayer, nextTime, isPrincipal); | |
1180 | + metTime = MDCalibratorTickToTime(inPlayer->calib, metTick); | |
1181 | + MDPlayerRingMetronomeClick(inPlayer, metTime, isPrincipal); | |
1180 | 1182 | } |
1183 | + nextTick = inPlayer->nextMetronomeBeat; | |
1181 | 1184 | } else inPlayer->nextMetronomeBeat = -1; /* Disable internal information */ |
1182 | - | |
1185 | + | |
1183 | 1186 | *outNextTick = nextTick; |
1184 | 1187 | return bytesSent; |
1185 | 1188 | } |
@@ -1212,7 +1215,7 @@ | ||
1212 | 1215 | } |
1213 | 1216 | |
1214 | 1217 | player->time = now_time; |
1215 | - if (tick >= kMDMaxTick || player->status == kMDPlayer_exhausted) { | |
1218 | + if (tick >= kMDMaxTick || (player->status == kMDPlayer_exhausted && !player->isRecording)) { | |
1216 | 1219 | player->status = kMDPlayer_exhausted; |
1217 | 1220 | // player->time = MDCalibratorTickToTime(player->calib, MDSequenceGetDuration(MDMergerGetSequence(player->merger))); |
1218 | 1221 | if (tick >= kMDMaxTick) |
@@ -1696,16 +1699,14 @@ | ||
1696 | 1699 | MDTickType tick, duration; |
1697 | 1700 | duration = MDSequenceGetDuration(sequence); |
1698 | 1701 | MDSetKind(&anEvent, kMDEventSpecial); |
1699 | - if (inPlayer->stopTick < kMDMaxTick) { | |
1700 | - MDSetCode(&anEvent, kMDSpecialStopPlaying); | |
1701 | - MDSetTick(&anEvent, inPlayer->stopTick); | |
1702 | - RegisterEventInNoteOffTrack(inPlayer, &anEvent); | |
1703 | - } | |
1704 | - if (inPlayer->isRecording) | |
1705 | - tick = kMDMaxTick - 1; /* Don't stop at the end of sequence */ | |
1706 | - else tick = duration; | |
1702 | + if (inPlayer->stopTick < kMDMaxTick) | |
1703 | + tick = inPlayer->stopTick; | |
1704 | + else tick = kMDMaxTick - 1; | |
1705 | + MDSetCode(&anEvent, kMDSpecialStopPlaying); | |
1706 | + MDSetTick(&anEvent, inPlayer->stopTick); | |
1707 | + RegisterEventInNoteOffTrack(inPlayer, &anEvent); | |
1707 | 1708 | MDSetCode(&anEvent, kMDSpecialEndOfSequence); |
1708 | - MDSetTick(&anEvent, tick); | |
1709 | + MDSetTick(&anEvent, duration); | |
1709 | 1710 | RegisterEventInNoteOffTrack(inPlayer, &anEvent); |
1710 | 1711 | } |
1711 | 1712 |
@@ -1208,6 +1208,9 @@ | ||
1208 | 1208 | int scope; |
1209 | 1209 | if (idx >= 0 && idx < kMDAudioNumberOfInputStreams) { |
1210 | 1210 | scope = kAudioUnitScope_Input; |
1211 | + } else if (idx >= kMDAudioFirstIndexForOutputStream && idx < kMDAudioNumberOfStreams) { | |
1212 | + idx -= kMDAudioFirstIndexForOutputStream; | |
1213 | + scope = kAudioUnitScope_Output; | |
1211 | 1214 | } else return kMDErrorCannotSetupAudio; |
1212 | 1215 | CHECK_ERR(err, AudioUnitSetParameter(gAudio->mixerUnit, kStereoMixerParam_Pan, scope, idx, f32, 0)); |
1213 | 1216 | return kMDNoError; |