import * as Redux from 'redux' ; import { AudioNode } from '../audio/AudioNode' ; import { ThemeManager } from '../audio/ThemeManager' ; import { MUSIC_DEFINITIONS } from '../Constants' ; import { getAudioContext } from '../Globals' ; import { AudioDataState , AudioState } from '../reducers/StateTypes' ; import { AudioDataSetAction , AudioSetAction } from './ActionTypes' ; const eachLimit = require ( 'async/eachLimit' ) ; export function getAllMusicFiles ( ) { return Object . keys ( MUSIC_DEFINITIONS ) . reduce ( ( list , musicClass ) => { return list . concat ( Object . keys ( MUSIC_DEFINITIONS [ musicClass ] ) . reduce ( ( acc , musicWeight ) => { const weight = MUSIC_DEFINITIONS [ musicClass ] [ musicWeight ] ; for ( const instrument of weight . instruments ) { for ( let v = 1 ; v <= weight . variants ; v ++ ) { acc . push ( `${ musicClass }/${ musicWeight }/${ instrument }${ v }` ) ; } } return acc ; } , [ ] ) ) ; } , [ ] ) ; } export function loadAudioLocalFile ( context , url , callback ) { const request = new XMLHttpRequest ( ) ; request . open ( 'GET' , url , true ) ; request . responseType = 'arraybuffer' ; request . onload = ( ) => { context . decodeAudioData ( request . response , ( buffer ) => { return callback ( null , new AudioNode ( context , buffer ) ) ; } , ( err ) => { return callback ( err , null ) ; } ) ; } ; request . onerror = ( ) => { return callback ( Error ( 'Network error' ) , null ) ; } ; request . send ( ) ; } function audioDataSet ( data ) { return { type : 'AUDIO_DATA_SET' , data } ; } export function loadAudioFiles ( ) { return ( dispatch ) : any => { const ac = getAudioContext ( ) ; if ( ! ac ) { return ; } dispatch ( audioSet ( { loaded : 'LOADING' } ) ) ; const musicFiles = getAllMusicFiles ( ) ; const audioNodes = { } ; eachLimit ( musicFiles , 4 , ( file , callback ) => { loadAudioLocalFile ( ac , 'audio/' + file + '.mp3' , ( err , ns ) => { if ( err ) { console . error ( 'Error loading audio file ' + file + ': ' + err . toString ( ) ) ; return callback ( err ) ; } audioNodes [ file ] = ns ; return callback ( ) ; } ) ; } , ( err ? ) => { if ( err ) { dispatch ( audioSet ( { loaded : 'ERROR' } ) ) ; return ; } dispatch ( audioSet ( { loaded : 'LOADED' } ) ) ; const themeManager = new ThemeManager ( audioNodes , Math . random ) ; dispatch ( audioDataSet ( { audioNodes , themeManager } ) ) ; } ) ; } ; } export function audioSet ( delta ) { return { delta : { sfx : null , timestamp : Date . now ( ) , ... delta , } , type : 'AUDIO_SET' , } as AudioSetAction ; }