diff --git a/Art/slow.artx/Preview/preview.png b/Art/slow.artx/Preview/preview.png new file mode 100644 index 0000000..b649e2f Binary files /dev/null and b/Art/slow.artx/Preview/preview.png differ diff --git a/Art/slow.artx/QuickLook/Preview.pdf b/Art/slow.artx/QuickLook/Preview.pdf new file mode 100644 index 0000000..f68a7d9 Binary files /dev/null and b/Art/slow.artx/QuickLook/Preview.pdf differ diff --git a/Art/slow.artx/doc.thread b/Art/slow.artx/doc.thread new file mode 100644 index 0000000..b17f99c Binary files /dev/null and b/Art/slow.artx/doc.thread differ diff --git a/English.lproj/VLDocument.xib b/English.lproj/VLDocument.xib index 2d14c48..9ef8a6e 100644 --- a/English.lproj/VLDocument.xib +++ b/English.lproj/VLDocument.xib @@ -101,10 +101,12 @@ Progress - + 1292 {{19, 14}, {16, 16}} + + _NS:3954 28938 100 @@ -164,6 +166,55 @@ YES 0 + + + 4FD2C68B-58C8-493C-8935-78D2E689B16F + + Slow + Slow + + + + 268 + {{0, 14}, {32, 32}} + + + _NS:1491 + YES + + 67763712 + 134217728 + + + LucidaGrande + 13 + 1044 + + _NS:1491 + + -2042347265 + 134 + + NSImage + slow + + + + 400 + 75 + + + + + + {32, 32} + {32, 32} + YES + YES + 0 + YES + 0 + 737868E5-40A9-4B03-B2FD-E67F9EE16B2B @@ -238,9 +289,11 @@ >> - + 268 {{0, 14}, {32, 32}} + + _NS:1491 1 YES @@ -248,11 +301,7 @@ 67763712 134217728 - - LucidaGrande - 13 - 1044 - + _NS:1491 -2042347265 @@ -286,9 +335,11 @@ << - + 268 {{0, 14}, {32, 32}} + + _NS:1491 -1 YES @@ -403,13 +454,14 @@ - + + @@ -422,6 +474,7 @@ + @@ -1584,7 +1637,7 @@ - {{0, 0}, {2560, 1418}} + {{0, 0}, {1440, 878}} {890, 428} {10000000000000, 10000000000000} 128 @@ -1800,7 +1853,7 @@ {338, 127} - {{0, 0}, {2560, 1418}} + {{0, 0}, {1440, 878}} {213, 129} {10000000000000, 10000000000000} YES @@ -2385,7 +2438,7 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA {372, 142} - {{0, 0}, {2560, 1418}} + {{0, 0}, {1440, 878}} {213, 129} {10000000000000, 10000000000000} YES @@ -3757,7 +3810,7 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA{537, 336} - {{0, 0}, {2560, 1418}} + {{0, 0}, {1440, 878}} {213, 129} {10000000000000, 10000000000000} YES @@ -4500,6 +4553,14 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA 100528 + + + playMusic: + + + + 100533 + @@ -6069,6 +6130,7 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA + @@ -6184,6 +6246,27 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA PDF Window + + 100529 + + + + + + + + 100530 + + + + + + + + 100531 + + + @@ -6343,6 +6426,10 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAAcom.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + VLToolbarButton + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -6478,7 +6565,7 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA - 100528 + 100533 @@ -6865,6 +6952,7 @@ AAAAAAAAAAAAAHRleHQAAAAAQ29weXJpZ2h0IEFwcGxlIENvbXB1dGVyLCBJbmMuLCAyMDA1AAAAAA{512, 512} {512, 512} {512, 512} + {512, 512} {128, 128} {512, 512} {512, 512} diff --git a/Resources/slow.icns b/Resources/slow.icns new file mode 100644 index 0000000..dc18852 Binary files /dev/null and b/Resources/slow.icns differ diff --git a/Sources/VLSheetWindow.mm b/Sources/VLSheetWindow.mm index d9c09a1..f98ac98 100644 --- a/Sources/VLSheetWindow.mm +++ b/Sources/VLSheetWindow.mm @@ -195,6 +195,16 @@ case 1: // Fwd VLSoundOut::Instance()->Fwd(); break; + case 0: { + float slowDown = 0.5f; + int modifiers= + [NSEvent modifierFlags] & (NSShiftKeyMask|NSAlternateKeyMask|NSCommandKeyMask|NSControlKeyMask); + while (modifiers) { + slowDown *= 0.75f; + modifiers &= modifiers-1; + } + VLSoundOut::Instance()->Slow(slowDown); } + break; case -1: // Rew VLSoundOut::Instance()->Bck(); break; diff --git a/Sources/VLSoundOut.cpp b/Sources/VLSoundOut.cpp index 8542594..2fa5ed8 100644 --- a/Sources/VLSoundOut.cpp +++ b/Sources/VLSoundOut.cpp @@ -37,6 +37,7 @@ public: virtual void SetPlayRate(float rate); virtual void Fwd(); virtual void Bck(); + virtual void Slow(float rate); virtual void SetMelodyState(MelodyState state); virtual ~VLAUSoundOut(); @@ -56,6 +57,7 @@ private: MusicTimeStamp fMusicLength; bool fRunning; bool fForward; + float fPlayRate; dispatch_source_t fMusicPoll; void Play(const int8_t * note, size_t numNotes = 1); @@ -75,6 +77,39 @@ private: OSType fDataFormat; }; +class VLResetTimer { +public: + VLResetTimer(int64_t interval, void (^block)()); + ~VLResetTimer(); + + void Prime(); +private: + dispatch_source_t fTimer; + int64_t fInterval; + void (^fBlock)(); +}; + +VLResetTimer::VLResetTimer(int64_t interval, void (^block)()) + : fInterval(interval), fBlock(Block_copy(block)) +{ + fTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + dispatch_source_set_event_handler(fTimer, fBlock); + dispatch_source_set_timer(fTimer, DISPATCH_TIME_FOREVER, INT64_MAX, 1000*NSEC_PER_USEC); + dispatch_resume(fTimer); +} + +VLResetTimer::~VLResetTimer() +{ + Block_release(fBlock); +} + +void VLResetTimer::Prime() +{ + dispatch_source_set_timer(fTimer, dispatch_time(DISPATCH_TIME_NOW, fInterval), + INT64_MAX, 10*NSEC_PER_MSEC); +} + VLSoundEvent::~VLSoundEvent() { } @@ -211,6 +246,7 @@ void VLAUSoundOut::PlaySequence(MusicSequence music) fMusic = music; fMusicLength = SequenceLength(music); + fPlayRate = 1.0; R(MusicSequenceSetAUGraph(fMusic, fGraph)); R(MusicPlayerSetSequence(fPlayer, fMusic)); @@ -248,11 +284,12 @@ void VLAUSoundOut::SetPlayRate(float rate) MusicSequenceReverse(fMusic); MusicPlayerSetTime(fPlayer, fMusicLength - rightNow); } - MusicPlayerSetPlayRateScalar(fPlayer, fabsf(rate)); + fPlayRate = fabsf(rate); + MusicPlayerSetPlayRateScalar(fPlayer, fPlayRate); } -static MusicTimeStamp sLastSkip = 0.0; -static dispatch_source_t sResetTimer; +static MusicTimeStamp sLastSkip = 0.0; +static VLResetTimer * sSkipResetTimer; void VLAUSoundOut::SkipTimeInterval() { @@ -260,17 +297,11 @@ void VLAUSoundOut::SkipTimeInterval() MusicPlayerGetTime(fPlayer, &time); time += sLastSkip; sLastSkip *= 1.1; - if (!sResetTimer) { - sResetTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, - dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); - dispatch_source_set_event_handler(sResetTimer, ^{ + if (!sSkipResetTimer) + sSkipResetTimer = new VLResetTimer(500*NSEC_PER_MSEC, ^{ sLastSkip = 0.0; }); - dispatch_source_set_timer(sResetTimer, DISPATCH_TIME_FOREVER, INT64_MAX, 1000*NSEC_PER_USEC); - dispatch_resume(sResetTimer); - } - dispatch_source_set_timer(sResetTimer, dispatch_time(DISPATCH_TIME_NOW, 500*NSEC_PER_MSEC), - INT64_MAX, 10*NSEC_PER_MSEC); + sSkipResetTimer->Prime(); MusicPlayerSetTime(fPlayer, time); } @@ -288,6 +319,18 @@ void VLAUSoundOut::Bck() SkipTimeInterval(); } +static VLResetTimer * sSlowResetTimer; + +void VLAUSoundOut::Slow(float rate) +{ + if (!sSlowResetTimer) + sSlowResetTimer = new VLResetTimer(500*NSEC_PER_MSEC, ^{ + MusicPlayerSetPlayRateScalar(fPlayer, fPlayRate); + }); + sSlowResetTimer->Prime(); + MusicPlayerSetPlayRateScalar(fPlayer, fPlayRate*rate); +} + void VLAUSoundOut::Stop(bool pause) { MusicPlayerStop(fPlayer); diff --git a/Sources/VLSoundOut.h b/Sources/VLSoundOut.h index 6ca7783..e4686b9 100644 --- a/Sources/VLSoundOut.h +++ b/Sources/VLSoundOut.h @@ -48,6 +48,7 @@ public: virtual void SetPlayRate(float rate) = 0; virtual void Fwd() = 0; virtual void Bck() = 0; + virtual void Slow(float rate) = 0; enum MelodyState { kMelodyMute, kMelodyRegular, diff --git a/VocalEasel.xcodeproj/project.pbxproj b/VocalEasel.xcodeproj/project.pbxproj index 196ee97..e7d632f 100644 --- a/VocalEasel.xcodeproj/project.pbxproj +++ b/VocalEasel.xcodeproj/project.pbxproj @@ -118,6 +118,7 @@ 95AC700514099C64007EA050 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC700314099C64007EA050 /* AudioUnit.framework */; }; 95AC700714099CF0007EA050 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC700614099CF0007EA050 /* Quartz.framework */; }; 95AC70091409A291007EA050 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95AC70081409A291007EA050 /* Carbon.framework */; }; + 95B2C10F141D154B00C96B56 /* slow.icns in Resources */ = {isa = PBXBuildFile; fileRef = 95B2C10E141D154B00C96B56 /* slow.icns */; }; 95B3E1A70960E58B000E9C0D /* Music in Resources */ = {isa = PBXBuildFile; fileRef = 95B3E1980960E58B000E9C0D /* Music */; }; 95B66658096BCA1F00FE18C9 /* VLSheetViewNotes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B66657096BCA1F00FE18C9 /* VLSheetViewNotes.mm */; }; 95BDA15909540BF1009F9D65 /* VLSheetView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95BDA15809540BF1009F9D65 /* VLSheetView.mm */; }; @@ -335,6 +336,7 @@ 95AC700314099C64007EA050 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/AudioUnit.framework; sourceTree = DEVELOPER_DIR; }; 95AC700614099CF0007EA050 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Quartz.framework; sourceTree = DEVELOPER_DIR; }; 95AC70081409A291007EA050 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; + 95B2C10E141D154B00C96B56 /* slow.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = slow.icns; path = Resources/slow.icns; sourceTree = ""; }; 95B3E1980960E58B000E9C0D /* Music */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Music; path = Resources/Music; sourceTree = ""; }; 95B66653096BC6A100FE18C9 /* VLSheetViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetViewInternal.h; path = Sources/VLSheetViewInternal.h; sourceTree = ""; }; 95B66656096BCA1F00FE18C9 /* VLSheetViewNotes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLSheetViewNotes.h; path = Sources/VLSheetViewNotes.h; sourceTree = ""; }; @@ -574,6 +576,7 @@ 953F4B70140B041800C627F9 /* Icons */ = { isa = PBXGroup; children = ( + 95B2C10E141D154B00C96B56 /* slow.icns */, 953F4B6C140B040000C627F9 /* next.icns */, 953F4B6D140B040000C627F9 /* prev.icns */, 953F4B6A140AFF2A00C627F9 /* display.icns */, @@ -1039,6 +1042,7 @@ 953F4B6B140AFF2A00C627F9 /* display.icns in Resources */, 953F4B6E140B040100C627F9 /* next.icns in Resources */, 953F4B6F140B040100C627F9 /* prev.icns in Resources */, + 95B2C10F141D154B00C96B56 /* slow.icns in Resources */, ); runOnlyForDeploymentPostprocessing = 0; };