Skip to content

Commit

Permalink
fix: normalizeNote, pitchClassesToPianoChordNotes
Browse files Browse the repository at this point in the history
  • Loading branch information
Seanitzel committed Apr 20, 2023
1 parent d327752 commit aeb259b
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
11 changes: 7 additions & 4 deletions src/utilities/MusicFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PITCH_CLASS_LETTERS } from '../Constants.js';
import { Note, PitchClass, Scale } from '../types.js';
import { rearrangeArray } from './GeneralFunctions.js';
import { enharmonicPitchClass, getPitchClassIndex } from './PureMusicUtils.js';
import { enharmonicPitchClass, getPitchClassIndex, normalizePitchClass } from './PureMusicUtils.js';

/**
* Returns an array of notes with a specific octave.
Expand Down Expand Up @@ -30,9 +30,12 @@ export function pitchClassesToPianoChordNotes(pitchClasses: Array<PitchClass>, o

return pitchClasses.map((pitchClass, i) => {
if(i !== 0) {
const pcIndex = getPitchClassIndex(pitchClass);
const prevPcIndex = getPitchClassIndex(pitchClasses[i - 1]);
if((i - 1) >= 0 && pcIndex < prevPcIndex) {
const pcIndex = getPitchClassIndex(normalizePitchClass(pitchClass));
const prevPcIndex = getPitchClassIndex(normalizePitchClass(pitchClasses[i - 1]));
// Checking if the octave needs to be incremented:
// We can know it definitely needs to be incremented if the current pitch class is C.
// Otherwise, we need to check if the current pitch class pitch class index is smaller than the previous one, as that would indicate that weve passed the B pitch class.
if((pcIndex < prevPcIndex && pitchClass[0] !== 'B') || pitchClass[0] === 'C') {
currentOctave++;
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/utilities/PureMusicUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,14 @@ export function normalizePitchClass(pc: PitchClass): PitchClass {

export function normalizeNote(note: Note): Note {
const { pitchClass, octave } = noteToObject(note);
return `${normalizePitchClass(pitchClass)}${octave}` as Note;
const normalizedPitchClass = normalizePitchClass(pitchClass);
let octaveDifference = 0;
if(pitchClass[0] === 'B' && pitchClass.includes('#' || 'x')) {
octaveDifference = 1;
} else if(pitchClass[0] === 'C' && pitchClass.includes('b')) {
octaveDifference = -1;
}
return `${normalizedPitchClass}${octave + octaveDifference}` as Note;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions test/utilities/music-functions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ describe('Music addon functions', () => {

expect(pitchClassesToPianoChordNotes(bigChord, 3)).to.eql(stub);
});

it('with a scale', () => {
const bigChord = spellScale(intervalsToNotes('E', [0, 3, 4, 6, 8, 9, 11]));
const stub = ['E3', 'Fx3', 'G#3', 'A#3', 'B#3', 'C#4', 'D#4'];

expect(pitchClassesToPianoChordNotes(bigChord, 3)).to.eql(stub);
});
});

it('should invert chords when called with inversion value', () => {
Expand Down
12 changes: 11 additions & 1 deletion test/utilities/pure-music-utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
enharmonicPitchClass, getNotesInterval, getPatternFromNotes, getPatternFromPitchClasses, isPitchClass, isNote, normalizePitchClass, toFlat,
enharmonicPitchClass, getNotesInterval, getPatternFromNotes, getPatternFromPitchClasses, isPitchClass, isNote, normalizePitchClass, toFlat, normalizeNote,
} from '../../lib/index.js';

describe('#PureMusicUtils', () => {
Expand Down Expand Up @@ -101,6 +101,16 @@ describe('#PureMusicUtils', () => {
});
});

describe('#normalizeNote', () => {
it('should normalize a note', () => {
expect(normalizeNote('C#3')).to.equal('C#3');
expect(normalizeNote('Gx3')).to.equal('A3');
expect(normalizeNote('B#3')).to.equal('C4');
expect(normalizeNote('Ab3')).to.equal('Ab3');
expect(normalizeNote('Bbb4')).to.equal('A4');
expect(normalizeNote('Cbb3')).to.equal('Bb2');
});
});
describe('#toFlat', () => {
it('should turn sharp pitch classes flat', () => {
expect(toFlat('C#')).to.equal('Db');
Expand Down

0 comments on commit aeb259b

Please sign in to comment.