license import * as tf from '@tensorflow/tfjs-core' ; import { promisify } from 'util' ; import { RawAudioData } from './types' ; export async function loadMetadataJson ( url ) { const HTTP_SCHEME = 'http://' ; const HTTPS_SCHEME = 'https://' ; const FILE_SCHEME = 'file://' ; if ( url . indexOf ( HTTP_SCHEME ) === 0 || url . indexOf ( HTTPS_SCHEME ) === 0 ) { const response = await fetch ( url ) ; const parsed = await response . json ( ) ; return parsed ; } else if ( url . indexOf ( FILE_SCHEME ) === 0 ) { const fs = require ( 'fs' ) ; const readFile = promisify ( fs . readFile ) ; return JSON . parse ( await readFile ( url . slice ( FILE_SCHEME . length ) , { encoding : 'utf-8' } ) ) ; } else { throw new Error ( `Unsupported URL scheme in metadata URL: ${ url }. ` + `Supported schemes are: http://, https://, and ` + `(node.js-only) file://` ) ; } } let EPSILON = null ; param x param y export function normalize ( x ) { if ( EPSILON == null ) { EPSILON = tf . backend ( ) . epsilon ( ) ; } return tf . tidy ( ( ) => { const { mean , variance } = tf . moments ( x ) ; return tf . div ( tf . sub ( x , mean ) , tf . add ( tf . sqrt ( variance ) , EPSILON ) ) ; } ) ; } param x return export function normalizeFloat32Array ( x ) { if ( x . length < 2 ) { throw new Error ( 'Cannot normalize a Float32Array with fewer than 2 elements.' ) ; } if ( EPSILON == null ) { EPSILON = tf . backend ( ) . epsilon ( ) ; } return tf . tidy ( ( ) => { const { mean , variance } = tf . moments ( tf . tensor1d ( x ) ) ; const meanVal = mean . arraySync ( ) as number ; const stdVal = Math . sqrt ( variance . arraySync ( ) as number ) ; const yArray = Array . from ( x ) . map ( y => ( y - meanVal ) / ( stdVal + EPSILON ) ) ; return new Float32Array ( yArray ) ; } ) ; } export function getAudioContextConstructor ( ) { return ( window as any ) . AudioContext || ( window as any ) . webkitAudioContext ; } export async function getAudioMediaStream ( audioTrackConstraints ? ) { return navigator . mediaDevices . getUserMedia ( { audio : audioTrackConstraints == null ? true : audioTrackConstraints , video : false } ) ; } param rawAudio param onEnded export function playRawAudio ( rawAudio , onEnded ) { const audioContextConstructor = ( window as any ) . AudioContext || ( window as any ) . webkitAudioContext ; const audioContext = new audioContextConstructor ( ) ; const arrayBuffer = audioContext . createBuffer ( 1 , rawAudio . data . length , rawAudio . sampleRateHz ) ; const nowBuffering = arrayBuffer . getChannelData ( 0 ) ; nowBuffering . set ( rawAudio . data ) ; const source = audioContext . createBufferSource ( ) ; source . buffer = arrayBuffer ; source . connect ( audioContext . destination ) ; source . start ( ) ; source . onended = ( ) => { if ( onEnded != null ) { onEnded ( ) ; } } ; }