Transpose songs

This commit is contained in:
Matthias Neeracher 2006-10-14 10:09:42 +00:00
parent 9a6768e8f3
commit 1b61bcd41e
3 changed files with 68 additions and 1 deletions

View File

@ -541,3 +541,53 @@ void VLSong::DelNote(size_t measure, VLFraction at)
}
}
static void TransposePinned(int8_t & pitch, int semi)
{
if (pitch == VLNote::kNoPitch)
return;
int pitchInOctave = pitch % 12;
int octave = pitch-pitchInOctave;
pitchInOctave += semi;
if (pitchInOctave < 0)
pitch = octave+pitchInOctave+12;
else if (pitchInOctave > 11)
pitch = octave+pitchInOctave-12;
else
pitch = octave+pitchInOctave;
}
void VLSong::Transpose(int semi)
{
for (int pass=0; pass<2 && semi;) {
int8_t low = 127;
int8_t high = 0;
for (int measure=0; measure<fMeasures.size(); ++measure) {
VLNoteList::iterator i = fMeasures[measure].fMelody.begin();
VLNoteList::iterator e = fMeasures[measure].fMelody.end();
for (; i!=e; ++i) {
if (i->fPitch == VLNote::kNoPitch)
continue;
i->fPitch += semi;
low = std::min(low, i->fPitch);
high = std::max(high, i->fPitch);
}
}
if (low < VLNote::kMiddleC-6 && high < VLNote::kMiddleC+7)
semi += 12; // Transpose an Octave up
else if (low > VLNote::kMiddleC+7 && high > VLNote::kMiddleC+16)
semi -= 12; // Transpose an Octave down
else
break; // Looks like we're done
}
for (int measure=0; measure<fMeasures.size(); ++measure) {
VLChordList::iterator i = fMeasures[measure].fChords.begin();
VLChordList::iterator e = fMeasures[measure].fChords.end();
for (; i!=e; ++i) {
TransposePinned(i->fPitch, semi);
TransposePinned(i->fRootPitch, semi);
}
}
}

View File

@ -217,6 +217,7 @@ struct VLSong {
void AddNote(VLNote note, size_t measure, VLFraction at);
void DelChord(size_t measure, VLFraction at);
void DelNote(size_t measure, VLFraction at);
void Transpose(int semitones);
size_t CountMeasures() const { return fMeasures.size(); }
};

View File

@ -345,8 +345,24 @@ static float sFlatPos[] = {
- (IBAction) setKey:(id)sender
{
[[NSAlert alertWithMessageText:@"Transpose Song?"
defaultButton:@"Transpose"
alternateButton:@"Cancel"
otherButton:@"Change Key"
informativeTextWithFormat:
@"Do you want to transpose the song into the new key?"]
beginSheetModalForWindow:[self window]
modalDelegate:self didEndSelector:@selector(setKey:returnCode:contextInfo:)
contextInfo:sender];
}
- (void)setKey:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(id)sender
{
if (returnCode == NSAlertAlternateReturn)
return;
int key = [[sender selectedItem] tag];
[[self document] setKey: key transpose: YES];
[[self document] setKey:key transpose:returnCode==NSAlertDefaultReturn];
fNeedsRecalc = kRecalc;
[self setNeedsDisplay: YES];
}