mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 11:14:00 +00:00
Implemen loading, update management
This commit is contained in:
parent
1b61bcd41e
commit
fe55af3f7c
2
English.lproj/VLDocument.nib/classes.nib
generated
2
English.lproj/VLDocument.nib/classes.nib
generated
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{CLASS = MyDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; },
|
||||
{CLASS = VLDocument; LANGUAGE = ObjC; SUPERCLASS = NSDocument; },
|
||||
{CLASS = VLEditable; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {hideFieldEditor = id; setDivisions = id; setKey = id; setTime = id; };
|
||||
CLASS = VLSheetView;
|
||||
|
|
2
English.lproj/VLDocument.nib/info.nib
generated
2
English.lproj/VLDocument.nib/info.nib
generated
|
@ -11,6 +11,6 @@
|
|||
<integer>5</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>9A274</string>
|
||||
<string>9A283</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
BIN
English.lproj/VLDocument.nib/keyedobjects.nib
generated
BIN
English.lproj/VLDocument.nib/keyedobjects.nib
generated
Binary file not shown.
|
@ -12,7 +12,7 @@
|
|||
<string>vlsong</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string></string>
|
||||
<string>vlsong.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Song</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<key>CFBundleExecutable</key>
|
||||
<string>Vocalese</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<string>vocalese</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.aereperennius.Vocalese</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
|
|
|
@ -76,8 +76,13 @@
|
|||
{
|
||||
VLProperties & prop = song->fProperties.front();
|
||||
|
||||
if (transpose)
|
||||
song->Transpose((7*((key>>8)-prop.fKey) % 12));
|
||||
|
||||
prop.fKey = key >> 8;
|
||||
prop.fMode= key & 0xFF;
|
||||
|
||||
[self updateChangeCount:NSChangeDone];
|
||||
}
|
||||
|
||||
- (NSNumber *) songTime
|
||||
|
@ -92,6 +97,8 @@
|
|||
VLProperties & prop = song->fProperties.front();
|
||||
|
||||
prop.fTime = VLFraction(num, denom);
|
||||
|
||||
[self updateChangeCount:NSChangeDone];
|
||||
}
|
||||
|
||||
- (NSNumber *) songDivisions
|
||||
|
@ -106,37 +113,19 @@
|
|||
VLProperties & prop = song->fProperties.front();
|
||||
|
||||
prop.fDivisions = divisions;
|
||||
|
||||
[self updateChangeCount:NSChangeDone];
|
||||
}
|
||||
|
||||
- (NSString *)windowNibName
|
||||
{
|
||||
// Override returning the nib file name of the document
|
||||
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
|
||||
return @"VLDocument";
|
||||
}
|
||||
|
||||
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
|
||||
- (void)windowControllerDidLoadNib:(NSWindowController *) controller
|
||||
{
|
||||
[super windowControllerDidLoadNib:aController];
|
||||
// Add any code here that needs to be executed once the windowController has loaded the document's window.
|
||||
}
|
||||
|
||||
- (NSData *)dataRepresentationOfType:(NSString *)aType
|
||||
{
|
||||
// Insert code here to write your document from the given data. You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
|
||||
|
||||
// For applications targeted for Tiger or later systems, you should use the new Tiger API -dataOfType:error:. In this case you can also choose to override -writeToURL:ofType:error:, -fileWrapperOfType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
|
||||
{
|
||||
// Insert code here to read your document from the given data. You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
|
||||
|
||||
// For applications targeted for Tiger or later systems, you should use the new Tiger API readFromData:ofType:error:. In this case you can also choose to override -readFromURL:ofType:error: or -readFromFileWrapper:ofType:error: instead.
|
||||
|
||||
return YES;
|
||||
[super windowControllerDidLoadNib:controller];
|
||||
[controller setShouldCloseDocument:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -119,6 +119,7 @@ std::string NormalizeName(NSString* rawName)
|
|||
fSong->AddChord(chord, fMeasure, fAt);
|
||||
[fView setNeedsDisplay:YES];
|
||||
}
|
||||
[[fView document] updateChangeCount:NSChangeDone];
|
||||
}
|
||||
|
||||
- (BOOL) validValue:(NSString *)val
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[self song]->AddNote(newNote, fCursorMeasure, fCursorAt);
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
[[self document] updateChangeCount:NSChangeDone];
|
||||
|
||||
VLSoundOut::Instance()->PlayNote(newNote);
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
|
||||
- (id) nodeForXPath:(NSString *)path error:(NSError **)outError
|
||||
{
|
||||
return [[self nodesForXPath:path error:outError] objectAtIndex:0];
|
||||
NSArray * nodes = [self nodesForXPath:path error:outError];
|
||||
return [nodes count] ? [nodes objectAtIndex:0] : nil;
|
||||
}
|
||||
|
||||
- (NSString *)stringForXPath:(NSString *)path error:(NSError **)outError
|
||||
|
@ -259,6 +260,105 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB ";
|
|||
return YES;
|
||||
}
|
||||
|
||||
int8_t sStepToPitch[] = {
|
||||
9, 11, 0, 2, 4, 5, 7
|
||||
};
|
||||
|
||||
- (VLNote) readNote:(NSXMLElement*)note withUnit:(VLFraction)unit
|
||||
{
|
||||
NSError * outError;
|
||||
VLNote n;
|
||||
|
||||
n.fTied = 0;
|
||||
|
||||
if ([[note elementsForName:@"rest"] count]) {
|
||||
n.fPitch = VLNote::kNoPitch;
|
||||
} else {
|
||||
n.fPitch = ([note intForXPath:@"./pitch/octave" error:&outError]+1)*12;
|
||||
n.fPitch +=
|
||||
sStepToPitch[[[note stringForXPath:@"./pitch/step" error:&outError]
|
||||
characterAtIndex:0] - 'A'];
|
||||
if (NSXMLElement * alter = [note nodeForXPath:@"./pitch/alter" error:&outError])
|
||||
n.fPitch += [[alter stringValue] intValue];
|
||||
}
|
||||
n.fDuration = VLFraction([note intForXPath:@"./duration" error:&outError])*unit;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
- (void) readMelody:(NSArray *)measures error:(NSError **)outError
|
||||
{
|
||||
NSEnumerator * e = [measures objectEnumerator];
|
||||
|
||||
for (NSXMLElement * measure; measure = [e nextObject]; ) {
|
||||
VLProperties & prop = song->fProperties.front();
|
||||
VLFraction unit(1, 4*prop.fDivisions);
|
||||
VLFraction at(0);
|
||||
int m = [[[measure attributeForName:@"number"]
|
||||
stringValue] intValue]-1;
|
||||
|
||||
if (m >= song->CountMeasures())
|
||||
song->fMeasures.resize(m);
|
||||
|
||||
NSEnumerator * n = [[measure elementsForName:@"note"] objectEnumerator];
|
||||
|
||||
for (NSXMLElement * note; note = [n nextObject]; ) {
|
||||
VLNote n = [self readNote:note withUnit:unit];
|
||||
if (n.fPitch != VLNote::kNoPitch)
|
||||
song->AddNote(n, m, at);
|
||||
at += n.fDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) readChords:(NSArray *)measures error:(NSError **)outError
|
||||
{
|
||||
NSEnumerator * e = [measures objectEnumerator];
|
||||
|
||||
for (NSXMLElement * measure; measure = [e nextObject]; ) {
|
||||
VLProperties & prop = song->fProperties.front();
|
||||
VLFraction unit(1, 4*prop.fDivisions);
|
||||
VLFraction at(0);
|
||||
VLFraction dur(0);
|
||||
int m = [[[measure attributeForName:@"number"]
|
||||
stringValue] intValue]-1;
|
||||
VLChord chord;
|
||||
|
||||
chord.fSteps = 0;
|
||||
if (m >= song->CountMeasures())
|
||||
song->fMeasures.resize(m);
|
||||
|
||||
NSEnumerator * n = [[measure elementsForName:@"note"] objectEnumerator];
|
||||
|
||||
for (NSXMLElement * note; note = [n nextObject]; ) {
|
||||
VLNote n = [self readNote:note withUnit:unit];
|
||||
if (![[note elementsForName:@"chord"] count]) {
|
||||
//
|
||||
// Start of new chord
|
||||
//
|
||||
if (chord.fSteps)
|
||||
song->AddChord(chord, m, at);
|
||||
at += dur;
|
||||
chord.fPitch = n.fPitch;
|
||||
chord.fRootPitch= VLNote::kNoPitch;
|
||||
chord.fDuration = n.fDuration;
|
||||
chord.fSteps = n.fPitch == VLNote::kNoPitch ? 0 : VLChord::kmUnison;
|
||||
dur = n.fDuration;
|
||||
if (n.fPitch < VLNote::kMiddleC) {
|
||||
chord.fPitch = VLNote::kNoPitch;
|
||||
chord.fRootPitch= n.fPitch;
|
||||
}
|
||||
} else if (chord.fPitch == VLNote::kNoPitch) {
|
||||
chord.fPitch = n.fPitch;
|
||||
} else {
|
||||
chord.fSteps |= 1 << (n.fPitch-chord.fPitch);
|
||||
}
|
||||
}
|
||||
if (chord.fSteps)
|
||||
song->AddChord(chord, m, at);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
|
||||
{
|
||||
NSXMLDocument * doc = [[NSXMLDocument alloc] initWithData:data
|
||||
|
@ -280,7 +380,12 @@ const char * sSteps = "C DbD EbE F GbG AbA BbB ";
|
|||
error:outError]
|
||||
)
|
||||
return NO;
|
||||
|
||||
|
||||
[self readMelody:[melody nodesForXPath:@"./measure" error:outError]
|
||||
error:outError];
|
||||
[self readChords:[chords nodesForXPath:@"./measure" error:outError]
|
||||
error:outError];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user