mirror of
https://github.com/microtherion/VocalEasel.git
synced 2025-01-20 17:14:00 +00:00
Merge 1.1-dev
This commit is contained in:
parent
be789acf06
commit
510bdc0413
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
build
|
||||
*~
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -219,7 +219,7 @@ class MusicXMLListener
|
|||
@note['pitch'] = VL::NoPitch
|
||||
when 'mode', 'step', 'alter', 'octave', 'duration', 'syllabic', 'text',
|
||||
'root-step', 'root-alter', 'bass-step', 'bass-alter', 'kind',
|
||||
'degree-value', 'degree-alter', 'degree-type'
|
||||
'degree-value', 'degree-alter', 'degree-type', 'accidental'
|
||||
@kind = tag
|
||||
when 'tie'
|
||||
@note['tied'] ||= 0
|
||||
|
@ -342,6 +342,13 @@ class MusicXMLListener
|
|||
else
|
||||
@duration = @text.to_i
|
||||
end
|
||||
when 'accidental'
|
||||
case @text
|
||||
when 'sharp'
|
||||
@note['visual'] = VL::WantSharp
|
||||
when 'flat'
|
||||
@note['visual'] = VL::WantFlat
|
||||
end
|
||||
when 'root-step'
|
||||
@note['pitch'] = PITCH[@text]
|
||||
when 'bass-step'
|
||||
|
|
|
@ -59,7 +59,7 @@ def _part_list
|
|||
end
|
||||
|
||||
def _attributes(prop)
|
||||
$USE_FLATS = prop['key'] < 0
|
||||
$USE_FLATS = prop['key'] <= 0
|
||||
$DIVISIONS = prop['divisions']
|
||||
attr = REXML::Element.new('attributes')
|
||||
attr.add_element newTextElement('divisions', prop['divisions'])
|
||||
|
@ -75,7 +75,6 @@ def _attributes(prop)
|
|||
clef.add_element newTextElement('sign', 'G')
|
||||
clef.add_element newTextElement('line', 2)
|
||||
attr.add_element(clef)
|
||||
|
||||
return attr
|
||||
end
|
||||
|
||||
|
@ -103,13 +102,13 @@ end
|
|||
|
||||
STEPS = 'C DbD EbE F GbG AbA BbB '
|
||||
|
||||
def _pitch(name, pitch, prefix="")
|
||||
def _pitch(name, pitch, preferFlats, prefix="")
|
||||
oct = pitch/12 - 1
|
||||
stp = 2*(pitch%12)
|
||||
step = STEPS[stp]
|
||||
alt = STEPS[stp+1] == ?b
|
||||
if alt
|
||||
if $USE_FLATS
|
||||
if preferFlats
|
||||
alt = -1
|
||||
else
|
||||
step = step == ?A ? ?G : step-1
|
||||
|
@ -131,9 +130,20 @@ def _pitch(name, pitch, prefix="")
|
|||
return pitch
|
||||
end
|
||||
|
||||
def _addAccidental(note, pitch, preferFlats)
|
||||
stp = 2*(pitch%12)
|
||||
alt = STEPS[stp+1] == ?b
|
||||
if alt
|
||||
note.add_element newTextElement('accidental',
|
||||
preferFlats ? 'flat' : 'sharp')
|
||||
end
|
||||
end
|
||||
|
||||
TYPE = %w[whole half quarter eighth 16th 32nd]
|
||||
|
||||
def _note(pitch, dur, visual, tied)
|
||||
preferFlats = (visual & VL::WantSharp) == 0 &&
|
||||
((visual & VL::WantFlat) != 0 || $USE_FLATS)
|
||||
note = REXML::Element.new('note')
|
||||
if pitch == VL::NoPitch
|
||||
note.add_element(REXML::Element.new('rest'))
|
||||
|
@ -141,7 +151,7 @@ def _note(pitch, dur, visual, tied)
|
|||
if (tied & VL::InChord) != 0
|
||||
note.add_element 'chord'
|
||||
end
|
||||
note.add_element(_pitch('pitch', pitch))
|
||||
note.add_element(_pitch('pitch', pitch, preferFlats))
|
||||
end
|
||||
note.add_element newTextElement('duration', dur)
|
||||
if (tied & VL::TiedWithPrev) != 0
|
||||
|
@ -152,6 +162,9 @@ def _note(pitch, dur, visual, tied)
|
|||
end
|
||||
note.add_element newTextElement('voice', 1)
|
||||
note.add_element newTextElement('type', TYPE[visual & 7])
|
||||
if (visual & (VL::WantSharp | VL::WantFlat)) != 0
|
||||
_addAccidental(note, pitch, preferFlats)
|
||||
end
|
||||
|
||||
return note
|
||||
end
|
||||
|
@ -229,7 +242,9 @@ DEGREE = [
|
|||
[VL::Dim13th+VL::Min13th+VL::Maj13th, VL::Maj13th]
|
||||
];
|
||||
|
||||
def _chord(pitch, steps, root)
|
||||
def _chord(pitch, visual, steps, root)
|
||||
preferFlats = (visual & VL::WantSharp) == 0 &&
|
||||
((visual & VL::WantFlat) != 0 || $USE_FLATS)
|
||||
#
|
||||
# Pick kind. sus takes precedence
|
||||
#
|
||||
|
@ -264,10 +279,10 @@ def _chord(pitch, steps, root)
|
|||
end
|
||||
end
|
||||
harm = REXML::Element.new('harmony')
|
||||
harm.add_element(_pitch('root', pitch, 'root'))
|
||||
harm.add_element(_pitch('root', pitch, visual, 'root'))
|
||||
harm.add_element newTextElement('kind', kind)
|
||||
if root != VL::NoPitch
|
||||
harm.add_element(_pitch('bass', root, 'bass'))
|
||||
harm.add_element(_pitch('bass', root, visual, 'bass'))
|
||||
end
|
||||
needSteps = steps & ~CHORD[kind]
|
||||
extraSteps= CHORD[kind] & ~steps
|
||||
|
@ -390,7 +405,7 @@ def _melody
|
|||
m.add_element(fw)
|
||||
tempAt = chordAt
|
||||
end
|
||||
m.add_element(_chord(chord['pitch'], chord['steps'], chord['root']))
|
||||
m.add_element(_chord(chord['pitch'], chord['visual'], chord['steps'], chord['root']))
|
||||
end
|
||||
chordAt += (chord['durNum'] * $DIVISIONS * 4) / chord['durDenom']
|
||||
chordIx += 1
|
||||
|
|
|
@ -7,6 +7,8 @@ class VL
|
|||
|
||||
TiedWithNext = 1
|
||||
TiedWithPrev = 2
|
||||
WantSharp = 0x20
|
||||
WantFlat = 0x40
|
||||
InChord = 4
|
||||
|
||||
Unison = 1<<0
|
||||
|
|
|
@ -44,6 +44,10 @@
|
|||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.aereperennius.vocaleasel-song</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<true/>
|
||||
<key>NSDocumentClass</key>
|
||||
|
@ -55,6 +59,8 @@
|
|||
<string>VLMusicXMLType</string>
|
||||
<string>VLLilypondType</string>
|
||||
<string>VLMMAType</string>
|
||||
<string>VLAIFFType</string>
|
||||
<string>VLMP3Type</string>
|
||||
</array>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>XML</string>
|
||||
|
@ -72,6 +78,10 @@
|
|||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.lilypond.lilypond-source</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSDocumentClass</key>
|
||||
|
@ -130,6 +140,10 @@
|
|||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.midi</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
|
@ -148,6 +162,62 @@
|
|||
<string>VLPDFType</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.adobe.pdf</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>aiff</string>
|
||||
</array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>audio/x-aiff</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>VLAIFFType</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>AIFC</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.aifc-audio</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
<string>Binary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>mp3</string>
|
||||
</array>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>audio/mp3</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>VLMP3Type</string>
|
||||
<key>CFBundleTypeOSTypes</key>
|
||||
<array>
|
||||
<string>MPG3</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>None</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>public.mp3</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<false/>
|
||||
<key>NSPersistentStoreTypeKey</key>
|
||||
|
@ -171,7 +241,7 @@
|
|||
<key>CFBundleSignature</key>
|
||||
<string>VçEz</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0b3</string>
|
||||
<string>1.1b1</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
BIN
Resources/bck.icns
Normal file
BIN
Resources/bck.icns
Normal file
Binary file not shown.
BIN
Resources/fwd.icns
Normal file
BIN
Resources/fwd.icns
Normal file
Binary file not shown.
BIN
Resources/installLame.scpt
Normal file
BIN
Resources/installLame.scpt
Normal file
Binary file not shown.
Binary file not shown.
BIN
Resources/play.icns
Normal file
BIN
Resources/play.icns
Normal file
Binary file not shown.
Binary file not shown.
BIN
Resources/stop.icns
Normal file
BIN
Resources/stop.icns
Normal file
Binary file not shown.
Binary file not shown.
BIN
Resources/tobeg.icns
Normal file
BIN
Resources/tobeg.icns
Normal file
Binary file not shown.
BIN
Resources/toend.icns
Normal file
BIN
Resources/toend.icns
Normal file
Binary file not shown.
18
Sources/VLAIFFDocument.h
Normal file
18
Sources/VLAIFFDocument.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// File: VLAIFFDocument.h - Export document in AIFF format
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "VLDocument.h"
|
||||
|
||||
@interface VLDocument (AIFF)
|
||||
|
||||
- (NSFileWrapper *)aiffFileWrapperWithError:(NSError **)outError;
|
||||
|
||||
@end
|
34
Sources/VLAIFFDocument.mm
Normal file
34
Sources/VLAIFFDocument.mm
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// File: VLAIFFDocument.mm - Export document in AIFF format
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLAIFFDocument.h"
|
||||
#import "VLSoundOut.h"
|
||||
|
||||
#import <CoreAudio/CoreAudio.h>
|
||||
|
||||
@implementation VLDocument (AIFF)
|
||||
|
||||
- (NSFileWrapper *)aiffFileWrapperWithError:(NSError **)outError
|
||||
{
|
||||
[self createTmpFileWithExtension:@"mid" ofType:@"VLMIDIType"];
|
||||
|
||||
NSURL * midiURL = [self fileURLWithExtension:@"mid"];
|
||||
NSURL * aiffURL = [self fileURLWithExtension:@"aiff"];
|
||||
VLSoundOut *writer =
|
||||
VLSoundOut::FileWriter((CFURLRef)aiffURL, kAudioFormatLinearPCM);
|
||||
writer->PlayFile(CFDataRef([NSData dataWithContentsOfURL:midiURL]));
|
||||
delete writer;
|
||||
|
||||
return [[[NSFileWrapper alloc]
|
||||
initWithPath:[[self fileURLWithExtension:@"aiff"] path]]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
@end
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2005-2007 Matthias Neeracher
|
||||
// Copyright © 2005-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
@ -17,6 +17,7 @@
|
|||
|
||||
NSString * toolPath;
|
||||
NSString * appPath;
|
||||
NSString * lamePath;
|
||||
}
|
||||
|
||||
- (IBAction) playNewPitch:(id)sender;
|
||||
|
@ -25,6 +26,8 @@
|
|||
- (IBAction) goToHelpURL:(id)sender;
|
||||
- (IBAction) showMirror:(id)sender;
|
||||
|
||||
- (BOOL) lameIsInstalled;
|
||||
|
||||
@end
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
if (self = [super init]) {
|
||||
toolPath = nil;
|
||||
appPath = nil;
|
||||
lamePath = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -269,6 +270,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL) lameIsInstalled
|
||||
{
|
||||
if (!lamePath) {
|
||||
lamePath = [self getLineFromCommand:@"bash -l which lame"];
|
||||
if (!lamePath)
|
||||
if ([self promptForSoftwareInstallation:@"Download"
|
||||
withTitle: @"LAME Not Found!"
|
||||
explanation:
|
||||
@"The LAME MP3 encoder is needed to save songs in"
|
||||
" MP3 format.%@"
|
||||
script:@"installLame"
|
||||
url:[NSURL URLWithString:@"http://64.151.81.88/download/thalictrum/lame-3.97.dmg.gz"]]
|
||||
) {
|
||||
[[NSAlert alertWithMessageText:@"Quit and Restart"
|
||||
defaultButton: @"OK" alternateButton: @"" otherButton: @""
|
||||
informativeTextWithFormat:
|
||||
@"The software you have chosen to install will be "
|
||||
"available after you restart this application."]
|
||||
runModal];
|
||||
[NSApp terminate:self];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (IBAction) playNewPitch:(id)sender
|
||||
{
|
||||
VLNote note(VLFraction(1,4), [sender intValue]);
|
||||
|
|
|
@ -51,6 +51,7 @@ enum {
|
|||
VLKeyValueUndo* undo;
|
||||
PDFDocument * printDoc;
|
||||
NSRange previewRange;
|
||||
float playRate;
|
||||
}
|
||||
|
||||
- (VLSong *) song;
|
||||
|
@ -74,8 +75,8 @@ enum {
|
|||
- (IBAction) play:(id)sender;
|
||||
- (IBAction) stop:(id)sender;
|
||||
- (IBAction) playStop:(id)sender;
|
||||
- (IBAction) playMusic:(id)sender;
|
||||
- (IBAction) togglePlayElements:(id)sender;
|
||||
- (IBAction) playStop:(id)sender;
|
||||
|
||||
- (NSString *) tmpPath;
|
||||
- (NSString *) workPath;
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
#import "VLLilypondDocument.h"
|
||||
#import "VLMMADocument.h"
|
||||
#import "VLMIDIDocument.h"
|
||||
#import "VLAIFFDocument.h"
|
||||
#import "VLMP3Document.h"
|
||||
#import "VLPDFDocument.h"
|
||||
#import "VLPListDocument.h"
|
||||
#import "VLPDFWindow.h"
|
||||
#import "VLLogWindow.h"
|
||||
#import "VLSheetWindow.h"
|
||||
#import "VLSoundOut.h"
|
||||
#import "VLMIDIWriter.h"
|
||||
|
||||
#import <Quartz/Quartz.h>
|
||||
|
||||
|
@ -88,6 +91,7 @@
|
|||
vcsWrapper = nil;
|
||||
repeatVolta = 2;
|
||||
brandNew = true;
|
||||
playRate = 1.0;
|
||||
observers = [[NSMutableArray alloc] init];
|
||||
validTmpFiles = [[NSMutableDictionary alloc] initWithCapacity:10];
|
||||
[self setHasUndoManager:YES];
|
||||
|
@ -402,6 +406,10 @@
|
|||
return [self mmaFileWrapperWithError:outError];
|
||||
} else if ([typeName isEqual:@"VLMIDIType"]) {
|
||||
return [self midiFileWrapperWithError:outError];
|
||||
} else if ([typeName isEqual:@"VLAIFFType"]) {
|
||||
return [self aiffFileWrapperWithError:outError];
|
||||
} else if ([typeName isEqual:@"VLMP3Type"]) {
|
||||
return [self mp3FileWrapperWithError:outError];
|
||||
} else if ([typeName isEqual:@"VLPDFType"]) {
|
||||
return [self pdfFileWrapperWithError:outError];
|
||||
} else {
|
||||
|
@ -488,9 +496,29 @@
|
|||
- (IBAction) play:(id)sender
|
||||
{
|
||||
[self createTmpFileWithExtension:@"mid" ofType:@"VLMIDIType"];
|
||||
VLSoundOut::Instance()->PlayFile(
|
||||
CFDataRef([NSData dataWithContentsOfURL:
|
||||
[self fileURLWithExtension:@"mid"]]));
|
||||
|
||||
MusicSequence music;
|
||||
NewMusicSequence(&music);
|
||||
|
||||
FSRef fsRef;
|
||||
CFURLGetFSRef((CFURLRef)[self fileURLWithExtension:@"mid"], &fsRef);
|
||||
|
||||
MusicSequenceLoadSMFWithFlags(music, &fsRef,
|
||||
kMusicSequenceLoadSMF_ChannelsToTracks);
|
||||
|
||||
size_t countIn = 0;
|
||||
if (playElements & kVLPlayCountIn)
|
||||
switch ([[self songTime] intValue]) {
|
||||
case 0x404:
|
||||
case 0x304:
|
||||
case 0x608:
|
||||
countIn = 2;
|
||||
}
|
||||
VLMIDIWriter annotate(music, countIn);
|
||||
annotate.Visit(*song);
|
||||
|
||||
[sheetWin willPlaySequence:music];
|
||||
VLSoundOut::Instance()->PlaySequence(music);
|
||||
}
|
||||
|
||||
- (void) playWithGroove:(NSString *)groove inSections:(NSRange)sections
|
||||
|
@ -524,6 +552,42 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (IBAction) playMusic:(id)sender
|
||||
{
|
||||
const float kMaxRate = 8.0f;
|
||||
const float kMinRate = 0.2f;
|
||||
const float kUpScale = 1.2f;
|
||||
const float kDownScale = 0.8f;
|
||||
bool nowPlaying = VLSoundOut::Instance()->Playing();
|
||||
switch (int tag = [sender tag]) {
|
||||
case 0: // Play
|
||||
VLSoundOut::Instance()->SetPlayRate(playRate = 1.0f);
|
||||
if (!nowPlaying)
|
||||
[self play:sender];
|
||||
break;
|
||||
case 1: // Fwd
|
||||
case -1: // Rew
|
||||
if (tag * playRate < 0)
|
||||
playRate = tag;
|
||||
else if (fabsf(playRate) >= kMaxRate)
|
||||
playRate = tag*kDownScale;
|
||||
else if (fabsf(playRate) <= kMinRate)
|
||||
playRate = tag*kUpScale;
|
||||
else if (fabsf(playRate) >= 1.0f)
|
||||
playRate *= kUpScale;
|
||||
else
|
||||
playRate *= kDownScale;
|
||||
VLSoundOut::Instance()->SetPlayRate(playRate);
|
||||
break;
|
||||
case -2: // To Start
|
||||
VLSoundOut::Instance()->SetTime(0);
|
||||
break;
|
||||
case 2: // To End
|
||||
VLSoundOut::Instance()->SetTime(0x7FFFFFFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) showOutput:(id)sender
|
||||
{
|
||||
[self createTmpFileWithExtension:@"pdf" ofType:@"VLPDFType"];
|
||||
|
|
|
@ -101,12 +101,13 @@ VLTextLayout::VLTextLayout(VLFontHandler * regular, VLFontHandler * narrow)
|
|||
{
|
||||
}
|
||||
|
||||
void VLTextLayout::AddSyllable(const VLSyllable & syll, float x)
|
||||
void VLTextLayout::AddSyllable(const VLSyllable & syll, float x, bool highlight)
|
||||
{
|
||||
VLLayoutSyll ls;
|
||||
|
||||
static_cast<VLSyllable &>(ls) = syll;
|
||||
ls.fX = x;
|
||||
ls.fX = x;
|
||||
ls.fHighlight = highlight;
|
||||
|
||||
fSyllables.push_back(ls);
|
||||
}
|
||||
|
@ -130,10 +131,12 @@ void VLTextLayout::DrawLine(float y)
|
|||
float nextX = syll->fX-0.5*nextW;
|
||||
|
||||
if (syll->fKind & VLSyllable::kHasPrev)
|
||||
fRegularFont->Draw(nextX-fRegularFont->Width(PRE_DASH), y, PRE_DASH);
|
||||
fRegularFont->Draw(nextX-fRegularFont->Width(PRE_DASH), y, PRE_DASH,
|
||||
false);
|
||||
|
||||
while (syll != end) {
|
||||
std::string text = syll->fText;
|
||||
bool hl = syll->fHighlight;
|
||||
VLSyllIter next = syll+1;
|
||||
float curW = nextW;
|
||||
float curX = nextX;
|
||||
|
@ -147,8 +150,8 @@ void VLTextLayout::DrawLine(float y)
|
|||
// Plenty of space, draw dashes
|
||||
//
|
||||
float dashSpace = 0.5*(nextX-curX-curW-kDashW);
|
||||
fRegularFont->Draw(curX, y, text.c_str());
|
||||
fRegularFont->Draw(curX+curW+dashSpace, y, "-");
|
||||
fRegularFont->Draw(curX, y, text.c_str(), hl);
|
||||
fRegularFont->Draw(curX+curW+dashSpace, y, "-", hl);
|
||||
|
||||
goto nextText;
|
||||
} else {
|
||||
|
@ -167,12 +170,12 @@ void VLTextLayout::DrawLine(float y)
|
|||
//
|
||||
// Enough space, draw regular
|
||||
//
|
||||
fRegularFont->Draw(curX, y, text.c_str());
|
||||
fRegularFont->Draw(curX, y, text.c_str(), hl);
|
||||
} else {
|
||||
//
|
||||
// Tight space, draw narrow & adjust
|
||||
//
|
||||
fNarrowFont->Draw(curX, y, text.c_str());
|
||||
fNarrowFont->Draw(curX, y, text.c_str(), syll->fHighlight);
|
||||
text += NARROW_SPACE;
|
||||
nextX = std::max(nextX, curX+fNarrowFont->Width(text.c_str()));
|
||||
}
|
||||
|
@ -184,7 +187,7 @@ void VLTextLayout::DrawLine(float y)
|
|||
//
|
||||
if ((end-1)->fKind & VLSyllable::kHasNext)
|
||||
text += POST_DASH;
|
||||
fRegularFont->Draw(curX, y, text.c_str());
|
||||
fRegularFont->Draw(curX, y, text.c_str(), hl);
|
||||
nextText:
|
||||
syll = next;
|
||||
}
|
||||
|
|
|
@ -45,20 +45,22 @@ public:
|
|||
|
||||
class VLFontHandler {
|
||||
public:
|
||||
virtual void Draw(float x, float y, const char * utf8Text) = 0;
|
||||
virtual void Draw(float x, float y,
|
||||
const char * utf8Text, bool highlight) = 0;
|
||||
virtual float Width(const char * utf8Text) = 0;
|
||||
virtual ~VLFontHandler();
|
||||
};
|
||||
|
||||
struct VLLayoutSyll : public VLSyllable {
|
||||
float fX;
|
||||
bool fHighlight;
|
||||
};
|
||||
|
||||
class VLTextLayout {
|
||||
public:
|
||||
VLTextLayout(VLFontHandler * regular, VLFontHandler * narrow);
|
||||
|
||||
void AddSyllable(const VLSyllable & syll, float x);
|
||||
void AddSyllable(const VLSyllable & syll, float x, bool highlight);
|
||||
void DrawLine(float y);
|
||||
private:
|
||||
VLFontHandler * fRegularFont;
|
||||
|
|
|
@ -224,9 +224,17 @@ static std::string EscapeSyllable(std::string syll)
|
|||
return '"'+syll+'"';
|
||||
}
|
||||
|
||||
static bool PreferSharps(bool globalSharps, int noteAccidentals)
|
||||
{
|
||||
return (noteAccidentals & VLNote::kAccidentals)
|
||||
? (noteAccidentals & VLNote::kWantSharp)
|
||||
: globalSharps;
|
||||
}
|
||||
|
||||
void VLLilypondWriter::VisitNote(VLLyricsNote & n)
|
||||
{
|
||||
std::string nm = LilypondPitchName(n.fPitch, fUseSharps);
|
||||
std::string nm =
|
||||
LilypondPitchName(n.fPitch, PreferSharps(fUseSharps, n.fVisual));
|
||||
if (n.fPitch != VLNote::kNoPitch) {
|
||||
int ref = VLNote::kMiddleC-VLNote::kOctave;
|
||||
for (int ticks = (n.fPitch-ref)/VLNote::kOctave; ticks>0; --ticks)
|
||||
|
@ -248,7 +256,8 @@ void VLLilypondWriter::VisitNote(VLLyricsNote & n)
|
|||
sprintf(duration, "%s\\times 2/3 { %s%d%s }",
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHead], tie);
|
||||
else
|
||||
sprintf(duration, "%s%s%d%s", space, nm.c_str(), kValue[n.fVisual], tie);
|
||||
sprintf(duration, "%s%s%d%s",
|
||||
space, nm.c_str(), kValue[n.fVisual & VLNote::kNoteHead], tie);
|
||||
|
||||
fAccum += duration;
|
||||
fPrevNote= n;
|
||||
|
@ -271,7 +280,8 @@ static const char * kLilypondStepNames[] = {
|
|||
|
||||
void VLLilypondWriter::VisitChord(VLChord & c)
|
||||
{
|
||||
std::string name = LilypondPitchName(c.fPitch, fUseSharps);
|
||||
std::string name =
|
||||
LilypondPitchName(c.fPitch, PreferSharps(fUseSharps, c.fVisual));
|
||||
char duration[16];
|
||||
if (c.fDuration.fNum == 1 && !(c.fDuration.fDenom & (c.fDuration.fDenom-1))) // Power of two
|
||||
sprintf(duration, "%d", c.fDuration.fDenom);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
|
||||
#import "VLMIDIDocument.h"
|
||||
#import "VLMIDIWriter.h"
|
||||
|
||||
@implementation VLDocument (MIDI)
|
||||
|
||||
|
|
69
Sources/VLMIDIWriter.cpp
Normal file
69
Sources/VLMIDIWriter.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// File: VLMIDIWriter.cpp
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#include "VLMIDIWriter.h"
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
struct VLMetaEvent : MIDIMetaEvent {
|
||||
char fPadding[32];
|
||||
|
||||
VLMetaEvent(const char * label)
|
||||
{
|
||||
metaEventType = 3;
|
||||
dataLength = strlen(label);
|
||||
memcpy(data, label, dataLength);
|
||||
}
|
||||
};
|
||||
|
||||
void VLMIDIWriter::Visit(VLSong & song)
|
||||
{
|
||||
MusicSequenceNewTrack(fMusic, &fTrack);
|
||||
VLMetaEvent meta("VocalEasel");
|
||||
MusicTrackNewMetaEvent(fTrack, 0.0, &meta);
|
||||
|
||||
VisitMeasures(song, true);
|
||||
}
|
||||
|
||||
void VLMIDIWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
||||
{
|
||||
fTime = p.fTime;
|
||||
fMeasure = m;
|
||||
|
||||
if (!m)
|
||||
fChordTime = fNoteTime = fCountIn*fTime.fNum;
|
||||
|
||||
fAt = 0;
|
||||
VisitChords(meas);
|
||||
|
||||
fAt = 0;
|
||||
VisitNotes(meas, p, false);
|
||||
}
|
||||
|
||||
void VLMIDIWriter::VisitNote(VLLyricsNote & n)
|
||||
{
|
||||
if (n.fPitch != VLNote::kNoPitch && !(n.fTied & VLNote::kTiedWithPrev)) {
|
||||
VLMIDIUserEvent event = {8, n.fPitch, fMeasure, fAt};
|
||||
MusicTrackNewUserEvent(fTrack, fNoteTime,
|
||||
reinterpret_cast<const MusicEventUserData *>(&event));
|
||||
}
|
||||
fAt += n.fDuration;
|
||||
fNoteTime += n.fDuration * (float)fTime.fDenom;
|
||||
}
|
||||
|
||||
void VLMIDIWriter::VisitChord(VLChord & c)
|
||||
{
|
||||
if (c.fPitch != VLNote::kNoPitch) {
|
||||
VLMIDIUserEvent event = {8, 0, fMeasure, fAt};
|
||||
MusicTrackNewUserEvent(fTrack, fChordTime,
|
||||
reinterpret_cast<const MusicEventUserData *>(&event));
|
||||
}
|
||||
fAt += c.fDuration;
|
||||
fChordTime += c.fDuration * (float)fTime.fDenom;
|
||||
}
|
44
Sources/VLMIDIWriter.h
Normal file
44
Sources/VLMIDIWriter.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// File: VLMIDIWriter.h
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#include "VLModel.h"
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
struct VLMIDIUserEvent {
|
||||
uint32_t fLength;
|
||||
int8_t fPitch; // 0 -> Chord
|
||||
int16_t fMeasure;
|
||||
VLFract fAt;
|
||||
};
|
||||
|
||||
class VLMIDIWriter: public VLSongVisitor {
|
||||
public:
|
||||
VLMIDIWriter(MusicSequence music, size_t countIn)
|
||||
: fMusic(music), fCountIn(countIn) {}
|
||||
|
||||
virtual void Visit(VLSong & song);
|
||||
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas);
|
||||
virtual void VisitNote(VLLyricsNote & n);
|
||||
virtual void VisitChord(VLChord & c);
|
||||
private:
|
||||
MusicSequence fMusic;
|
||||
size_t fCountIn;
|
||||
MusicTrack fTrack;
|
||||
size_t fMeasure;
|
||||
MusicTimeStamp fChordTime;
|
||||
MusicTimeStamp fNoteTime;
|
||||
VLFraction fAt;
|
||||
VLFraction fTime;
|
||||
};
|
||||
|
||||
// Local Variables:
|
||||
// mode:C++
|
||||
// End:
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// File: VLMMAWriter.h
|
||||
// File: VLMMAWriter.cpp
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
|
|
18
Sources/VLMP3Document.h
Normal file
18
Sources/VLMP3Document.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// File: VLMP3Document.h - Export document in MP3 format
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "VLDocument.h"
|
||||
|
||||
@interface VLDocument (MP3)
|
||||
|
||||
- (NSFileWrapper *)mp3FileWrapperWithError:(NSError **)outError;
|
||||
|
||||
@end
|
69
Sources/VLMP3Document.mm
Normal file
69
Sources/VLMP3Document.mm
Normal file
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// File: VLMP3Document.mm - Export document in MP3 format
|
||||
//
|
||||
// Author(s):
|
||||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLMP3Document.h"
|
||||
|
||||
@implementation VLDocument (MP3)
|
||||
|
||||
- (NSFileWrapper *)mp3FileWrapperWithError:(NSError **)outError
|
||||
{
|
||||
if (![[NSApp delegate] lameIsInstalled]) {
|
||||
if (outError)
|
||||
*outError = [NSError errorWithDomain:NSPOSIXErrorDomain
|
||||
code:ENOEXEC userInfo:nil];
|
||||
return nil;
|
||||
}
|
||||
NSBundle * mainBundle = [NSBundle mainBundle];
|
||||
|
||||
[self createTmpFileWithExtension:@"aiff" ofType:@"VLAIFFType"];
|
||||
|
||||
NSURL * aiffURL = [self fileURLWithExtension:@"aiff"];
|
||||
NSURL * mp3URL = [self fileURLWithExtension:@"mp3"];
|
||||
NSString * launch =
|
||||
[mainBundle pathForResource:@"lameWrapper" ofType:@""
|
||||
inDirectory:@"bin"];
|
||||
NSArray * args = [NSArray arrayWithObjects: @"--quiet", @"-h", [aiffURL path], [mp3URL path], nil];
|
||||
NSTask * task = [self taskWithLaunchPath:launch arguments:args];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self selector:@selector(lameDone:)
|
||||
name:NSTaskDidTerminateNotification object:task];
|
||||
|
||||
[sheetWin startAnimation];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
[sheetWin stopAnimation];
|
||||
int status = [task terminationStatus];
|
||||
if (!status) {
|
||||
return [[[NSFileWrapper alloc]
|
||||
initWithPath:[[self fileURLWithExtension:@"mp3"] path]]
|
||||
autorelease];
|
||||
} else {
|
||||
if (outError)
|
||||
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
|
||||
code:NSPersistentStoreSaveError
|
||||
userInfo:nil];
|
||||
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)lameDone:(NSNotification *)notification {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self
|
||||
name:NSTaskDidTerminateNotification object:[notification object]];
|
||||
int status = [[notification object] terminationStatus];
|
||||
if (!status) {
|
||||
;
|
||||
} else {
|
||||
NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2005-2007 Matthias Neeracher
|
||||
// Copyright © 2005-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#include "VLModel.h"
|
||||
|
@ -104,15 +104,19 @@ VLNote::VLNote(std::string name)
|
|||
name.erase(0, 1);
|
||||
//
|
||||
// Look for sharp / flat
|
||||
//
|
||||
//
|
||||
fVisual = 0;
|
||||
if (name.size())
|
||||
if (name[0] == '#') {
|
||||
++fPitch;
|
||||
fVisual |= kWantSharp;
|
||||
name.erase(0);
|
||||
} else if (name[0] == 'b') {
|
||||
--fPitch;
|
||||
fVisual |= kWantFlat;
|
||||
name.erase(0, 1);
|
||||
}
|
||||
AdjustAccidentals();
|
||||
if (name == "")
|
||||
return;
|
||||
|
||||
|
@ -127,14 +131,14 @@ VLNote::VLNote(VLFraction dur, int pitch)
|
|||
|
||||
void VLNote::Name(std::string & name, bool useSharps) const
|
||||
{
|
||||
name = PitchName(fPitch, useSharps);
|
||||
name = PitchName(fPitch, useSharps && !(fVisual & kWantFlat));
|
||||
}
|
||||
|
||||
void VLNote::MakeRepresentable()
|
||||
{
|
||||
if (fDuration > 1)
|
||||
fDuration = 1;
|
||||
fVisual = kWhole;
|
||||
fVisual = kWhole | (fVisual & kAccidentals);
|
||||
VLFraction part(1,1);
|
||||
VLFraction triplet(2,3);
|
||||
//
|
||||
|
@ -159,6 +163,26 @@ void VLNote::MakeRepresentable()
|
|||
abort();
|
||||
}
|
||||
|
||||
void VLNote::AdjustAccidentals()
|
||||
{
|
||||
//
|
||||
// Don't store accidental preferences for whole notes:
|
||||
// There is no way to represent these in MusicXML, so saving and
|
||||
// reloading would change behavior.
|
||||
//
|
||||
enum {
|
||||
kC = 1<<0,
|
||||
kD = 1<<2,
|
||||
kE = 1<<4,
|
||||
kF = 1<<5,
|
||||
kG = 1<<7,
|
||||
kA = 1<<9,
|
||||
kB = 1<<11
|
||||
};
|
||||
if ((1 << (fPitch % 12)) & (kC | kD | kE | kF | kG | kA | kB))
|
||||
fVisual &= ~kAccidentals;
|
||||
}
|
||||
|
||||
void VLNote::AlignToGrid(VLFraction at, VLFraction grid)
|
||||
{
|
||||
if (at+fDuration > grid) {
|
||||
|
@ -232,11 +256,14 @@ VLChord::VLChord(std::string name)
|
|||
if (name.size())
|
||||
if (name[0] == '#') {
|
||||
++fPitch;
|
||||
fVisual |= kWantSharp;
|
||||
name.erase(0, 1);
|
||||
} else if (name[0] == 'b') {
|
||||
--fPitch;
|
||||
fVisual |= kWantFlat;
|
||||
name.erase(0, 1);
|
||||
}
|
||||
AdjustAccidentals();
|
||||
//
|
||||
// Root
|
||||
//
|
||||
|
@ -300,7 +327,7 @@ static const char * kStepNames[] = {
|
|||
|
||||
void VLChord::Name(std::string & base, std::string & ext, std::string & root, bool useSharps) const
|
||||
{
|
||||
base = PitchName(fPitch, useSharps);
|
||||
base = PitchName(fPitch, useSharps && !(fVisual & kWantFlat));
|
||||
ext = "";
|
||||
root = "";
|
||||
|
||||
|
@ -372,7 +399,7 @@ void VLChord::Name(std::string & base, std::string & ext, std::string & root, bo
|
|||
// Root
|
||||
//
|
||||
if (fRootPitch != kNoPitch)
|
||||
root = PitchName(fRootPitch, useSharps);
|
||||
root = PitchName(fRootPitch, useSharps && !(fVisual & kWantFlat));
|
||||
}
|
||||
|
||||
VLMeasure::VLMeasure()
|
||||
|
@ -490,7 +517,7 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
|
|||
//
|
||||
// First swing note (4th triplet -> 8th)
|
||||
//
|
||||
p.fVisual = (p.fVisual+1) & VLNote::kNoteHead;
|
||||
p.fVisual = (p.fVisual+1) & ~VLNote::kTriplet;
|
||||
}
|
||||
} else if ((p.fDuration == sw12 && ((at+p.fDuration) % grid4 == 0))
|
||||
|| (swing16 && p.fDuration == sw24 && ((at+p.fDuration) % grid8 == 0))
|
||||
|
@ -498,7 +525,7 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
|
|||
//
|
||||
// Second swing note (8th triplet -> 8th)
|
||||
//
|
||||
p.fVisual &= VLNote::kNoteHead;
|
||||
p.fVisual &= ~VLNote::kTriplet;
|
||||
} else if ((at % p.fDuration != 0)
|
||||
|| (p.fDuration != c.fDuration
|
||||
&& 2*p.fDuration != c.fDuration)
|
||||
|
@ -507,7 +534,7 @@ void VLMeasure::DecomposeNotes(const VLProperties & prop, VLNoteList & decompose
|
|||
// Get rid of awkward triplets
|
||||
//
|
||||
p.fDuration *= VLFraction(3,4);
|
||||
p.fVisual = (p.fVisual+1) & VLNote::kNoteHead;
|
||||
p.fVisual = (p.fVisual+1) & ~VLNote::kTriplet;
|
||||
}
|
||||
}
|
||||
haveDuration:
|
||||
|
@ -703,6 +730,8 @@ void VLSong::AddNote(VLLyricsNote note, size_t measure, VLFraction at)
|
|||
//
|
||||
while (measure+1 >= fMeasures.size())
|
||||
AddMeasure();
|
||||
|
||||
note.AdjustAccidentals();
|
||||
|
||||
VLNoteList::iterator i = fMeasures[measure].fMelody.begin();
|
||||
VLFraction t(0);
|
||||
|
@ -863,6 +892,7 @@ void VLSong::ExtendNote(size_t measure, VLFraction at)
|
|||
// Extend previous note
|
||||
//
|
||||
k->fPitch = i->fPitch;
|
||||
k->fVisual= i->fVisual;
|
||||
k->fTied = VLNote::kTiedWithPrev;
|
||||
i->fTied |= VLNote::kTiedWithNext;
|
||||
k->fLyrics.clear();
|
||||
|
@ -935,6 +965,7 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
|
|||
for (; i!=e; ++i) {
|
||||
TransposePinned(i->fPitch, semi);
|
||||
TransposePinned(i->fRootPitch, semi);
|
||||
i->AdjustAccidentals();
|
||||
}
|
||||
}
|
||||
for (int pass=0; pass<2 && semi;) {
|
||||
|
@ -953,6 +984,7 @@ void VLSong::ChangeKey(int section, int newKey, int newMode, bool transpose)
|
|||
i->fPitch += semi;
|
||||
low = std::min(low, i->fPitch);
|
||||
high = std::max(high, i->fPitch);
|
||||
i->AdjustAccidentals();
|
||||
}
|
||||
}
|
||||
if (low < VLNote::kMiddleC-6 && high < VLNote::kMiddleC+7)
|
||||
|
|
|
@ -145,12 +145,16 @@ struct VLNote {
|
|||
k32nd = 5,
|
||||
|
||||
kNoteHead = 0x07,
|
||||
kWantSharp = 0x20,
|
||||
kWantFlat = 0x40,
|
||||
kAccidentals= 0x60,
|
||||
kTriplet = 0x80
|
||||
};
|
||||
VLNote(VLFraction dur=0, int pitch=kNoPitch);
|
||||
VLNote(std::string name);
|
||||
void Name(std::string & name, bool useSharps = false) const;
|
||||
void MakeRepresentable();
|
||||
void AdjustAccidentals();
|
||||
void AlignToGrid(VLFraction at, VLFraction grid);
|
||||
};
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ void VLPlistVisitor::VisitChord(VLChord & c)
|
|||
[NSNumber numberWithInt:c.fDuration.fNum], @"durNum",
|
||||
[NSNumber numberWithInt:c.fDuration.fDenom], @"durDenom",
|
||||
[NSNumber numberWithInt:c.fPitch], @"pitch",
|
||||
[NSNumber numberWithInt:c.fVisual], @"visual",
|
||||
[NSNumber numberWithInt:c.fSteps], @"steps",
|
||||
[NSNumber numberWithInt:c.fRootPitch], @"root",
|
||||
nil];
|
||||
|
@ -230,8 +231,10 @@ void VLPlistVisitor::VisitChord(VLChord & c)
|
|||
VLFraction([[ndict objectForKey:@"durNum"] intValue],
|
||||
[[ndict objectForKey:@"durDenom"] intValue],
|
||||
true);
|
||||
note.fPitch = [[ndict objectForKey:@"pitch"] intValue];
|
||||
note.fTied = 0;
|
||||
note.fPitch = [[ndict objectForKey:@"pitch"] intValue];
|
||||
note.fVisual |= [[ndict objectForKey:@"visual"] intValue]
|
||||
& VLNote::kAccidentals;
|
||||
note.fTied = 0;
|
||||
|
||||
if ([[ndict objectForKey:@"tied"] intValue] & VLNote::kTiedWithPrev) {
|
||||
if (at != 0) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#import "VLModel.h"
|
||||
#import "VLLayout.h"
|
||||
|
@ -83,6 +84,11 @@ enum VLRecalc {
|
|||
size_t fVolta;
|
||||
size_t fVoltaOK;
|
||||
VLLayout * fLayout;
|
||||
int fHighlightMeasure;
|
||||
VLFract fHighlightAt;
|
||||
size_t fHighlightStanza;
|
||||
bool fHighlightNow;
|
||||
bool fHighlightOne;
|
||||
|
||||
IBOutlet id fFieldEditor;
|
||||
IBOutlet id fRepeatSheet;
|
||||
|
@ -109,10 +115,10 @@ enum VLRecalc {
|
|||
- (VLSong *) song;
|
||||
- (NSImage *) musicElement:(VLMusicElement)elt;
|
||||
|
||||
- (int) stepInSection:(int)section withPitch:(int)pitch;
|
||||
- (int) stepInSection:(int)section withPitch:(int)pitch visual:(int)visual;
|
||||
- (float) systemY:(int)system;
|
||||
- (float) noteYInSection:(int)section withPitch:(int)pitch accidental:(VLMusicElement*)accidental;
|
||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch accidental:(VLMusicElement*)accidental;
|
||||
- (float) noteYInSection:(int)section withPitch:(int)pitch visual:(int)visual accidental:(VLMusicElement*)accidental;
|
||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch visual:(int)visual accidental:(VLMusicElement*)accidental;
|
||||
- (float) noteXInMeasure:(int)measure at:(VLFraction)at;
|
||||
|
||||
- (void) scrollMeasureToVisible:(int)measure;
|
||||
|
@ -131,6 +137,8 @@ enum VLRecalc {
|
|||
- (void) setGroove:(NSString *)groove;
|
||||
- (void) playWithGroove:(NSString *)groove;
|
||||
|
||||
- (NSColor *)textBackgroundColorForSystem:(int)system;
|
||||
|
||||
@end
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -97,6 +97,7 @@ static float sFlatPos[] = {
|
|||
fNumBotLedgers = 2;
|
||||
fNumStanzas = 2;
|
||||
fLastMeasures = 0;
|
||||
fHighlightOne = false;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ static float sFlatPos[] = {
|
|||
return kSystemBaseline+b.origin.y+b.size.height-(system+1)*kSystemH;
|
||||
}
|
||||
|
||||
int8_t sSemi2Pitch[2][12] = {{
|
||||
int8_t sSemi2Pitch[4][12] = {{
|
||||
// C Db D Eb E F Gb G Ab A Bb B
|
||||
0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6,
|
||||
},{
|
||||
|
@ -151,7 +152,7 @@ int8_t sSemi2Pitch[2][12] = {{
|
|||
#define N kMusicNatural,
|
||||
#define _ kMusicNothing,
|
||||
|
||||
VLMusicElement sSemi2Accidental[12][12] = {
|
||||
VLMusicElement sSemi2Accidental[13][12] = {
|
||||
// C DbD EbE F GbG AbA BbB
|
||||
{N _ N _ N _ _ N _ N _ N}, // Gb major - 6 flats
|
||||
{_ _ N _ N _ _ N _ N _ N}, // Db major - 5 flats
|
||||
|
@ -166,6 +167,7 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
|||
{N _ _ S _ N _ N _ _ S _}, // A major - 3 sharps
|
||||
{N _ N _ _ N _ N _ _ S _}, // E major - 4 sharps
|
||||
{N _ N _ _ N _ N _ N _ _}, // B major - 5 sharps
|
||||
{N _ N _ N N _ N _ N _ _}, // F# major - 6 sharps
|
||||
};
|
||||
|
||||
#undef S
|
||||
|
@ -173,33 +175,46 @@ VLMusicElement sSemi2Accidental[12][12] = {
|
|||
#undef N
|
||||
#undef _
|
||||
|
||||
- (int) stepInSection:(int)section withPitch:(int)pitch
|
||||
- (int) stepInSection:(int)section withPitch:(int)pitch visual:(int)visual
|
||||
{
|
||||
int semi = pitch % 12;
|
||||
int key = [self song]->fProperties[section].fKey;
|
||||
bool useSharps = key > 0;
|
||||
bool useSharps = (visual & VLNote::kAccidentals)
|
||||
? (visual & VLNote::kWantSharp) : (key > 0);
|
||||
|
||||
return sSemi2Pitch[useSharps][semi];
|
||||
}
|
||||
|
||||
- (float) noteYInSection:(int)section
|
||||
withPitch:(int)pitch accidental:(VLMusicElement*)accidental
|
||||
- (float) noteYInSection:(int)section withPitch:(int)pitch
|
||||
visual:(int)visual accidental:(VLMusicElement*)accidental
|
||||
{
|
||||
int semi = pitch % 12;
|
||||
int octave = (pitch / 12) - 5;
|
||||
int key = [self song]->fProperties[section].fKey;
|
||||
|
||||
*accidental = sSemi2Accidental[key+6][semi];
|
||||
switch (*accidental = sSemi2Accidental[key+6][semi]) {
|
||||
case kMusicSharp:
|
||||
if (visual & VLNote::kWantFlat)
|
||||
*accidental = kMusicFlat;
|
||||
break;
|
||||
case kMusicFlat:
|
||||
if (visual & VLNote::kWantSharp)
|
||||
*accidental = kMusicSharp;
|
||||
break;
|
||||
}
|
||||
|
||||
return (octave*3.5f
|
||||
+ [self stepInSection:section withPitch:pitch]*0.5f-1.0f)*kLineH;
|
||||
+ [self stepInSection:section withPitch:pitch visual:visual]*0.5f
|
||||
- 1.0f
|
||||
)* kLineH;
|
||||
}
|
||||
|
||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch accidental:(VLMusicElement*)accidental
|
||||
- (float) noteYInMeasure:(int)measure withPitch:(int)pitch
|
||||
visual:(int)visual accidental:(VLMusicElement*)accidental
|
||||
{
|
||||
return [self systemY:fLayout->SystemForMeasure(measure)]
|
||||
+ [self noteYInSection:[self song]->fMeasures[measure].fPropIdx
|
||||
withPitch:pitch accidental:accidental];
|
||||
withPitch:pitch visual:visual accidental:accidental];
|
||||
}
|
||||
|
||||
- (float) noteXInMeasure:(int)measure at:(VLFraction)at
|
||||
|
@ -492,20 +507,24 @@ const char * sBreak[3] = {"", "\xE2\xA4\xBE", "\xE2\x8E\x98"};
|
|||
withAttributes: sBreakFont];
|
||||
}
|
||||
|
||||
- (void)drawBackgroundForSystem:(int)system
|
||||
- (NSColor *)notesBackgroundColorForSystem:(int)system
|
||||
{
|
||||
NSArray * colors = [NSColor controlAlternatingRowBackgroundColors];
|
||||
|
||||
return [colors objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSColor *)textBackgroundColorForSystem:(int)system
|
||||
{
|
||||
const VLSong * song = [self song];
|
||||
const float kSystemY = [self systemY:system];
|
||||
const float kLineW = (*fLayout)[system].SystemWidth();
|
||||
const bool kAltColors = song->fMeasures[fLayout->FirstMeasure(system)].fPropIdx & 1;
|
||||
|
||||
NSArray * colors = [NSColor controlAlternatingRowBackgroundColors];
|
||||
NSColor * bgColor= [colors objectAtIndex:0];
|
||||
NSColor * fgColor= [colors objectAtIndex:1];
|
||||
NSColor * color= [colors objectAtIndex:1];
|
||||
if (kAltColors) {
|
||||
float hue, saturation, brightness, alpha;
|
||||
|
||||
[[fgColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getHue:&hue saturation:&saturation
|
||||
[[color colorUsingColorSpaceName:NSCalibratedRGBColorSpace] getHue:&hue saturation:&saturation
|
||||
brightness:&brightness alpha:&alpha];
|
||||
|
||||
if (saturation) // Color
|
||||
|
@ -513,17 +532,25 @@ const char * sBreak[3] = {"", "\xE2\xA4\xBE", "\xE2\x8E\x98"};
|
|||
else // Black & white
|
||||
brightness -= 0.05f;
|
||||
|
||||
fgColor = [NSColor colorWithCalibratedHue:hue saturation:saturation
|
||||
brightness:brightness alpha:alpha];
|
||||
color = [NSColor colorWithCalibratedHue:hue saturation:saturation
|
||||
brightness:brightness alpha:alpha];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
- (void)drawBackgroundForSystem:(int)system
|
||||
{
|
||||
const float kSystemY = [self systemY:system];
|
||||
const float kLineW = (*fLayout)[system].SystemWidth();
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[fgColor setFill];
|
||||
[[self textBackgroundColorForSystem:system] setFill];
|
||||
[NSBezierPath fillRect:
|
||||
NSMakeRect(kLineX, kSystemY-kSystemBaseline,
|
||||
kLineW, fNumStanzas*kLyricsH)];
|
||||
[NSBezierPath fillRect:
|
||||
NSMakeRect(kLineX, kSystemY+kChordY, kLineW, kChordH)];
|
||||
[bgColor setFill];
|
||||
[[self notesBackgroundColorForSystem:system] setFill];
|
||||
[NSBezierPath fillRect:
|
||||
NSMakeRect(kLineX, kSystemY-kSystemBaseline+fNumStanzas*kLyricsH,
|
||||
kLineW, kSystemBaseline+kChordY-fNumStanzas*kLyricsH)];
|
||||
|
@ -731,8 +758,10 @@ static int8_t sSharpAcc[] = {
|
|||
fCursorAccidental = kMusicFlatCursor; // G# -> Gb
|
||||
fCursorActualPitch = fCursorPitch-1;
|
||||
break;
|
||||
default:
|
||||
case NSCommandKeyMask:
|
||||
fCursorAccidental = kMusicSharpCursor;
|
||||
// Fall through
|
||||
default:
|
||||
fCursorActualPitch = fCursorPitch+1;
|
||||
break; // G# -> G#
|
||||
case NSAlternateKeyMask|NSCommandKeyMask:
|
||||
|
@ -745,8 +774,10 @@ static int8_t sSharpAcc[] = {
|
|||
} else {
|
||||
if (prop.fKey <= -sFlatAcc[fCursorPitch % 12]) { // Flat in Key
|
||||
switch ([event modifierFlags] & (NSAlternateKeyMask|NSCommandKeyMask)) {
|
||||
default:
|
||||
case NSAlternateKeyMask:
|
||||
fCursorAccidental = kMusicFlatCursor;
|
||||
// Fall through
|
||||
default:
|
||||
fCursorActualPitch = fCursorPitch-1;
|
||||
break; // Gb -> Gb
|
||||
case NSCommandKeyMask:
|
||||
|
@ -978,6 +1009,8 @@ static int8_t sSharpAcc[] = {
|
|||
break;
|
||||
default:
|
||||
[editable autorelease];
|
||||
fHighlightStanza = 0xFFFFFFFF;
|
||||
fHighlightOne = false;
|
||||
editable = nil;
|
||||
}
|
||||
[self setEditTarget:editable];
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
- (void) editLyrics;
|
||||
- (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza;
|
||||
- (void) highlightLyricsInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at;
|
||||
- (void) highlightTextInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at one:(BOOL)one;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
VLFraction At = fAt;
|
||||
fSong->FindWord(fStanza, fMeasure, At);
|
||||
fAt = At;
|
||||
[fView highlightTextInStanza:fStanza measure:fMeasure at:fAt one:NO];
|
||||
|
||||
[fView setNeedsDisplay: YES];
|
||||
|
||||
|
@ -78,6 +79,7 @@
|
|||
}
|
||||
fNextMeas = fMeasure;
|
||||
fNextAt = fAt;
|
||||
[fView highlightTextInStanza:fStanza measure:fMeasure at:fAt];
|
||||
[fView scrollMeasureToVisible:fMeasure];
|
||||
}
|
||||
|
||||
|
@ -92,12 +94,15 @@
|
|||
fAt = at;
|
||||
fNextMeas = fMeasure;
|
||||
fNextAt = fAt;
|
||||
[fView highlightTextInStanza:fStanza measure:fMeasure at:fAt];
|
||||
[fView scrollMeasureToVisible:fMeasure];
|
||||
}
|
||||
|
||||
- (void) highlightCursor
|
||||
{
|
||||
[fView highlightLyricsInStanza:fStanza measure:fMeasure at:fAt];
|
||||
std::string word = fSong->GetWord(fStanza, fMeasure, fAt);
|
||||
if (!word.size())
|
||||
[fView highlightLyricsInStanza:fStanza measure:fMeasure at:fAt];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -106,7 +111,7 @@ class VLCocoaFontHandler : public VLFontHandler {
|
|||
public:
|
||||
VLCocoaFontHandler(NSString * name, float size);
|
||||
|
||||
virtual void Draw(float x, float y, const char * utf8Text);
|
||||
virtual void Draw(float x, float y, const char * utf8Text, bool highlight);
|
||||
virtual float Width(const char * utf8Text);
|
||||
private:
|
||||
NSDictionary * fTextAttr;
|
||||
|
@ -121,10 +126,20 @@ VLCocoaFontHandler::VLCocoaFontHandler(NSString * name, float size)
|
|||
font, NSFontAttributeName, nil];
|
||||
}
|
||||
|
||||
void VLCocoaFontHandler::Draw(float x, float y, const char * utf8Text)
|
||||
static NSColor * sHighlightColor;
|
||||
|
||||
void VLCocoaFontHandler::Draw(float x, float y,
|
||||
const char * utf8Text, bool highlight)
|
||||
{
|
||||
NSString * t = [NSString stringWithUTF8String:utf8Text];
|
||||
[t drawAtPoint:NSMakePoint(x,y) withAttributes:fTextAttr];
|
||||
NSDictionary * attr = fTextAttr;
|
||||
if (highlight) {
|
||||
NSMutableDictionary * aa =
|
||||
[NSMutableDictionary dictionaryWithDictionary:attr];
|
||||
[aa setValue:sHighlightColor forKey:NSBackgroundColorAttributeName];
|
||||
attr = aa;
|
||||
}
|
||||
NSString * t = [NSString stringWithUTF8String:utf8Text];
|
||||
[t drawAtPoint:NSMakePoint(x,y) withAttributes:attr];
|
||||
}
|
||||
|
||||
float VLCocoaFontHandler::Width(const char * utf8Text)
|
||||
|
@ -171,14 +186,28 @@ float VLCocoaFontHandler::Width(const char * utf8Text)
|
|||
) {
|
||||
;
|
||||
} else {
|
||||
if (!fHighlightNow) {
|
||||
fHighlightNow = stanza == fHighlightStanza
|
||||
&& measIdx == fHighlightMeasure
|
||||
&& at == fHighlightAt;
|
||||
if (fHighlightNow && !sHighlightColor)
|
||||
sHighlightColor =
|
||||
[[self textBackgroundColorForSystem:system]
|
||||
shadowWithLevel:0.2];
|
||||
}
|
||||
|
||||
text.AddSyllable(note->fLyrics[stanza-1],
|
||||
[self noteXInMeasure:measIdx at:at]);
|
||||
[self noteXInMeasure:measIdx at:at],
|
||||
fHighlightNow);
|
||||
fHighlightNow = fHighlightNow && !fHighlightOne &&
|
||||
note->fLyrics[stanza-1].fKind & VLSyllable::kHasNext;
|
||||
}
|
||||
at += note->fDuration;
|
||||
}
|
||||
}
|
||||
|
||||
text.DrawLine(kSystemY+kLyricsY-stanza*kLyricsH);
|
||||
sHighlightColor = nil;
|
||||
}
|
||||
|
||||
- (void) editLyrics
|
||||
|
@ -196,6 +225,21 @@ float VLCocoaFontHandler::Width(const char * utf8Text)
|
|||
|
||||
- (void) highlightLyricsInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at
|
||||
{
|
||||
const float kSystemY = [self systemY:fLayout->SystemForMeasure(measure)];
|
||||
NSRect r =
|
||||
NSMakeRect([self noteXInMeasure:measure at:at]-kNoteW*0.5f,
|
||||
kSystemY+kLyricsY-stanza*kLyricsH, kNoteW, kLyricsH);
|
||||
[[NSColor colorWithCalibratedWhite:0.8f alpha:1.0f] setFill];
|
||||
NSRectFillUsingOperation(r, NSCompositePlusDarker);
|
||||
}
|
||||
|
||||
- (void) highlightTextInStanza:(size_t)stanza measure:(int)measure at:(VLFraction)at one:(BOOL)one
|
||||
{
|
||||
fHighlightStanza = stanza;
|
||||
fHighlightMeasure= measure;
|
||||
fHighlightAt = at;
|
||||
fHighlightNow = false;
|
||||
fHighlightOne = one;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
- (void) drawNotesForSystem:(int)system;
|
||||
- (void) addNoteAtCursor;
|
||||
- (void) startKeyboardCursor;
|
||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2005-2007 Matthias Neeracher
|
||||
// Copyright © 2005-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLSheetView.h"
|
||||
|
@ -22,7 +22,14 @@
|
|||
{
|
||||
if (fCursorMeasure > -1) {
|
||||
VLNote newNote(1, fClickMode==' ' ? fCursorActualPitch : VLNote::kNoPitch);
|
||||
|
||||
switch (fCursorAccidental) {
|
||||
case kMusicFlatCursor:
|
||||
newNote.fVisual |= VLNote::kWantFlat;
|
||||
break;
|
||||
case kMusicSharpCursor:
|
||||
newNote.fVisual |= VLNote::kWantSharp;
|
||||
break;
|
||||
}
|
||||
[[self document] willChangeSong];
|
||||
if (fCursorAccidental == kMusicExtendCursor)
|
||||
[self song]->ExtendNote(fCursorMeasure, fCursorAt);
|
||||
|
@ -49,11 +56,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void) drawLedgerLinesInSection:(int)section withPitch:(int)pitch at:(NSPoint)p
|
||||
- (void) drawLedgerLinesInSection:(int)section withPitch:(int)pitch visual:(int)visual at:(NSPoint)p
|
||||
{
|
||||
p.x += kLedgerX;
|
||||
int octave = (pitch / 12) - 5;
|
||||
int step = (octave*7+[self stepInSection:section withPitch:pitch]-2)/2;
|
||||
int step = (octave*7
|
||||
+ [self stepInSection:section withPitch:pitch visual:visual]
|
||||
- 2
|
||||
) / 2;
|
||||
|
||||
for (int i=0; i-- > step; ) {
|
||||
NSPoint p0 = p;
|
||||
|
@ -71,71 +81,96 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void) drawNoteCursor
|
||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at
|
||||
accidental:(VLMusicElement)accidental
|
||||
mode:(char)mode
|
||||
{
|
||||
int cursorX;
|
||||
int cursorY;
|
||||
int cursorSect;
|
||||
VLMusicElement accidental;
|
||||
int cursorVisual = 0;
|
||||
VLMusicElement acc;
|
||||
VLMusicElement cursorElt;
|
||||
|
||||
cursorX = [self noteXInMeasure:fCursorMeasure at:fCursorAt];
|
||||
if (fCursorAccidental == kMusicExtendCursor) {
|
||||
cursorX = [self noteXInMeasure:measure at:at];
|
||||
if (accidental == kMusicExtendCursor) {
|
||||
cursorY =
|
||||
[self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch
|
||||
accidental:&accidental];
|
||||
cursorElt = fCursorAccidental;
|
||||
[self noteYInMeasure:measure
|
||||
withPitch:pitch
|
||||
visual:0
|
||||
accidental:&acc];
|
||||
cursorElt = accidental;
|
||||
} else
|
||||
switch (fClickMode) {
|
||||
switch (mode) {
|
||||
default:
|
||||
switch (accidental) {
|
||||
case kMusicSharp:
|
||||
cursorVisual = VLNote::kWantSharp;
|
||||
break;
|
||||
case kMusicFlat:
|
||||
cursorVisual = VLNote::kWantFlat;
|
||||
break;
|
||||
}
|
||||
cursorY =
|
||||
[self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch accidental:&accidental] - kNoteY;
|
||||
cursorSect = [self song]->fMeasures[fCursorMeasure].fPropIdx;
|
||||
[self drawLedgerLinesInSection:cursorSect withPitch:fCursorPitch
|
||||
at:NSMakePoint(cursorX,
|
||||
[self systemY:fLayout->SystemForMeasure(fCursorMeasure)])];
|
||||
[self noteYInMeasure:measure withPitch:pitch
|
||||
visual:cursorVisual accidental:&acc] - kNoteY;
|
||||
cursorSect = [self song]->fMeasures[measure].fPropIdx;
|
||||
[self drawLedgerLinesInSection:cursorSect withPitch:pitch
|
||||
visual:cursorVisual at:NSMakePoint(cursorX,
|
||||
[self systemY:fLayout->SystemForMeasure(measure)])];
|
||||
cursorElt = kMusicNoteCursor;
|
||||
break;
|
||||
case 'r':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:65 accidental:&accidental];
|
||||
cursorY = [self noteYInMeasure:measure
|
||||
withPitch:65 visual:0 accidental:&acc];
|
||||
cursorElt = kMusicRestCursor;
|
||||
break;
|
||||
case 'k':
|
||||
cursorY = [self noteYInMeasure:fCursorMeasure
|
||||
withPitch:fCursorPitch accidental:&accidental];
|
||||
cursorY = [self noteYInMeasure:measure
|
||||
withPitch:pitch visual:0
|
||||
accidental:&acc];
|
||||
cursorElt = kMusicKillCursor;
|
||||
break;
|
||||
}
|
||||
|
||||
NSPoint at = NSMakePoint(cursorX-kNoteX, cursorY);
|
||||
NSPoint xy = NSMakePoint(cursorX-kNoteX, cursorY);
|
||||
[[self musicElement:cursorElt]
|
||||
compositeToPoint:at
|
||||
compositeToPoint:xy
|
||||
operation: NSCompositeSourceOver];
|
||||
if (fCursorAccidental && fCursorAccidental != kMusicExtendCursor) {
|
||||
at.y += kNoteY;
|
||||
switch (cursorElt= fCursorAccidental) {
|
||||
if (accidental && accidental != kMusicExtendCursor) {
|
||||
xy.y += kNoteY;
|
||||
switch (cursorElt= accidental) {
|
||||
case kMusicFlatCursor:
|
||||
at.x += kFlatW;
|
||||
at.y += kFlatY;
|
||||
xy.x += kFlatW;
|
||||
xy.y += kFlatY;
|
||||
break;
|
||||
case kMusicSharpCursor:
|
||||
at.x += kSharpW;
|
||||
at.y += kSharpY;
|
||||
xy.x += kSharpW;
|
||||
xy.y += kSharpY;
|
||||
break;
|
||||
default:
|
||||
at.x += kNaturalW;
|
||||
at.y += kNaturalY;
|
||||
xy.x += kNaturalW;
|
||||
xy.y += kNaturalY;
|
||||
break;
|
||||
}
|
||||
[[self musicElement:cursorElt]
|
||||
compositeToPoint:at
|
||||
compositeToPoint:xy
|
||||
operation: NSCompositeSourceOver];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at
|
||||
{
|
||||
[self drawNoteCursor:pitch inMeasure:measure at:at
|
||||
accidental:kMusicNothing mode:' '];
|
||||
}
|
||||
|
||||
- (void) drawNoteCursor
|
||||
{
|
||||
[self drawNoteCursor:fCursorPitch inMeasure:fCursorMeasure at:fCursorAt
|
||||
accidental:kMusicNothing mode:' '];
|
||||
}
|
||||
|
||||
- (void) drawNote:(int)visual at:(NSPoint)p
|
||||
accidental:(VLMusicElement)accidental tied:(BOOL)tied
|
||||
{
|
||||
|
@ -304,16 +339,20 @@
|
|||
int pitch = note->fPitch;
|
||||
if (pitch != VLNote::kNoPitch) {
|
||||
[self drawLedgerLinesInSection:measure.fPropIdx withPitch:pitch
|
||||
at:NSMakePoint([self noteXInMeasure:measIdx at:at], kSystemY)];
|
||||
visual:note->fVisual
|
||||
at:NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||
kSystemY)];
|
||||
VLMusicElement accidental;
|
||||
NSPoint pos =
|
||||
NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||
kSystemY+[self noteYInSection:measure.fPropIdx
|
||||
withPitch:pitch
|
||||
visual:note->fVisual
|
||||
accidental:&accidental]);
|
||||
VLMusicElement acc = accidental;
|
||||
int step= [self stepInSection:measure.fPropIdx
|
||||
withPitch:pitch];
|
||||
withPitch:pitch
|
||||
visual:note->fVisual];
|
||||
if (acc == accidentals[step])
|
||||
acc = kMusicNothing; // Don't repeat accidentals
|
||||
else if (acc == kMusicNothing)
|
||||
|
@ -331,7 +370,7 @@
|
|||
NSPoint pos =
|
||||
NSMakePoint([self noteXInMeasure:measIdx at:at],
|
||||
kSystemY+[self noteYInSection:measure.fPropIdx
|
||||
withPitch:65
|
||||
withPitch:65 visual:0
|
||||
accidental:&accidental]);
|
||||
[self drawRest:note->fVisual & VLNote::kNoteHead at: pos];
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
// Copyright © 2006-2007 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLMIDIWriter.h"
|
||||
|
||||
@interface VLSheetView (Selection)
|
||||
|
||||
- (void)editSelection;
|
||||
|
@ -33,6 +35,8 @@
|
|||
|
||||
- (void)updateMenus;
|
||||
|
||||
- (void) willPlaySequence:(MusicSequence)music;
|
||||
|
||||
@end
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -9,9 +9,67 @@
|
|||
//
|
||||
|
||||
#import "VLSheetView.h"
|
||||
#import "VLSheetViewNotes.h"
|
||||
#import "VLSheetViewSelection.h"
|
||||
#import "VLSheetViewNotes.h"
|
||||
#import "VLSheetViewChords.h"
|
||||
#import "VLSheetViewLyrics.h"
|
||||
#import "VLSheetWindow.h"
|
||||
#import "VLDocument.h"
|
||||
|
||||
@interface VLPlaybackEditable : VLEditable {
|
||||
VLSheetView * fView;
|
||||
size_t fStanza;
|
||||
size_t fNoteMeasure;
|
||||
VLFract fNoteAt;
|
||||
int fNotePitch;
|
||||
size_t fChordMeasure;
|
||||
VLFract fChordAt;
|
||||
}
|
||||
|
||||
- (VLPlaybackEditable *)initWithView:(VLSheetView *)view;
|
||||
- (void) userEvent:(VLMIDIUserEvent *)event;
|
||||
- (void) highlightCursor;
|
||||
|
||||
@end
|
||||
|
||||
@implementation VLPlaybackEditable
|
||||
|
||||
- (VLPlaybackEditable *)initWithView:(VLSheetView *)view
|
||||
{
|
||||
fView = view;
|
||||
fStanza = 1;
|
||||
fNoteMeasure = 0x80000000;
|
||||
fChordMeasure = 0x80000000;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) userEvent:(VLMIDIUserEvent *)event
|
||||
{
|
||||
if (event->fPitch) {
|
||||
fNotePitch = event->fPitch;
|
||||
fNoteMeasure = event->fMeasure;
|
||||
fNoteAt = event->fAt;
|
||||
[fView highlightTextInStanza:fStanza measure:fNoteMeasure at:fNoteAt one:YES];
|
||||
} else {
|
||||
fChordMeasure = event->fMeasure;
|
||||
fChordAt = event->fAt;
|
||||
}
|
||||
[fView scrollMeasureToVisible:event->fMeasure];
|
||||
[fView setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void) highlightCursor
|
||||
{
|
||||
if (fNoteMeasure != 0x80000000)
|
||||
[fView drawNoteCursor:fNotePitch inMeasure:fNoteMeasure at:fNoteAt];
|
||||
if (fChordMeasure != 0x80000000)
|
||||
[fView highlightChordInMeasure:fChordMeasure at:fChordAt];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface NSMenuItem (VLSetStateToOff)
|
||||
- (void) VLSetStateToOff;
|
||||
@end
|
||||
|
@ -30,6 +88,16 @@
|
|||
//
|
||||
static VLSong sPasteboard;
|
||||
|
||||
extern "C" void
|
||||
VLSequenceCallback(
|
||||
void * inClientData,
|
||||
MusicSequence inSequence, MusicTrack inTrack,
|
||||
MusicTimeStamp inEventTime, const MusicEventUserData *inEventData,
|
||||
MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat)
|
||||
{
|
||||
[(id)inClientData userEvent:(VLMIDIUserEvent *)inEventData];
|
||||
}
|
||||
|
||||
@implementation VLSheetView (Selection)
|
||||
|
||||
- (void)editSelection
|
||||
|
@ -442,4 +510,12 @@ inline int TimeTag(const VLProperties & prop)
|
|||
[self updateGrooveMenu];
|
||||
}
|
||||
|
||||
- (void) willPlaySequence:(MusicSequence)music
|
||||
{
|
||||
VLEditable * e =
|
||||
[[VLPlaybackEditable alloc] initWithView:self];
|
||||
[self setEditTarget:e];
|
||||
MusicSequenceSetUserCallback(music, VLSequenceCallback, e);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2005-2007 Matthias Neeracher
|
||||
// Copyright © 2005-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@interface VLEditable : NSObject
|
||||
{
|
||||
|
@ -30,6 +31,10 @@
|
|||
IBOutlet id logToolItem;
|
||||
IBOutlet id playToolItem;
|
||||
IBOutlet id stopToolItem;
|
||||
IBOutlet id fwdToolItem;
|
||||
IBOutlet id bckToolItem;
|
||||
IBOutlet id tobegToolItem;
|
||||
IBOutlet id toendToolItem;
|
||||
IBOutlet id zoomInToolItem;
|
||||
IBOutlet id zoomOutToolItem;
|
||||
IBOutlet id progressToolItem;
|
||||
|
@ -46,5 +51,6 @@
|
|||
- (void) setEditTarget:(VLEditable *)editable;
|
||||
- (void) startAnimation;
|
||||
- (void) stopAnimation;
|
||||
- (void) willPlaySequence:(MusicSequence)music;
|
||||
|
||||
@end
|
||||
|
|
|
@ -49,6 +49,10 @@ static NSString* sOutputToolbarItemIdentifier = @"Output Toolbar Item Identifie
|
|||
static NSString* sLogToolbarItemIdentifier = @"Log Toolbar Item Identifier";
|
||||
static NSString* sPlayToolbarItemIdentifier = @"Play Toolbar Item Identifier";
|
||||
static NSString* sStopToolbarItemIdentifier = @"Stop Toolbar Item Identifier";
|
||||
static NSString* sFwdToolbarItemIdentifier = @"Fwd Toolbar Item Identifier";
|
||||
static NSString* sBckToolbarItemIdentifier = @"Rew Toolbar Item Identifier";
|
||||
static NSString* sToBegToolbarItemIdentifier = @"Begin Toolbar Item Identifier";
|
||||
static NSString* sToEndToolbarItemIdentifier = @"End Toolbar Item Identifier";
|
||||
static NSString* sZoomInToolbarItemIdentifier = @"Zoom In Toolbar Item Identifier";
|
||||
static NSString* sZoomOutToolbarItemIdentifier = @"Zoom Out Toolbar Item Identifier";
|
||||
static NSString* sProgressToolbarItemIdentifier = @"Progress Toolbar Item Identifier";
|
||||
|
@ -96,6 +100,14 @@ static NSString* sDisplayToolbarItemIdentifier = @"Display Toolbar Item Identifi
|
|||
prototype = playToolItem;
|
||||
else if ([itemIdent isEqual: sStopToolbarItemIdentifier])
|
||||
prototype = stopToolItem;
|
||||
else if ([itemIdent isEqual: sFwdToolbarItemIdentifier])
|
||||
prototype = fwdToolItem;
|
||||
else if ([itemIdent isEqual: sBckToolbarItemIdentifier])
|
||||
prototype = bckToolItem;
|
||||
else if ([itemIdent isEqual: sToBegToolbarItemIdentifier])
|
||||
prototype = tobegToolItem;
|
||||
else if ([itemIdent isEqual: sToEndToolbarItemIdentifier])
|
||||
prototype = toendToolItem;
|
||||
else if ([itemIdent isEqual: sZoomInToolbarItemIdentifier])
|
||||
prototype = zoomInToolItem;
|
||||
else if ([itemIdent isEqual: sZoomOutToolbarItemIdentifier])
|
||||
|
@ -112,6 +124,7 @@ static NSString* sDisplayToolbarItemIdentifier = @"Display Toolbar Item Identifi
|
|||
[toolbarItem setImage: [prototype image]];
|
||||
[toolbarItem setTarget: [prototype target]];
|
||||
[toolbarItem setAction: [prototype action]];
|
||||
[toolbarItem setTag: [prototype tag]];
|
||||
} else if ([itemIdent isEqual: sProgressToolbarItemIdentifier]) {
|
||||
toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdent] autorelease];
|
||||
|
||||
|
@ -126,8 +139,12 @@ static NSString* sDisplayToolbarItemIdentifier = @"Display Toolbar Item Identifi
|
|||
return [NSArray arrayWithObjects:
|
||||
sOutputToolbarItemIdentifier,
|
||||
NSToolbarSeparatorItemIdentifier,
|
||||
sToBegToolbarItemIdentifier,
|
||||
sBckToolbarItemIdentifier,
|
||||
sPlayToolbarItemIdentifier,
|
||||
sStopToolbarItemIdentifier,
|
||||
sFwdToolbarItemIdentifier,
|
||||
sToEndToolbarItemIdentifier,
|
||||
NSToolbarSeparatorItemIdentifier,
|
||||
sZoomInToolbarItemIdentifier,
|
||||
sZoomOutToolbarItemIdentifier,
|
||||
|
@ -140,8 +157,12 @@ static NSString* sDisplayToolbarItemIdentifier = @"Display Toolbar Item Identifi
|
|||
|
||||
- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar {
|
||||
return [NSArray arrayWithObjects:
|
||||
sToBegToolbarItemIdentifier,
|
||||
sBckToolbarItemIdentifier,
|
||||
sPlayToolbarItemIdentifier,
|
||||
sStopToolbarItemIdentifier,
|
||||
sFwdToolbarItemIdentifier,
|
||||
sToEndToolbarItemIdentifier,
|
||||
sZoomInToolbarItemIdentifier,
|
||||
sZoomOutToolbarItemIdentifier,
|
||||
sOutputToolbarItemIdentifier,
|
||||
|
@ -179,4 +200,9 @@ static NSString* sDisplayToolbarItemIdentifier = @"Display Toolbar Item Identifi
|
|||
[sheetView mouseMoved:event];
|
||||
}
|
||||
|
||||
- (void) willPlaySequence:(MusicSequence)music
|
||||
{
|
||||
[sheetView willPlaySequence:music];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "VLSoundOut.h"
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#include "CAAudioFileFormats.h"
|
||||
#include "AUOutputBL.h"
|
||||
|
@ -27,9 +26,11 @@ public:
|
|||
|
||||
virtual void PlayNote(const VLNote & note);
|
||||
virtual void PlayChord(const VLChord & chord);
|
||||
virtual void PlayFile(CFDataRef file);
|
||||
virtual void PlaySequence(MusicSequence music);
|
||||
virtual void Stop();
|
||||
virtual bool Playing();
|
||||
virtual void SetPlayRate(float rate);
|
||||
virtual void SetTime(MusicTimeStamp time);
|
||||
|
||||
virtual ~VLAUSoundOut();
|
||||
protected:
|
||||
|
@ -37,14 +38,15 @@ protected:
|
|||
|
||||
void InitSoundOutput(bool fileOutput);
|
||||
virtual void SetupOutput(AUNode outputNode);
|
||||
virtual void PlaySequence(MusicSequence music);
|
||||
MusicTimeStamp SequenceLength(MusicSequence music);
|
||||
|
||||
AUGraph fGraph;
|
||||
MusicPlayer fPlayer;
|
||||
private:
|
||||
MusicSequence fMusic;
|
||||
MusicTimeStamp fMusicLength;
|
||||
bool fRunning;
|
||||
bool fForward;
|
||||
|
||||
void Play(const int8_t * note, size_t numNotes = 1);
|
||||
};
|
||||
|
@ -95,12 +97,22 @@ VLSoundOut * VLSoundOut::FileWriter(CFURLRef file, OSType dataFormat)
|
|||
return new VLAUFileSoundOut(file, dataFormat);
|
||||
}
|
||||
|
||||
void VLSoundOut::PlayFile(CFDataRef file)
|
||||
{
|
||||
MusicSequence music;
|
||||
|
||||
NewMusicSequence(&music);
|
||||
MusicSequenceLoadSMFDataWithFlags(music, file,
|
||||
kMusicSequenceLoadSMF_ChannelsToTracks);
|
||||
PlaySequence(music);
|
||||
}
|
||||
|
||||
VLSoundOut::~VLSoundOut()
|
||||
{
|
||||
}
|
||||
|
||||
VLAUSoundOut::VLAUSoundOut()
|
||||
: fRunning(false), fMusic(0)
|
||||
: fMusic(0), fRunning(false), fForward(true)
|
||||
{
|
||||
InitSoundOutput(false);
|
||||
}
|
||||
|
@ -179,7 +191,8 @@ void VLAUSoundOut::PlaySequence(MusicSequence music)
|
|||
{
|
||||
Stop();
|
||||
|
||||
fMusic = music;
|
||||
fMusic = music;
|
||||
fMusicLength = SequenceLength(music);
|
||||
|
||||
R(MusicSequenceSetAUGraph(fMusic, fGraph));
|
||||
R(MusicPlayerSetSequence(fPlayer, fMusic));
|
||||
|
@ -188,6 +201,25 @@ void VLAUSoundOut::PlaySequence(MusicSequence music)
|
|||
fRunning = true;
|
||||
}
|
||||
|
||||
void VLAUSoundOut::SetPlayRate(float rate)
|
||||
{
|
||||
if ((rate < 0) != fForward) {
|
||||
fForward = !fForward;
|
||||
|
||||
MusicTimeStamp rightNow;
|
||||
MusicPlayerGetTime(fPlayer, &rightNow);
|
||||
MusicSequenceReverse(fMusic);
|
||||
MusicPlayerSetTime(fPlayer, fMusicLength - rightNow);
|
||||
}
|
||||
MusicPlayerSetPlayRateScalar(fPlayer, fabsf(rate));
|
||||
}
|
||||
|
||||
void VLAUSoundOut::SetTime(MusicTimeStamp time)
|
||||
{
|
||||
SetPlayRate(1.0f);
|
||||
MusicPlayerSetTime(fPlayer, time);
|
||||
}
|
||||
|
||||
void VLAUSoundOut::Stop()
|
||||
{
|
||||
MusicPlayerStop(fPlayer);
|
||||
|
@ -240,16 +272,6 @@ void VLAUSoundOut::Play(const int8_t * note, size_t numNotes)
|
|||
PlaySequence(music);
|
||||
}
|
||||
|
||||
void VLAUSoundOut::PlayFile(CFDataRef file)
|
||||
{
|
||||
MusicSequence music;
|
||||
|
||||
NewMusicSequence(&music);
|
||||
MusicSequenceLoadSMFDataWithFlags(music, file,
|
||||
kMusicSequenceLoadSMF_ChannelsToTracks);
|
||||
PlaySequence(music);
|
||||
}
|
||||
|
||||
MusicTimeStamp VLAUSoundOut::SequenceLength(MusicSequence music)
|
||||
{
|
||||
UInt32 ntracks;
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2005-2007 Matthias Neeracher
|
||||
// Copyright © 2005-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#include "VLModel.h"
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
class VLSoundEvent {
|
||||
protected:
|
||||
|
@ -36,9 +37,12 @@ public:
|
|||
|
||||
virtual void PlayNote(const VLNote & note) = 0;
|
||||
virtual void PlayChord(const VLChord & chord) = 0;
|
||||
virtual void PlayFile(CFDataRef file) = 0;
|
||||
void PlayFile(CFDataRef file);
|
||||
virtual void PlaySequence(MusicSequence music) = 0;
|
||||
virtual void Stop() = 0;
|
||||
virtual bool Playing() = 0;
|
||||
virtual void SetPlayRate(float rate) = 0;
|
||||
virtual void SetTime(MusicTimeStamp time) = 0;
|
||||
|
||||
virtual ~VLSoundOut();
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// (MN) Matthias Neeracher
|
||||
//
|
||||
// Copyright © 2006-2007 Matthias Neeracher
|
||||
// Copyright © 2006-2008 Matthias Neeracher
|
||||
//
|
||||
|
||||
#import "VLXMLDocument.h"
|
||||
|
|
3
Tools/lameWrapper
Executable file
3
Tools/lameWrapper
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
exec lame $*
|
|
@ -1,8 +1,7 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
export PATH=`dirname $1`:$PATH
|
||||
echo PATH=$PATH
|
||||
$*
|
||||
exec $*
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
95009B830B0EDCD800EB33A4 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95009B820B0EDCD800EB33A4 /* CoreFoundation.framework */; };
|
||||
95049CF30BDC32EB0015EE6E /* installLilypond.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049CF20BDC32CD0015EE6E /* installLilypond.scpt */; };
|
||||
95049D020BDC436A0015EE6E /* installPython.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 95049D010BDC43510015EE6E /* installPython.scpt */; };
|
||||
950795E10B4A34D9008911A6 /* stop.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 950795E00B4A34D9008911A6 /* stop.tiff */; };
|
||||
95140E3C0C944F7F00966576 /* VLLilypondType.reader in Copy Filters */ = {isa = PBXBuildFile; fileRef = 95140E3B0C944F7F00966576 /* VLLilypondType.reader */; };
|
||||
9524DAFB0BE569C50002AC03 /* Help in Resources */ = {isa = PBXBuildFile; fileRef = 9524DAF70BE569C50002AC03 /* Help */; };
|
||||
9524DB390BE5CA070002AC03 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9524DB380BE5CA070002AC03 /* Carbon.framework */; };
|
||||
|
@ -42,6 +41,9 @@
|
|||
952CBBB6095FD37300434E43 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
||||
952DCD78096BBB11001C2316 /* VLSheetViewChords.mm in Sources */ = {isa = PBXBuildFile; fileRef = 952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */; };
|
||||
9530A7020BD9E16700635FEC /* display.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 9530A7010BD9E16700635FEC /* display.tiff */; };
|
||||
9531F3510DE2B4CD004F78C2 /* VLAIFFDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9531F34E0DE2B4CD004F78C2 /* VLAIFFDocument.mm */; };
|
||||
9531F3520DE2B4CD004F78C2 /* VLMP3Document.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9531F3500DE2B4CD004F78C2 /* VLMP3Document.mm */; };
|
||||
9531F3670DE2B872004F78C2 /* lameWrapper in Copy Tools */ = {isa = PBXBuildFile; fileRef = 9531F3660DE2B872004F78C2 /* lameWrapper */; };
|
||||
953722670AE9F0E100B6E483 /* VLLilypondDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */; };
|
||||
9545C5C30C092F4600251547 /* VLMMAWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9545C5C10C092F4600251547 /* VLMMAWriter.cpp */; };
|
||||
95498DBD0AE3812F006B5F81 /* VLSoundSched.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95498DBC0AE3812F006B5F81 /* VLSoundSched.mm */; };
|
||||
|
@ -65,6 +67,14 @@
|
|||
959408AD096922EA007CCCF8 /* TVLEdit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959408AC096922EA007CCCF8 /* TVLEdit.cpp */; };
|
||||
959408AE096922F7007CCCF8 /* VLModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955E58E4095658AB0045FDA5 /* VLModel.cpp */; };
|
||||
9599ED9D0B731CC500A6A2F7 /* VLGrooveController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9599ED9B0B731CC500A6A2F7 /* VLGrooveController.mm */; };
|
||||
959A3A130DE64BA300EF207B /* play.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A110DE64BA300EF207B /* play.icns */; };
|
||||
959A3A140DE64BA300EF207B /* stop.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A120DE64BA300EF207B /* stop.icns */; };
|
||||
959A3A260DE78BCD00EF207B /* bck.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A220DE78BCD00EF207B /* bck.icns */; };
|
||||
959A3A270DE78BCD00EF207B /* fwd.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A230DE78BCD00EF207B /* fwd.icns */; };
|
||||
959A3A280DE78BCD00EF207B /* tobeg.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A240DE78BCD00EF207B /* tobeg.icns */; };
|
||||
959A3A290DE78BCD00EF207B /* toend.icns in Resources */ = {isa = PBXBuildFile; fileRef = 959A3A250DE78BCD00EF207B /* toend.icns */; };
|
||||
959A3A6E0DE8CB5B00EF207B /* VLMIDIWriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959A3A6C0DE8CB5B00EF207B /* VLMIDIWriter.cpp */; };
|
||||
959B77C20DE3139F004432E0 /* installLame.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 958139C20DE2FBE4003C00B4 /* installLame.scpt */; };
|
||||
95A1C37C0AF1D4370076597D /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 95A1C37B0AF1D4370076597D /* Quartz.framework */; };
|
||||
95A1C3860AF2ACE20076597D /* VLSheetWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */; };
|
||||
95A55C540BD5E5770068A203 /* VLPDFDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95A55C530BD5E5770068A203 /* VLPDFDocument.mm */; };
|
||||
|
@ -99,7 +109,6 @@
|
|||
95FC66C40AF0A4D4003D9C11 /* music.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66BD0AF0A4D4003D9C11 /* music.tiff */; };
|
||||
95FC66C50AF0A4D5003D9C11 /* nextpage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66BE0AF0A4D4003D9C11 /* nextpage.tiff */; };
|
||||
95FC66C60AF0A4D5003D9C11 /* prevpage.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66BF0AF0A4D4003D9C11 /* prevpage.tiff */; };
|
||||
95FC66C70AF0A4D5003D9C11 /* run.icns in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66C00AF0A4D4003D9C11 /* run.icns */; };
|
||||
95FC66C80AF0A4D5003D9C11 /* zoomin.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66C10AF0A4D4003D9C11 /* zoomin.tiff */; };
|
||||
95FC66C90AF0A4D5003D9C11 /* zoomout.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 95FC66C20AF0A4D4003D9C11 /* zoomout.tiff */; };
|
||||
95FC66CE0AF0A591003D9C11 /* VLPDFView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95FC66CC0AF0A591003D9C11 /* VLPDFView.mm */; };
|
||||
|
@ -125,6 +134,7 @@
|
|||
dstPath = bin;
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
9531F3670DE2B872004F78C2 /* lameWrapper in Copy Tools */,
|
||||
95D0C2FC0B785D020061080E /* rebuildGrooves in Copy Tools */,
|
||||
95C462830B045CB700649F92 /* lilyWrapper in Copy Tools */,
|
||||
95C462000B04472E00649F92 /* mmaWrapper in Copy Tools */,
|
||||
|
@ -184,7 +194,6 @@
|
|||
95009B820B0EDCD800EB33A4 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
|
||||
95049CF20BDC32CD0015EE6E /* installLilypond.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installLilypond.scpt; path = Resources/installLilypond.scpt; sourceTree = "<group>"; };
|
||||
95049D010BDC43510015EE6E /* installPython.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = installPython.scpt; path = Resources/installPython.scpt; sourceTree = "<group>"; };
|
||||
950795E00B4A34D9008911A6 /* stop.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = stop.tiff; path = Resources/stop.tiff; sourceTree = "<group>"; };
|
||||
95140E3B0C944F7F00966576 /* VLLilypondType.reader */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = VLLilypondType.reader; sourceTree = "<group>"; };
|
||||
9524DAF70BE569C50002AC03 /* Help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Help; path = Resources/Help; sourceTree = "<group>"; };
|
||||
9524DB380BE5CA070002AC03 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
|
@ -198,6 +207,11 @@
|
|||
952DCD76096BBB11001C2316 /* VLSheetViewChords.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLSheetViewChords.h; path = Sources/VLSheetViewChords.h; sourceTree = "<group>"; };
|
||||
952DCD77096BBB11001C2316 /* VLSheetViewChords.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLSheetViewChords.mm; path = Sources/VLSheetViewChords.mm; sourceTree = "<group>"; };
|
||||
9530A7010BD9E16700635FEC /* display.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = display.tiff; path = Resources/display.tiff; sourceTree = "<group>"; };
|
||||
9531F34D0DE2B4CD004F78C2 /* VLAIFFDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLAIFFDocument.h; path = Sources/VLAIFFDocument.h; sourceTree = "<group>"; };
|
||||
9531F34E0DE2B4CD004F78C2 /* VLAIFFDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLAIFFDocument.mm; path = Sources/VLAIFFDocument.mm; sourceTree = "<group>"; };
|
||||
9531F34F0DE2B4CD004F78C2 /* VLMP3Document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLMP3Document.h; path = Sources/VLMP3Document.h; sourceTree = "<group>"; };
|
||||
9531F3500DE2B4CD004F78C2 /* VLMP3Document.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLMP3Document.mm; path = Sources/VLMP3Document.mm; sourceTree = "<group>"; };
|
||||
9531F3660DE2B872004F78C2 /* lameWrapper */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = lameWrapper; path = Tools/lameWrapper; sourceTree = "<group>"; };
|
||||
953722650AE9F0E100B6E483 /* VLLilypondDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLLilypondDocument.h; path = Sources/VLLilypondDocument.h; sourceTree = "<group>"; };
|
||||
953722660AE9F0E100B6E483 /* VLLilypondDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLLilypondDocument.mm; path = Sources/VLLilypondDocument.mm; sourceTree = "<group>"; };
|
||||
9545C5C10C092F4600251547 /* VLMMAWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = VLMMAWriter.cpp; path = Sources/VLMMAWriter.cpp; sourceTree = "<group>"; };
|
||||
|
@ -222,6 +236,7 @@
|
|||
95784D860BFAD795009ABEA4 /* VLMirrorWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLMirrorWindow.mm; path = Sources/VLMirrorWindow.mm; sourceTree = "<group>"; };
|
||||
95795CE40C88B25D00E4A21F /* vl.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = vl.rb; sourceTree = "<group>"; };
|
||||
95795CE50C88B25D00E4A21F /* VLMusicXMLType.reader */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = VLMusicXMLType.reader; sourceTree = "<group>"; };
|
||||
958139C20DE2FBE4003C00B4 /* installLame.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = installLame.scpt; path = Resources/installLame.scpt; sourceTree = "<group>"; };
|
||||
9588363A0C6F9C7D004B4162 /* VLPListDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLPListDocument.h; path = Sources/VLPListDocument.h; sourceTree = "<group>"; };
|
||||
9588363B0C6F9C7D004B4162 /* VLPListDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLPListDocument.mm; path = Sources/VLPListDocument.mm; sourceTree = "<group>"; };
|
||||
9588365A0C6FABBA004B4162 /* VLDebugFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLDebugFlags.cpp; path = Sources/VLDebugFlags.cpp; sourceTree = "<group>"; };
|
||||
|
@ -232,6 +247,14 @@
|
|||
959408AC096922EA007CCCF8 /* TVLEdit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = TVLEdit.cpp; path = Tests/TVLEdit.cpp; sourceTree = "<group>"; };
|
||||
9599ED9A0B731CC500A6A2F7 /* VLGrooveController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLGrooveController.h; path = Sources/VLGrooveController.h; sourceTree = "<group>"; };
|
||||
9599ED9B0B731CC500A6A2F7 /* VLGrooveController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = VLGrooveController.mm; path = Sources/VLGrooveController.mm; sourceTree = "<group>"; };
|
||||
959A3A110DE64BA300EF207B /* play.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = play.icns; path = Resources/play.icns; sourceTree = "<group>"; };
|
||||
959A3A120DE64BA300EF207B /* stop.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = stop.icns; path = Resources/stop.icns; sourceTree = "<group>"; };
|
||||
959A3A220DE78BCD00EF207B /* bck.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = bck.icns; path = Resources/bck.icns; sourceTree = "<group>"; };
|
||||
959A3A230DE78BCD00EF207B /* fwd.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = fwd.icns; path = Resources/fwd.icns; sourceTree = "<group>"; };
|
||||
959A3A240DE78BCD00EF207B /* tobeg.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = tobeg.icns; path = Resources/tobeg.icns; sourceTree = "<group>"; };
|
||||
959A3A250DE78BCD00EF207B /* toend.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = toend.icns; path = Resources/toend.icns; sourceTree = "<group>"; };
|
||||
959A3A6C0DE8CB5B00EF207B /* VLMIDIWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VLMIDIWriter.cpp; path = Sources/VLMIDIWriter.cpp; sourceTree = "<group>"; };
|
||||
959A3A6D0DE8CB5B00EF207B /* VLMIDIWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLMIDIWriter.h; path = Sources/VLMIDIWriter.h; sourceTree = "<group>"; };
|
||||
95A1C37B0AF1D4370076597D /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = /System/Library/Frameworks/Quartz.framework; sourceTree = "<absolute>"; };
|
||||
95A1C3840AF2ACE20076597D /* VLSheetWindow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VLSheetWindow.h; path = Sources/VLSheetWindow.h; sourceTree = "<group>"; };
|
||||
95A1C3850AF2ACE20076597D /* VLSheetWindow.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLSheetWindow.mm; path = Sources/VLSheetWindow.mm; sourceTree = "<group>"; };
|
||||
|
@ -274,7 +297,6 @@
|
|||
95FC66BD0AF0A4D4003D9C11 /* music.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = music.tiff; path = Resources/music.tiff; sourceTree = "<group>"; };
|
||||
95FC66BE0AF0A4D4003D9C11 /* nextpage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = nextpage.tiff; path = Resources/nextpage.tiff; sourceTree = "<group>"; };
|
||||
95FC66BF0AF0A4D4003D9C11 /* prevpage.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = prevpage.tiff; path = Resources/prevpage.tiff; sourceTree = "<group>"; };
|
||||
95FC66C00AF0A4D4003D9C11 /* run.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = run.icns; path = Resources/run.icns; sourceTree = "<group>"; };
|
||||
95FC66C10AF0A4D4003D9C11 /* zoomin.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = zoomin.tiff; path = Resources/zoomin.tiff; sourceTree = "<group>"; };
|
||||
95FC66C20AF0A4D4003D9C11 /* zoomout.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = zoomout.tiff; path = Resources/zoomout.tiff; sourceTree = "<group>"; };
|
||||
95FC66CC0AF0A591003D9C11 /* VLPDFView.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; name = VLPDFView.mm; path = Sources/VLPDFView.mm; sourceTree = "<group>"; };
|
||||
|
@ -384,8 +406,14 @@
|
|||
2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
95D059780D1E6B0D00E28FAE /* VLLayout.cpp */,
|
||||
95D059790D1E6B0D00E28FAE /* VLLayout.h */,
|
||||
95D059780D1E6B0D00E28FAE /* VLLayout.cpp */,
|
||||
959A3A6D0DE8CB5B00EF207B /* VLMIDIWriter.h */,
|
||||
959A3A6C0DE8CB5B00EF207B /* VLMIDIWriter.cpp */,
|
||||
9531F34D0DE2B4CD004F78C2 /* VLAIFFDocument.h */,
|
||||
9531F34E0DE2B4CD004F78C2 /* VLAIFFDocument.mm */,
|
||||
9531F34F0DE2B4CD004F78C2 /* VLMP3Document.h */,
|
||||
9531F3500DE2B4CD004F78C2 /* VLMP3Document.mm */,
|
||||
9588365A0C6FABBA004B4162 /* VLDebugFlags.cpp */,
|
||||
9588365B0C6FABBA004B4162 /* VLDebugFlags.h */,
|
||||
9588363A0C6F9C7D004B4162 /* VLPListDocument.h */,
|
||||
|
@ -457,6 +485,10 @@
|
|||
2A37F4B8FDCFA73011CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
959A3A220DE78BCD00EF207B /* bck.icns */,
|
||||
959A3A230DE78BCD00EF207B /* fwd.icns */,
|
||||
959A3A240DE78BCD00EF207B /* tobeg.icns */,
|
||||
959A3A250DE78BCD00EF207B /* toend.icns */,
|
||||
9524DAF70BE569C50002AC03 /* Help */,
|
||||
95003B3F0D4B9A5D00C9849C /* MainMenu.xib */,
|
||||
95003B410D4B9A5D00C9849C /* VLDocument.xib */,
|
||||
|
@ -465,14 +497,15 @@
|
|||
95003B470D4B9A5D00C9849C /* VLMirrorWindow.xib */,
|
||||
95003B490D4B9A5D00C9849C /* VLPDFWindow.xib */,
|
||||
95049CF20BDC32CD0015EE6E /* installLilypond.scpt */,
|
||||
958139C20DE2FBE4003C00B4 /* installLame.scpt */,
|
||||
95049D010BDC43510015EE6E /* installPython.scpt */,
|
||||
95FC66BC0AF0A4D4003D9C11 /* console.icns */,
|
||||
9530A7010BD9E16700635FEC /* display.tiff */,
|
||||
959A3A110DE64BA300EF207B /* play.icns */,
|
||||
959A3A120DE64BA300EF207B /* stop.icns */,
|
||||
95FC66BD0AF0A4D4003D9C11 /* music.tiff */,
|
||||
950795E00B4A34D9008911A6 /* stop.tiff */,
|
||||
95FC66BE0AF0A4D4003D9C11 /* nextpage.tiff */,
|
||||
95FC66BF0AF0A4D4003D9C11 /* prevpage.tiff */,
|
||||
95FC66C00AF0A4D4003D9C11 /* run.icns */,
|
||||
95FC66C10AF0A4D4003D9C11 /* zoomin.tiff */,
|
||||
95FC66C20AF0A4D4003D9C11 /* zoomout.tiff */,
|
||||
95E04DCA0AEB4D9B006F30A0 /* Templates */,
|
||||
|
@ -529,6 +562,7 @@
|
|||
95C4627A0B045C8E00649F92 /* lilyWrapper */,
|
||||
95C461FF0B04472900649F92 /* mmaWrapper */,
|
||||
95C461D50B04406300649F92 /* mma.py */,
|
||||
9531F3660DE2B872004F78C2 /* lameWrapper */,
|
||||
95D0C2FB0B785D020061080E /* rebuildGrooves */,
|
||||
);
|
||||
name = Tools;
|
||||
|
@ -673,6 +707,7 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
959B77C20DE3139F004432E0 /* installLame.scpt in Resources */,
|
||||
95049D020BDC436A0015EE6E /* installPython.scpt in Resources */,
|
||||
95049CF30BDC32EB0015EE6E /* installLilypond.scpt in Resources */,
|
||||
8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */,
|
||||
|
@ -685,10 +720,8 @@
|
|||
95FC66C40AF0A4D4003D9C11 /* music.tiff in Resources */,
|
||||
95FC66C50AF0A4D5003D9C11 /* nextpage.tiff in Resources */,
|
||||
95FC66C60AF0A4D5003D9C11 /* prevpage.tiff in Resources */,
|
||||
95FC66C70AF0A4D5003D9C11 /* run.icns in Resources */,
|
||||
95FC66C80AF0A4D5003D9C11 /* zoomin.tiff in Resources */,
|
||||
95FC66C90AF0A4D5003D9C11 /* zoomout.tiff in Resources */,
|
||||
950795E10B4A34D9008911A6 /* stop.tiff in Resources */,
|
||||
9530A7020BD9E16700635FEC /* display.tiff in Resources */,
|
||||
9524DAFB0BE569C50002AC03 /* Help in Resources */,
|
||||
95003B4B0D4B9A5D00C9849C /* MainMenu.xib in Resources */,
|
||||
|
@ -697,6 +730,12 @@
|
|||
95003B4E0D4B9A5D00C9849C /* VLLogWindow.xib in Resources */,
|
||||
95003B4F0D4B9A5D00C9849C /* VLMirrorWindow.xib in Resources */,
|
||||
95003B500D4B9A5D00C9849C /* VLPDFWindow.xib in Resources */,
|
||||
959A3A130DE64BA300EF207B /* play.icns in Resources */,
|
||||
959A3A140DE64BA300EF207B /* stop.icns in Resources */,
|
||||
959A3A260DE78BCD00EF207B /* bck.icns in Resources */,
|
||||
959A3A270DE78BCD00EF207B /* fwd.icns in Resources */,
|
||||
959A3A280DE78BCD00EF207B /* tobeg.icns in Resources */,
|
||||
959A3A290DE78BCD00EF207B /* toend.icns in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -756,6 +795,9 @@
|
|||
9588363C0C6F9C7D004B4162 /* VLPListDocument.mm in Sources */,
|
||||
9588365C0C6FABBA004B4162 /* VLDebugFlags.cpp in Sources */,
|
||||
95D0597A0D1E6B0D00E28FAE /* VLLayout.cpp in Sources */,
|
||||
9531F3510DE2B4CD004F78C2 /* VLAIFFDocument.mm in Sources */,
|
||||
9531F3520DE2B4CD004F78C2 /* VLMP3Document.mm in Sources */,
|
||||
959A3A6E0DE8CB5B00EF207B /* VLMIDIWriter.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user