mirror of
https://github.com/microtherion/VocalEasel.git
synced 2024-12-22 19:23:59 +00:00
Smart groove preview
This commit is contained in:
parent
fc1e8277c7
commit
f9f2946bb8
|
@ -21,7 +21,8 @@ enum {
|
||||||
kVLPlayAccompaniment = 1,
|
kVLPlayAccompaniment = 1,
|
||||||
kVLPlayMelody = 2,
|
kVLPlayMelody = 2,
|
||||||
kVLPlayMetronome = 4,
|
kVLPlayMetronome = 4,
|
||||||
kVLPlayCountIn = 8
|
kVLPlayCountIn = 8,
|
||||||
|
kVLPlayGroovePreview = 32768
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface VLDocument : NSDocument
|
@interface VLDocument : NSDocument
|
||||||
|
@ -46,6 +47,7 @@ enum {
|
||||||
VLPDFWindow * pdfWin;
|
VLPDFWindow * pdfWin;
|
||||||
VLKeyValueUndo* undo;
|
VLKeyValueUndo* undo;
|
||||||
PDFDocument * printDoc;
|
PDFDocument * printDoc;
|
||||||
|
NSRange previewRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (VLSong *) song;
|
- (VLSong *) song;
|
||||||
|
@ -59,6 +61,7 @@ enum {
|
||||||
- (void) setTimeNum:(int)num denom:(int)denom inSections:(NSRange)sections;
|
- (void) setTimeNum:(int)num denom:(int)denom inSections:(NSRange)sections;
|
||||||
- (void) setDivisions:(int)divisions inSections:(NSRange)sections;
|
- (void) setDivisions:(int)divisions inSections:(NSRange)sections;
|
||||||
- (void) setGroove:(NSString *)groove inSections:(NSRange)sections;
|
- (void) setGroove:(NSString *)groove inSections:(NSRange)sections;
|
||||||
|
- (void) playWithGroove:(NSString *)groove inSections:(NSRange)sections;
|
||||||
|
|
||||||
- (void) setRepeatVolta:(int)repeatVolta;
|
- (void) setRepeatVolta:(int)repeatVolta;
|
||||||
|
|
||||||
|
@ -81,7 +84,6 @@ enum {
|
||||||
- (void) didChangeSong;
|
- (void) didChangeSong;
|
||||||
- (void) addObserver:(id)observer;
|
- (void) addObserver:(id)observer;
|
||||||
- (VLLogWindow *)logWin;
|
- (VLLogWindow *)logWin;
|
||||||
- (void) playWithGroove:(NSString *)groove;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -448,14 +448,17 @@
|
||||||
[self fileURLWithExtension:@"mid"]]));
|
[self fileURLWithExtension:@"mid"]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) playWithGroove:(NSString *)groove
|
- (void) playWithGroove:(NSString *)groove inSections:(NSRange)sections
|
||||||
{
|
{
|
||||||
NSString * savedGroove = songGroove;
|
NSString * savedGroove = songGroove;
|
||||||
songGroove = groove;
|
|
||||||
[validTmpFiles removeObjectForKey:@"mma"];
|
[validTmpFiles removeObjectForKey:@"mma"];
|
||||||
[validTmpFiles removeObjectForKey:@"mid"];
|
[validTmpFiles removeObjectForKey:@"mid"];
|
||||||
|
songGroove = groove;
|
||||||
|
previewRange = sections;
|
||||||
|
playElements |= kVLPlayGroovePreview;
|
||||||
[self play:groove];
|
[self play:groove];
|
||||||
songGroove = savedGroove;
|
playElements &= ~kVLPlayGroovePreview;
|
||||||
|
songGroove = savedGroove;
|
||||||
[validTmpFiles removeObjectForKey:@"mma"];
|
[validTmpFiles removeObjectForKey:@"mma"];
|
||||||
[validTmpFiles removeObjectForKey:@"mid"];
|
[validTmpFiles removeObjectForKey:@"mid"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
NSDictionary * fSubStyles;
|
NSDictionary * fSubStyles;
|
||||||
NSArray * fSubStyleList;
|
NSArray * fSubStyleList;
|
||||||
NSPredicate * fSubStyleFilter;
|
NSPredicate * fSubStyleFilter;
|
||||||
|
VLSheetView * fView;
|
||||||
VLDocument * fDocument;
|
VLDocument * fDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
[[NSPredicate predicateWithFormat:
|
[[NSPredicate predicateWithFormat:
|
||||||
@"!(SELF matches[c] '.*(Intro|End)\\\\d*$')"]
|
@"!(SELF matches[c] '.*(Intro|End)\\\\d*$')"]
|
||||||
retain];
|
retain];
|
||||||
|
fView = view;
|
||||||
fDocument = [view document];
|
fDocument = [view document];
|
||||||
|
|
||||||
[NSApp beginSheet: [self window]
|
[NSApp beginSheet: [self window]
|
||||||
|
@ -43,7 +44,7 @@
|
||||||
- (IBAction) togglePlay:(id)sender
|
- (IBAction) togglePlay:(id)sender
|
||||||
{
|
{
|
||||||
if ([sender state])
|
if ([sender state])
|
||||||
[fDocument playWithGroove:[[fBrowser selectedCellInColumn:1] stringValue]];
|
[fView playWithGroove:[[fBrowser selectedCellInColumn:1] stringValue]];
|
||||||
else
|
else
|
||||||
[fDocument stop:sender];
|
[fDocument stop:sender];
|
||||||
}
|
}
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
{
|
{
|
||||||
[fDocument stop:self];
|
[fDocument stop:self];
|
||||||
if (returnCode == NSAlertFirstButtonReturn)
|
if (returnCode == NSAlertFirstButtonReturn)
|
||||||
[(VLSheetView *)contextInfo setGroove:[[fBrowser selectedCellInColumn:1] stringValue]];
|
[fView setGroove:[[fBrowser selectedCellInColumn:1] stringValue]];
|
||||||
|
|
||||||
[[self window] orderOut:self];
|
[[self window] orderOut:self];
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,37 +15,47 @@
|
||||||
|
|
||||||
- (NSData *)mmaDataWithError:(NSError **)outError
|
- (NSData *)mmaDataWithError:(NSError **)outError
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
NSBundle * bndl = [NSBundle mainBundle];
|
NSBundle * bndl = [NSBundle mainBundle];
|
||||||
VLMMAWriter writer;
|
VLMMAWriter writer(playElements & kVLPlayGroovePreview,
|
||||||
writer.Visit(*song);
|
previewRange.location,
|
||||||
const VLProperties & prop = song->fProperties.front();
|
previewRange.location+previewRange.length);
|
||||||
|
|
||||||
|
writer.Visit(*song);
|
||||||
std::string mmaFile = std::string("// Generated by VocalEasel ")
|
std::string mmaFile = std::string("// Generated by VocalEasel ")
|
||||||
+ (const char *)[[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]
|
+ (const char *)[[bndl objectForInfoDictionaryKey:@"CFBundleVersion"]
|
||||||
UTF8String]
|
UTF8String]
|
||||||
+ "\n\n"
|
+ "\n\n";
|
||||||
+ "Solo Voice AltoSax\n"
|
|
||||||
+ "Solo Volume fff\n";
|
|
||||||
sprintf(buf, "Tempo %d\n", [songTempo intValue]);
|
sprintf(buf, "Tempo %d\n", [songTempo intValue]);
|
||||||
mmaFile += buf;
|
mmaFile += buf;
|
||||||
if (playElements & kVLPlayCountIn)
|
if (playElements & kVLPlayGroovePreview) {
|
||||||
switch ([[self songTime] intValue]) {
|
//
|
||||||
case 0x404:
|
// Override all other flags
|
||||||
mmaFile += "Groove Metronome2-4\nz\nz\n";
|
//
|
||||||
break;
|
mmaFile += "Groove ";
|
||||||
case 0x304:
|
mmaFile += [songGroove UTF8String];
|
||||||
case 0x608:
|
mmaFile += "\nSolo Off\n";
|
||||||
mmaFile += "Groove Metronome3\nz\nz\n";
|
} else {
|
||||||
break;
|
if (playElements & kVLPlayCountIn)
|
||||||
default:
|
switch ([[self songTime] intValue]) {
|
||||||
// Can't handle these yet
|
case 0x404:
|
||||||
break;
|
mmaFile += "Groove Metronome2-4\nz\nz\n";
|
||||||
}
|
break;
|
||||||
if (!(playElements & kVLPlayAccompaniment))
|
case 0x304:
|
||||||
mmaFile += "AllTracks Off\nSolo On\n";
|
case 0x608:
|
||||||
if (!(playElements & kVLPlayMelody))
|
mmaFile += "Groove Metronome3\nz\nz\n";
|
||||||
mmaFile += "Solo Off\n";
|
break;
|
||||||
|
default:
|
||||||
|
// Can't handle these yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(playElements & kVLPlayAccompaniment))
|
||||||
|
mmaFile += "AllTracks Off\nSolo On\n";
|
||||||
|
if (playElements & kVLPlayMelody)
|
||||||
|
mmaFile += "Solo Voice AltoSax\nSolo Volume fff\n";
|
||||||
|
else
|
||||||
|
mmaFile += "Solo Off\n";
|
||||||
|
}
|
||||||
mmaFile += '\n'+writer.Measures();
|
mmaFile += '\n'+writer.Measures();
|
||||||
|
|
||||||
return [[NSString stringWithUTF8String:mmaFile.c_str()]
|
return [[NSString stringWithUTF8String:mmaFile.c_str()]
|
||||||
|
|
|
@ -24,6 +24,10 @@ void VLMMAWriter::Visit(VLSong & song)
|
||||||
|
|
||||||
void VLMMAWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
void VLMMAWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
||||||
{
|
{
|
||||||
|
if (fPreview)
|
||||||
|
if (meas.fPropIdx < fBeginSection || meas.fPropIdx >= fEndSection)
|
||||||
|
return; // Skip this measure
|
||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
if (p.fKey != fKey) {
|
if (p.fKey != fKey) {
|
||||||
|
@ -31,7 +35,7 @@ void VLMMAWriter::VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas)
|
||||||
sprintf(buf, "KeySig %d%c\n", labs(fKey), fKey>=0 ? '#' : '&');
|
sprintf(buf, "KeySig %d%c\n", labs(fKey), fKey>=0 ? '#' : '&');
|
||||||
fMeasures += buf;
|
fMeasures += buf;
|
||||||
}
|
}
|
||||||
if (p.fGroove != fGroove) {
|
if (!fPreview && p.fGroove != fGroove) {
|
||||||
fGroove = p.fGroove;
|
fGroove = p.fGroove;
|
||||||
fMeasures += "Groove " + fGroove + '\n';
|
fMeasures += "Groove " + fGroove + '\n';
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
class VLMMAWriter: public VLSongVisitor {
|
class VLMMAWriter: public VLSongVisitor {
|
||||||
public:
|
public:
|
||||||
VLMMAWriter() {}
|
VLMMAWriter(bool preview, int beginSection, int endSection)
|
||||||
|
: fPreview(preview), fBeginSection(beginSection), fEndSection(endSection)
|
||||||
|
{}
|
||||||
|
|
||||||
virtual void Visit(VLSong & song);
|
virtual void Visit(VLSong & song);
|
||||||
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas);
|
virtual void VisitMeasure(size_t m, VLProperties & p, VLMeasure & meas);
|
||||||
|
@ -24,6 +26,7 @@ private:
|
||||||
std::string fMeasures;
|
std::string fMeasures;
|
||||||
|
|
||||||
VLSong * fSong;
|
VLSong * fSong;
|
||||||
|
bool fPreview;
|
||||||
bool fUseSharps;
|
bool fUseSharps;
|
||||||
bool fTied;
|
bool fTied;
|
||||||
bool fInitial;
|
bool fInitial;
|
||||||
|
@ -32,6 +35,8 @@ private:
|
||||||
std::string fAccum;
|
std::string fAccum;
|
||||||
int fKey;
|
int fKey;
|
||||||
std::string fGroove;
|
std::string fGroove;
|
||||||
|
int fBeginSection;
|
||||||
|
int fEndSection;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
|
|
|
@ -128,7 +128,7 @@ enum VLRecalc {
|
||||||
- (VLRegion) findRegionForEvent:(NSEvent *) event;
|
- (VLRegion) findRegionForEvent:(NSEvent *) event;
|
||||||
|
|
||||||
- (void) setGroove:(NSString *)groove;
|
- (void) setGroove:(NSString *)groove;
|
||||||
- (void) setGrooveMenu:(NSString *)groove;
|
- (void) playWithGroove:(NSString *)groove;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -1054,6 +1054,11 @@ static int8_t sSharpAcc[] = {
|
||||||
[[self document] setGroove:groove inSections:[self sectionsInSelection]];
|
[[self document] setGroove:groove inSections:[self sectionsInSelection]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)playWithGroove:(NSString *)groove
|
||||||
|
{
|
||||||
|
[[self document] playWithGroove:groove inSections:[self sectionsInSelection]];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)editDisplayOptions:(id)sender
|
- (IBAction)editDisplayOptions:(id)sender
|
||||||
{
|
{
|
||||||
VLSheetWindow * wc = [[self window] windowController];
|
VLSheetWindow * wc = [[self window] windowController];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user