diff --git a/English.lproj/MainMenu.nib/classes.nib b/English.lproj/MainMenu.nib/classes.nib
index b9b4b09..a0b26a9 100644
--- a/English.lproj/MainMenu.nib/classes.nib
+++ b/English.lproj/MainMenu.nib/classes.nib
@@ -1,4 +1,12 @@
{
- IBClasses = ({CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; });
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {playNewPitch = id; };
+ CLASS = VLAppController;
+ LANGUAGE = ObjC;
+ SUPERCLASS = NSObject;
+ }
+ );
IBVersion = 1;
}
\ No newline at end of file
diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib
index 03b2f91..52deefc 100644
--- a/English.lproj/MainMenu.nib/info.nib
+++ b/English.lproj/MainMenu.nib/info.nib
@@ -13,6 +13,7 @@
452.0
IBOpenObjects
+ 217
29
IBSystem Version
diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib
index 528c7c3..58f9805 100644
Binary files a/English.lproj/MainMenu.nib/keyedobjects.nib and b/English.lproj/MainMenu.nib/keyedobjects.nib differ
diff --git a/Resources/UserDefaults.plist b/Resources/UserDefaults.plist
new file mode 100644
index 0000000..19a993a
--- /dev/null
+++ b/Resources/UserDefaults.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ VLHighPitch
+ 75
+ VLLowPitch
+ 57
+
+
diff --git a/Sources/VLAppController.h b/Sources/VLAppController.h
new file mode 100644
index 0000000..508d698
--- /dev/null
+++ b/Sources/VLAppController.h
@@ -0,0 +1,17 @@
+//
+// VLAppController.h
+// Vocalese
+//
+// Created by Matthias Neeracher on 10/23/06.
+// Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#import
+
+@interface VLAppController : NSObject {
+
+}
+
+- (IBAction) playNewPitch:(id)sender;
+
+@end
diff --git a/Sources/VLAppController.mm b/Sources/VLAppController.mm
new file mode 100644
index 0000000..0b1f88c
--- /dev/null
+++ b/Sources/VLAppController.mm
@@ -0,0 +1,63 @@
+//
+// VLAppController.mm
+// Vocalese
+//
+// Created by Matthias Neeracher on 10/23/06.
+// Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#import "VLAppController.h"
+#import "VLPitchTransformer.h"
+#import "VLSoundOut.h"
+
+@implementation VLAppController
+
++ (void)setupDefaults
+{
+ // load the default values for the user defaults
+ NSString * userDefaultsValuesPath =
+ [[NSBundle mainBundle] pathForResource:@"UserDefaults" ofType:@"plist"];
+ NSDictionary * userDefaultsValuesDict =
+ [NSDictionary dictionaryWithContentsOfFile:userDefaultsValuesPath];
+
+ // set them in the standard user defaults
+ [[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];
+
+ // if your application supports resetting a subset of the defaults to
+ // factory values, you should set those values
+ // in the shared user defaults controller
+ NSArray * resettableUserDefaultsKeys =
+ [NSArray arrayWithObjects:@"VLLowPitch",@"VLHighPitch",nil];
+ NSDictionary * initialValuesDict =
+ [userDefaultsValuesDict dictionaryWithValuesForKeys:resettableUserDefaultsKeys];
+
+ // Set the initial values in the shared user defaults controller
+ [[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:initialValuesDict];
+}
+
++ (void)setupTransformers
+{
+ VLPitchTransformer * pitchTransformer;
+
+ // create an autoreleased instance of our value transformer
+ pitchTransformer = [[[VLPitchTransformer alloc] init] autorelease];
+
+ // register it with the name that we refer to it with
+ [NSValueTransformer setValueTransformer:pitchTransformer
+ forName:@"VLPitchTransformer"];
+}
+
++ (void)initialize
+{
+ [self setupDefaults];
+ [self setupTransformers];
+}
+
+- (IBAction) playNewPitch:(id)sender
+{
+ VLNote note(VLFraction(1,4), [sender intValue]);
+
+ VLSoundOut::Instance()->PlayNote(note);
+}
+
+@end
diff --git a/Sources/VLModel.cpp b/Sources/VLModel.cpp
index 47c7262..aaa11e3 100644
--- a/Sources/VLModel.cpp
+++ b/Sources/VLModel.cpp
@@ -84,9 +84,11 @@ static std::string PitchName(int8_t pitch, bool useSharps)
if (kScale[pitch] != ' ')
return static_cast(std::toupper(kScale[pitch])) + std::string();
else if (useSharps)
- return static_cast(std::toupper(kScale[pitch-1])) + std::string("♯");
+ return static_cast(std::toupper(kScale[pitch-1]))
+ + std::string(kVLSharpStr);
else
- return static_cast(std::toupper(kScale[pitch+1])) + std::string("♭");
+ return static_cast(std::toupper(kScale[pitch+1]))
+ + std::string(kVLFlatStr);
}
static std::string LilypondPitchName(int8_t pitch, bool useSharps)
diff --git a/Sources/VLModel.h b/Sources/VLModel.h
index 1b4b541..14cdd35 100644
--- a/Sources/VLModel.h
+++ b/Sources/VLModel.h
@@ -12,6 +12,11 @@
#include
#include
+const int kVLSharpChar = 0x266F;
+const int kVLFlatChar = 0x266D;
+const char *kVLSharpStr = "\xE2\x99\xAF";
+const char *kVLFlatStr = "\xE2\x99\xAD";
+
struct VLFract {
uint16_t fNum; // Numerator
uint16_t fDenom; // Denominator
diff --git a/Sources/VLPitchTransformer.h b/Sources/VLPitchTransformer.h
new file mode 100644
index 0000000..0d939ae
--- /dev/null
+++ b/Sources/VLPitchTransformer.h
@@ -0,0 +1,18 @@
+//
+// VLPitchTransformer.h
+// Vocalese
+//
+// Created by Matthias Neeracher on 10/23/06.
+// Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#import
+
+@interface VLPitchTransformer : NSValueTransformer {
+}
+
++ (Class)transformedValueClass;
+
+- (NSString *)transformedValue:(id)value;
+
+@end
diff --git a/Sources/VLPitchTransformer.mm b/Sources/VLPitchTransformer.mm
new file mode 100644
index 0000000..f63ed57
--- /dev/null
+++ b/Sources/VLPitchTransformer.mm
@@ -0,0 +1,35 @@
+//
+// VLPitchTransformer.mm
+// Vocalese
+//
+// Created by Matthias Neeracher on 10/23/06.
+// Copyright 2006 __MyCompanyName__. All rights reserved.
+//
+
+#import "VLPitchTransformer.h"
+#import "VLModel.h"
+
+@implementation VLPitchTransformer
+
++ (Class)transformedValueClass
+{
+ return [NSString class];
+}
+
+const char * sPitch2Name = "C D EF G A B";
+
+- (NSString *)transformedValue:(id)value
+{
+ int pitch = [value intValue];
+ int octave= (pitch / 12)-1;
+ pitch %= 12;
+ if (sPitch2Name[pitch] == ' ')
+ return [NSString stringWithFormat:@"%c%C%d / %c%C%d",
+ sPitch2Name[pitch-1], kVLSharpChar, octave,
+ sPitch2Name[pitch+1], kVLFlatChar, octave];
+ else
+ return [NSString stringWithFormat:@"%c%d",
+ sPitch2Name[pitch], octave];
+}
+
+@end
diff --git a/Vocalese.xcodeproj/project.pbxproj b/Vocalese.xcodeproj/project.pbxproj
index ed19f05..f6f3c1d 100644
--- a/Vocalese.xcodeproj/project.pbxproj
+++ b/Vocalese.xcodeproj/project.pbxproj
@@ -23,6 +23,8 @@
952DCD78096BBB11001C2316 /* VLSheetViewChords.mm in Sources */ = {isa = PBXBuildFile; fileRef = 952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */; };
953722670AE9F0E100B6E483 /* VLLilypondDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */; };
95498DBD0AE3812F006B5F81 /* VLSoundSched.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95498DBC0AE3812F006B5F81 /* VLSoundSched.mm */; };
+ 954BBD860AEDDE5300BBFD5F /* VLAppController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 954BBD850AEDDE5300BBFD5F /* VLAppController.mm */; };
+ 954BBD9A0AEDE81500BBFD5F /* VLPitchTransformer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 954BBD990AEDE81500BBFD5F /* VLPitchTransformer.mm */; };
955E58E5095658AB0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
955E59610957C1400045FDA5 /* TVLChord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E59600957C1400045FDA5 /* TVLChord.cpp */; };
955E59640957C15A0045FDA5 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
@@ -73,6 +75,10 @@
953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLLilypondDocument.mm; path = Sources/VLLilypondDocument.mm; sourceTree = ""; };
95498DBB0AE3812F006B5F81 /* VLSoundSched.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSoundSched.h; path = Sources/VLSoundSched.h; sourceTree = ""; };
95498DBC0AE3812F006B5F81 /* VLSoundSched.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLSoundSched.mm; path = Sources/VLSoundSched.mm; sourceTree = ""; };
+ 954BBD840AEDDE5300BBFD5F /* VLAppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLAppController.h; path = Sources/VLAppController.h; sourceTree = ""; };
+ 954BBD850AEDDE5300BBFD5F /* VLAppController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLAppController.mm; path = Sources/VLAppController.mm; sourceTree = ""; };
+ 954BBD980AEDE81500BBFD5F /* VLPitchTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLPitchTransformer.h; path = Sources/VLPitchTransformer.h; sourceTree = ""; };
+ 954BBD990AEDE81500BBFD5F /* VLPitchTransformer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLPitchTransformer.mm; path = Sources/VLPitchTransformer.mm; sourceTree = ""; };
955E58E3095658AB0045FDA5 /* VLModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLModel.h; path = Sources/VLModel.h; sourceTree = ""; };
955E58E4095658AB0045FDA5 /* VLModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLModel.cpp; path = Sources/VLModel.cpp; sourceTree = ""; };
955E595C0957C0FC0045FDA5 /* TVLChord */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TVLChord; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -207,6 +213,10 @@
95F5F50E0ADCC433003980B2 /* VLXMLDocument.mm */,
953722650AE9F0E100B6E483 /* VLLilypondDocument.h */,
953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */,
+ 954BBD840AEDDE5300BBFD5F /* VLAppController.h */,
+ 954BBD850AEDDE5300BBFD5F /* VLAppController.mm */,
+ 954BBD980AEDE81500BBFD5F /* VLPitchTransformer.h */,
+ 954BBD990AEDE81500BBFD5F /* VLPitchTransformer.mm */,
);
name = Classes;
sourceTree = "";
@@ -398,6 +408,8 @@
95F5F50F0ADCC433003980B2 /* VLXMLDocument.mm in Sources */,
95498DBD0AE3812F006B5F81 /* VLSoundSched.mm in Sources */,
953722670AE9F0E100B6E483 /* VLLilypondDocument.mm in Sources */,
+ 954BBD860AEDDE5300BBFD5F /* VLAppController.mm in Sources */,
+ 954BBD9A0AEDE81500BBFD5F /* VLPitchTransformer.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};