move tonleiter
This commit is contained in:
parent
d47fd0cf18
commit
70d6f3000a
2 changed files with 238 additions and 0 deletions
112
packages/tonal/test/tonleiter.test.mjs
Normal file
112
packages/tonal/test/tonleiter.test.mjs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
tonleiter.test.mjs - <short description TODO>
|
||||
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/tonal/test/tonleiter.test.mjs>
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import {
|
||||
Step,
|
||||
Note,
|
||||
transpose,
|
||||
pc2chroma,
|
||||
rotateChroma,
|
||||
chroma2pc,
|
||||
tokenizeChord,
|
||||
note2pc,
|
||||
note2oct,
|
||||
note2midi,
|
||||
midi2note,
|
||||
voiceBelow,
|
||||
} from '../tonleiter.mjs';
|
||||
|
||||
describe('tonleiter', () => {
|
||||
test('Step ', () => {
|
||||
expect(Step.tokenize('#11')).toEqual(['#', 11]);
|
||||
expect(Step.tokenize('b13')).toEqual(['b', 13]);
|
||||
expect(Step.tokenize('bb6')).toEqual(['bb', 6]);
|
||||
expect(Step.tokenize('b3')).toEqual(['b', 3]);
|
||||
expect(Step.tokenize('3')).toEqual(['', 3]);
|
||||
expect(Step.tokenize('10')).toEqual(['', 10]);
|
||||
// expect(Step.tokenize('asdasd')).toThrow();
|
||||
expect(Step.accidentals('b3')).toEqual(-1);
|
||||
expect(Step.accidentals('#11')).toEqual(1);
|
||||
});
|
||||
test('Note', () => {
|
||||
expect(Note.tokenize('C##')).toEqual(['C', '##']);
|
||||
expect(Note.tokenize('Bb')).toEqual(['B', 'b']);
|
||||
expect(Note.accidentals('C#')).toEqual(1);
|
||||
expect(Note.accidentals('C##')).toEqual(2);
|
||||
expect(Note.accidentals('Eb')).toEqual(-1);
|
||||
expect(Note.accidentals('Bbb')).toEqual(-2);
|
||||
});
|
||||
test('transpose', () => {
|
||||
expect(transpose('F#', '3')).toEqual('A#');
|
||||
expect(transpose('C', '3')).toEqual('E');
|
||||
expect(transpose('D', '3')).toEqual('F#');
|
||||
expect(transpose('E', '3')).toEqual('G#');
|
||||
expect(transpose('Eb', '3')).toEqual('G');
|
||||
expect(transpose('Ebb', '3')).toEqual('Gb');
|
||||
});
|
||||
test('pc2chroma', () => {
|
||||
expect(pc2chroma('C')).toBe(0);
|
||||
expect(pc2chroma('C#')).toBe(1);
|
||||
expect(pc2chroma('C##')).toBe(2);
|
||||
expect(pc2chroma('D')).toBe(2);
|
||||
expect(pc2chroma('Db')).toBe(1);
|
||||
expect(pc2chroma('Dbb')).toBe(0);
|
||||
});
|
||||
test('rotateChroma', () => {
|
||||
expect(rotateChroma(0, 1)).toBe(1);
|
||||
expect(rotateChroma(0, -1)).toBe(-1); // this is wrong...
|
||||
//expect(rotateChroma(0, -1)).toBe(11); // <-- TODO
|
||||
expect(rotateChroma(11, 1)).toBe(0);
|
||||
expect(rotateChroma(11, 13)).toBe(0);
|
||||
});
|
||||
test('chroma2pc', () => {
|
||||
expect(chroma2pc(0)).toBe('C');
|
||||
expect(chroma2pc(1)).toBe('Db');
|
||||
expect(chroma2pc(1, true)).toBe('C#');
|
||||
expect(chroma2pc(2)).toBe('D');
|
||||
expect(chroma2pc(3)).toBe('Eb');
|
||||
});
|
||||
test('tokenizeChord', () => {
|
||||
expect(tokenizeChord('Cm7')).toEqual(['C', 'm7', undefined]);
|
||||
expect(tokenizeChord('C#m7')).toEqual(['C#', 'm7', undefined]);
|
||||
expect(tokenizeChord('Bb^7')).toEqual(['Bb', '^7', undefined]);
|
||||
expect(tokenizeChord('Bb^7/F')).toEqual(['Bb', '^7', 'F']);
|
||||
});
|
||||
test('note2pc', () => {
|
||||
expect(note2pc('C5')).toBe('C');
|
||||
// expect(note2pc('C52')).toBe('C'); // <- 2 digits fail
|
||||
expect(note2pc('Bb3')).toBe('Bb');
|
||||
});
|
||||
test('note2oct', () => {
|
||||
expect(note2oct('C5')).toBe(5);
|
||||
expect(note2oct('Bb3')).toBe(3);
|
||||
expect(note2oct('C7')).toBe(7);
|
||||
//expect(note2oct('C10')).toBe(10); // <- 2 digits fail
|
||||
});
|
||||
test('note2midi', () => {
|
||||
expect(note2midi('C4')).toBe(60);
|
||||
expect(note2midi('C#4')).toBe(61);
|
||||
expect(note2midi('Cb4')).toBe(59);
|
||||
expect(note2midi('Bb3')).toBe(58);
|
||||
// expect(note2midi('C10')).toBe(58); // <- 2 digits fail
|
||||
});
|
||||
test('midi2note', () => {
|
||||
expect(midi2note(60)).toBe('C4');
|
||||
expect(midi2note(61)).toBe('Db4');
|
||||
expect(midi2note(61, true)).toBe('C#4');
|
||||
});
|
||||
test('voiceBelow', () => {
|
||||
const voicingDictionary = {
|
||||
m7: [
|
||||
'3 7 10 14', // b3 5 b7 9
|
||||
'10 14 5 19', // b7 9 b3 5
|
||||
],
|
||||
};
|
||||
expect(voiceBelow('Bb4', 'Em7', voicingDictionary)).toEqual(['G3', 'B3', 'D4', 'Gb4']);
|
||||
expect(voiceBelow('D5', 'Cm7', voicingDictionary)).toEqual(['Eb4', 'G4', 'Bb4', 'D5']);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue