import React , { useEffect } from 'react' ; import StartAudioContext from 'startaudiocontext' ; import Tone from '../lib/tone' ; type SongContextProps = { isPlaying : boolean ; } ; export const SongContext = React . createContext < SongContextProps > ( { isPlaying : false } ) ; export type SongProps = { isPlaying ? : boolean ; bpm ? : number ; swing ? : number ; subdivision ? : string ; swingSubdivision ? : string ; volume ? : number ; isMuted ? : boolean ; children ? : React . ReactNode ; } ; const Song = ( { isPlaying = false , bpm = 90 , swing = 0 , swingSubdivision = '8n' , volume = 0 , isMuted = false , children , } ) => { useEffect ( ( ) => { document . body . addEventListener ( 'click' , ( ) => { StartAudioContext ( Tone . context ) ; } , { once : true } ) ; } , [ ] ) ; useEffect ( ( ) => { Tone . Transport . bpm . value = bpm ; Tone . Transport . swing = swing ; Tone . Transport . swingSubdivision = swingSubdivision ; } , [ bpm , swing , swingSubdivision ] ) ; useEffect ( ( ) => { if ( isPlaying ) { Tone . Transport . bpm . value = bpm ; Tone . Transport . swing = swing ; Tone . Transport . swingSubdivision = swingSubdivision ; Tone . Transport . start ( ) ; } else { Tone . Transport . stop ( ) ; } } , [ isPlaying ] ) ; useEffect ( ( ) => { Tone . Master . volume . value = volume ; } , [ volume ] ) ; useEffect ( ( ) => { Tone . Master . mute = isMuted ; } , [ isMuted ] ) ; if ( typeof window === 'undefined' ) { return null ; } return ( < SongContext . Provider value = { { isPlaying } } > { children } < /SongContext.Provider>); } ; export default Song ;