@@ -8,18 +8,27 @@ import { computed, type ComputedRef } from 'vue'
88import TIMBRES from '@/timbres.json'
99
1010type Spectrum = number [ ]
11+ type Timbre = { spectrum : Spectrum ; amplitudes : number [ ] ; source ?: string }
1112
1213type Timbres = {
1314 plainSpectra : { [ key : string ] : Spectrum }
14- // TODO: Migrate inharmonic metallic and some other timbral data
15+ timbres : { [ key : string ] : Timbre }
1516}
1617
1718function getPlainSpectrum ( id : string ) : Spectrum {
1819 return ( TIMBRES as unknown as Timbres ) . plainSpectra [ id ]
1920}
2021
2122function getPlainSpectraWaveformNames ( ) : string [ ] {
22- return Object . keys ( ( TIMBRES as unknown as Timbres ) . plainSpectra )
23+ return Object . keys ( ( TIMBRES as unknown as Timbres ) . plainSpectra ) . sort ( )
24+ }
25+
26+ function getTimbre ( id : string ) : Timbre {
27+ return ( TIMBRES as unknown as Timbres ) . timbres [ id ]
28+ }
29+
30+ function getTimbreWaveformNames ( ) : string [ ] {
31+ return Object . keys ( ( TIMBRES as unknown as Timbres ) . timbres ) . sort ( )
2332}
2433
2534export const BASIC_WAVEFORMS = [ 'sine' , 'square' , 'sawtooth' , 'triangle' ]
@@ -49,6 +58,7 @@ export const CUSTOM_WAVEFORMS = [
4958export const WAVEFORMS = BASIC_WAVEFORMS . concat ( CUSTOM_WAVEFORMS )
5059export const PERIODIC_WAVES : Record < string , ComputedRef < PeriodicWave > > = { }
5160
61+ // Some of these have entries in timbres.json, but we preserve the old UI order.
5262export const APERIODIC_WAVEFORMS = [
5363 'jegogan' ,
5464 'jublag' ,
@@ -332,55 +342,6 @@ function initializeAperiodic(audioContext: BaseAudioContext) {
332342 return new AperiodicWave ( audioContext , spectrum , amplitudes , maxNumberOfVoices , tolerance )
333343 } )
334344
335- // https://pubs.aip.org/asa/jasa/article/127/5/EL197/783208/Vibrational-characteristics-of-Balinese-gamelan
336- APERIODIC_WAVES [ 'jublag' ] = computed ( ( ) => {
337- // Spectrum is from literature
338- const spectrum = [ 1 , 2.77 , 5.18 , 5.33 ]
339- // Made up stuff to round it off
340- spectrum . push ( 9.1 , 18.9 , 23 )
341- // Add shimmer
342- spectrum [ 0 ] = 1.01
343- spectrum . unshift ( 1 / spectrum [ 0 ] )
344- spectrum . push ( 2.76 )
345-
346- // Amplitudes are made up
347- const amplitudes = [ 1 , 0.5 , 0.5 , 0.3 , 0.2 , 0.15 , 0.1 , 0.09 , 0.2 ] . map ( ( a ) => 0.45 * a )
348-
349- return new AperiodicWave ( audioContext , spectrum , amplitudes , maxNumberOfVoices , tolerance )
350- } )
351-
352- // https://pubs.aip.org/asa/jasa/article/127/5/EL197/783208/Vibrational-characteristics-of-Balinese-gamelan
353- APERIODIC_WAVES [ 'ugal' ] = computed ( ( ) => {
354- // Spectrum is from literature
355- const spectrum = [ 1 , 2.61 , 4.8 , 4.94 , 6.32 ]
356- // Made up stuff to round it off
357- spectrum . push ( 9.9 , 17 , 24.1 )
358- // Add shimmer
359- spectrum [ 0 ] = 1.008
360- spectrum . unshift ( 1 / spectrum [ 0 ] )
361- spectrum . push ( 2.605 )
362- spectrum . push ( 4.81 )
363-
364- // Amplitudes are made up
365- const amplitudes = [ 0.6 , 1 , 0.45 , 0.3 , 0.15 , 0.2 , 0.07 , 0.08 , 0.05 , 0.1 , 0.1 ] . map (
366- ( a ) => 0.45 * a
367- )
368-
369- return new AperiodicWave ( audioContext , spectrum , amplitudes , maxNumberOfVoices , tolerance )
370- } )
371-
372- // https://pubs.aip.org/asa/jasa/article/127/5/EL197/783208/Vibrational-characteristics-of-Balinese-gamelan
373- APERIODIC_WAVES [ 'jegogan' ] = computed ( ( ) => {
374- // Spectrum is from literature
375- const spectrum = [
376- 1 , 2.8 , 5.5 , 9 , 16.7 , 17.8 , 20.5 , 22.9 , 24.9 , 27 , 28.1 , 29.2 , 29.5 , 30 , 31.8 , 33.3 , 36 , 36.9 ,
377- 40.6 , 41.4
378- ]
379- // Amplitudes are made up
380- const amplitudes = spectrum . map ( ( i ) => ( 0.7 * ( Math . cos ( 0.3 * i * i ) + 1.6 ) ) / ( i ** 1.4 + 1.6 ) )
381- return new AperiodicWave ( audioContext , spectrum , amplitudes , maxNumberOfVoices , tolerance )
382- } )
383-
384345 APERIODIC_WAVES [ '12-TET' ] = computed ( ( ) => {
385346 const twelveSpectrumCents : number [ ] = [ ]
386347 const twelveAmplitudes : number [ ] = [ ]
@@ -405,26 +366,6 @@ function initializeAperiodic(audioContext: BaseAudioContext) {
405366 )
406367 } )
407368
408- APERIODIC_WAVES [ 'piano' ] = computed ( ( ) => {
409- const spectrum = [
410- 0.998711340392508 , 1.0012886596074921 , 2.000000001915048 , 3.0077319605175252 ,
411- 4.024484537329971 , 4.028350517109971 , 5.052835053482418 , 6.0953608281898495 ,
412- 6.100515466619817 , 7.149484540322233 , 7.158505158532202 , 8.221649488874554 , 9.326030932401801 ,
413- 9.3298969121818 , 9.33891753039177 , 10.449742272914 , 10.457474232474 , 10.466494850683969 ,
414- 11.597938150756168
415- ]
416-
417- const amps = [
418- 0.9123120265773679 , 0.7281477301038842 , 0.5078045641543809 , 0.8061314224800064 ,
419- 0.3177244232370868 , 0.15135058363038334 , 0.12440135191000032 , 0.045007651288955175 ,
420- 0.050804443667738106 , 0.029671376885221354 , 0.023841125287306208 , 0.01853341284211317 ,
421- 0.02380292893502422 , 0.024761095205029133 , 0.020866326567241505 , 0.0017670624571622458 ,
422- 0.0024893662658642206 , 0.0012043792096897129 , 0.0014228119365412375
423- ] . map ( ( a ) => a * 0.38 )
424-
425- return new AperiodicWave ( audioContext , spectrum , amps , maxNumberOfVoices , tolerance )
426- } )
427-
428369 getPlainSpectraWaveformNames ( ) . forEach ( ( id ) => {
429370 APERIODIC_WAVES [ id ] = computed ( ( ) => {
430371 const spectrum = getPlainSpectrum ( id )
@@ -436,6 +377,13 @@ function initializeAperiodic(audioContext: BaseAudioContext) {
436377 return new AperiodicWave ( audioContext , spectrum , amps , maxNumberOfVoices , tolerance )
437378 } )
438379 } )
380+
381+ getTimbreWaveformNames ( ) . forEach ( ( id ) => {
382+ APERIODIC_WAVES [ id ] = computed ( ( ) => {
383+ const { spectrum, amplitudes } = getTimbre ( id )
384+ return new AperiodicWave ( audioContext , spectrum , amplitudes , maxNumberOfVoices , tolerance )
385+ } )
386+ } )
439387}
440388
441389export function initializeCustomWaves ( audioContext : BaseAudioContext ) {
0 commit comments