diff --git a/src/audioUtil.js b/src/audioUtil.js index dbd6127..0ab4475 100644 --- a/src/audioUtil.js +++ b/src/audioUtil.js @@ -1,7 +1,7 @@ import { soundChord } from "../app.js"; import { getRandomPitches } from "./pitch_generation/getRandomPitches.js"; import { getProceduralPitches } from "./pitch_generation/getProceduralPitches.js"; -import { extractPitchset } from "./vector_logic/extractPitchset.js"; +import { extractPitchset } from "./data_conversions/extractPitchset.js"; // initial test: generate a single, random chord export const fullRandomChord = () => { diff --git a/src/data_conversions/extractOctave.js b/src/data_conversions/extractOctave.js new file mode 100644 index 0000000..6731ddb --- /dev/null +++ b/src/data_conversions/extractOctave.js @@ -0,0 +1 @@ +export const extractOctave = (pitchName) => pitchName.match(/[0-9]/g).join(''); diff --git a/src/vector_logic/extractPitchName.js b/src/data_conversions/extractPitchName.js similarity index 100% rename from src/vector_logic/extractPitchName.js rename to src/data_conversions/extractPitchName.js diff --git a/src/vector_logic/extractPitchset.js b/src/data_conversions/extractPitchset.js similarity index 100% rename from src/vector_logic/extractPitchset.js rename to src/data_conversions/extractPitchset.js diff --git a/src/pitch_generation/getProceduralPitches.js b/src/pitch_generation/getProceduralPitches.js index fbf1c5b..51ec6e5 100644 --- a/src/pitch_generation/getProceduralPitches.js +++ b/src/pitch_generation/getProceduralPitches.js @@ -1,6 +1,7 @@ import { pitchsets, musicalPitches } from "../harmonyUtil.js"; -import { extractPitchName } from "../vector_logic/extractPitchName.js"; +import { extractPitchName } from "../data_conversions/extractPitchName.js"; import { getRandomIndex } from "./getRandomPitches.js"; +import { melodicGeneration } from './melodicGeneration.js'; // iterator to prevent stack overflow let callCount = 0; @@ -62,57 +63,7 @@ export const getProceduralPitches = () => { console.log(`call count: ${callCount}`); callCount = 0; console.log(pitches); + melodicGeneration(pitches); return pitches; } } - -// an additional method based on the structure of getRandomPitches, -// but taking some principles of music theory into account. -export const old_getProceduralPitches = (prevPitches) => { - // prevPitches is passed in to ensure there is no linear dissonance within voices - let pitches = []; - let formattedPitches = []; - - for (let voice of pitchsets) { - let index; - let formattedPitch; - - while (pitches.length <= pitchsets.indexOf(voice)) { - // the first section of this while loop is more free. - index = getRandomIndex(voice); - formattedPitch = extractPitchName(voice[index]); - - // this initial condition will apply only to the bass voice, - if (!pitches.length) { - pitches.push(voice[index]); - } else { - // now we need some repeating logic for the remaining four voices - while (pitches.length !== (pitchsets.indexOf(voice) + 1)) { - index = getRandomIndex(voice); - pitches.push(voice[index]); - - - for (let i = 0; i < pitches.length; i++) { - let numVals = []; - - for (let j = i; j < i + 2; j++) { - console.log(pitches[j]); - let extracted = extractPitchName(pitches[j]); - numVals.push(musicalPitches.indexOf(extracted) + 1); - } - - let difference = Math.abs(numVals.reduce((x,y) => x - y)); - if (difference === 1 || difference === 6) { - pitches.pop(); - } else { - continue; - } - } - } - } - } - } - - console.log(pitches); - return pitches; -} diff --git a/src/pitch_generation/getRandomPitches.js b/src/pitch_generation/getRandomPitches.js index aee08bd..185d085 100644 --- a/src/pitch_generation/getRandomPitches.js +++ b/src/pitch_generation/getRandomPitches.js @@ -1,5 +1,5 @@ import { pitchsets } from "../harmonyUtil.js"; -import { extractPitchName } from "../vector_logic/extractPitchName.js"; +import { extractPitchName } from "../data_conversions/extractPitchName.js"; // helper function for assigning a random index for a given voice's pitchset export const getRandomIndex = (voice) => Math.floor(Math.random() * 100) % voice.length; diff --git a/src/pitch_generation/melodicGeneration.js b/src/pitch_generation/melodicGeneration.js new file mode 100644 index 0000000..1005c26 --- /dev/null +++ b/src/pitch_generation/melodicGeneration.js @@ -0,0 +1,46 @@ +import { getRandomPitches } from './getRandomPitches.js'; +import { extractPitchName } from '../data_conversions/extractPitchName.js'; +import { extractOctave } from '../data_conversions/extractOctave.js'; +import { musicalPitches } from '../harmonyUtil.js'; + +// reads the pitch of the previous sonority and determines appropriate melodic movement for the soprano +// returns a boolean which triggers a recursive call if the interval received is out of expected values + +let callCount = 0; + +export const melodicGeneration = (prevPitches) => { + callCount++; + + // direction: boolean; true refers to ascending motion; false refers to descending motion + let direction; + + const preferredMotion = [0,1,2,3,4]; + let isMelodic = true; + + let newPitches = getRandomPitches(); + let prevSoprano = prevPitches[3]; + let newSoprano = newPitches[3]; + + let octaveOne = extractOctave(prevSoprano); + let octaveTwo = extractOctave(newSoprano); + + let pitchNameOne = extractPitchName(prevSoprano); + let pitchNameTwo = extractPitchName(newSoprano); + + let pitchNumOne = musicalPitches.indexOf(pitchNameOne); + let pitchNumTwo = musicalPitches.indexOf(pitchNameTwo); + + console.log(prevSoprano, newSoprano); + + let interval = pitchNumOne - pitchNumTwo; + direction = interval > 0; + + isMelodic = preferredMotion.includes(Math.abs(interval)); + + console.log(`interval: ${interval}`); + console.log(`direction: ${direction ? 'ascending' : 'descending'}`); + console.log(`isMelodic: ${isMelodic}`); + console.log(`melody call count: ${callCount}`); + + callCount = 0; +} diff --git a/src/vector_logic/evaluateVector.js b/src/vector_logic/evaluateVector.js index 2d5268f..808476c 100644 --- a/src/vector_logic/evaluateVector.js +++ b/src/vector_logic/evaluateVector.js @@ -1,5 +1,5 @@ import { getRandomPitches } from '../pitch_generation/getRandomPitches.js'; -import { extractPitchset } from "./extractPitchset.js"; +import { extractPitchset } from "../data_conversions/extractPitchset.js"; import { findVector } from "./findVector.js"; export const evaluateVector = (vector) => { diff --git a/src/vector_logic/helper.js b/src/vector_logic/helper.js deleted file mode 100644 index 50e38d0..0000000 --- a/src/vector_logic/helper.js +++ /dev/null @@ -1,96 +0,0 @@ -import { pitchsets, musicalPitches } from '../harmonyUtil.js'; -import { extractPitchName } from './extractPitchName.js'; -import { getRandomIndex } from '../pitch_generation/getRandomPitches.js'; - -let callCount = 0; - -const iteratePitchsets = () => { - callCount++; - - if (callCount >= 10) { - return ["E3", "C4", "D4", "G4"]; - } - - const bass = pitchsets[0]; - let bassNote = bass[getRandomIndex(bass)]; - - let pitches = [bassNote]; - let result = []; - - for (let i = 1; i < 4; i++) { - let voice = pitchsets[i]; - let idx = getRandomIndex(voice); - let pitch = voice[idx]; - pitches.push(pitch); - } - - let pitchNames = pitches.map(x => extractPitchName(x)); - let pitchNums = pitchNames.map(x => musicalPitches.indexOf(x)); - - console.log(pitches); - console.log(pitchNames); - console.log(pitchNums); - - let isDissonant = false; - - for (let i = 0; i < pitchNums.length; i++) { - for (let j = i; j < pitchNums.length; j++) { - let interval = Math.abs(pitchNums[i] - pitchNums[j]); - if (interval > 6) { - interval = 12 - interval; - } - - let intervalIsDissonant = ((interval === 1) || (interval === 6)); - // console.log(`pitches: ${[pitches[i], pitches[j]]} interval: ${interval}, dissonant: ${isDissonant}, positions: [${i}, ${j}]: ${[pitchNums[i], pitchNums[j]]}`); - - if (!intervalIsDissonant) { - continue; - } else { - isDissonant = true; - } - } - } - - if (isDissonant) { - console.log('bad'); - let newValues = iteratePitchsets(); - return newValues; - } else { - console.log('good'); - console.log(pitches); - return pitches; - } -} - -function twoPointIteration() { - let caught = false; - let data = [1,2,3,4,5,6]; - - for (let i = 0; i < data.length; i++) { - console.log(data[i]); - for (let j = 0; j < data.length; j++) { - if (data[i] === data[j]) continue; - - let difference = Math.abs(data[j] - data[i]); - - if (difference === 3) { - difference = "caught: 3"; - } - - console.log([difference, [data[i], data[j]]]); - } - - console.log('next'); - } - - return caught; -} - -function selfReferentialPointer() { - for (let i = 0; i < 5; i++) { - console.log(`i: ${i}`); - for (let j = i; j < i+2; j++) { - console.log(`jjjjjjj: ${j % 3}`); - } - } -}