Merge 1.1-dev

This commit is contained in:
Matthias Neeracher 2008-05-29 18:54:30 +00:00
parent be789acf06
commit 510bdc0413
51 changed files with 1980 additions and 2010 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build
*~

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -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'

View File

@ -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

View File

@ -7,6 +7,8 @@ class VL
TiedWithNext = 1
TiedWithPrev = 2
WantSharp = 0x20
WantFlat = 0x40
InChord = 4
Unison = 1<<0

View File

@ -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

Binary file not shown.

BIN
Resources/fwd.icns Normal file

Binary file not shown.

BIN
Resources/installLame.scpt Normal file

Binary file not shown.

Binary file not shown.

BIN
Resources/play.icns Normal file

Binary file not shown.

Binary file not shown.

BIN
Resources/stop.icns Normal file

Binary file not shown.

Binary file not shown.

BIN
Resources/tobeg.icns Normal file

Binary file not shown.

BIN
Resources/toend.icns Normal file

Binary file not shown.

18
Sources/VLAIFFDocument.h Normal file
View 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
View 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

View File

@ -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:

View File

@ -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]);

View File

@ -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;

View File

@ -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"];

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -9,6 +9,7 @@
//
#import "VLMIDIDocument.h"
#import "VLMIDIWriter.h"
@implementation VLDocument (MIDI)

69
Sources/VLMIDIWriter.cpp Normal file
View 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
View 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:

View File

@ -1,5 +1,5 @@
//
// File: VLMMAWriter.h
// File: VLMMAWriter.cpp
//
// Author(s):
//

18
Sources/VLMP3Document.h Normal file
View 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
View 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

View File

@ -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)

View File

@ -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);
};

View File

@ -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) {

View File

@ -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:

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -15,6 +15,7 @@
- (void) drawNotesForSystem:(int)system;
- (void) addNoteAtCursor;
- (void) startKeyboardCursor;
- (void) drawNoteCursor:(int)pitch inMeasure:(size_t)measure at:(VLFract)at;
@end

View File

@ -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];
}

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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();
};

View File

@ -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
View File

@ -0,0 +1,3 @@
#!/bin/bash -l
exec lame $*

View File

@ -1,8 +1,7 @@
#!/bin/bash -l
export PATH=`dirname $1`:$PATH
echo PATH=$PATH
$*
exec $*

View File

@ -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;
};