@@ -2,13 +2,16 @@ import { useEffect, useState } from "react";
22import "../css/MainContent.css" ;
33import AudioDeviceList from "./AudioDeviceList" ;
44import { writeSerial } from "functions/serial" ;
5+ import Loading from "./Loading" ;
56const electron = window . require ( "electron" ) ;
67
78enum AudioState {
8- Loading ,
9- Recording ,
10- Ready ,
119 Idle ,
10+ Ready ,
11+ Recording ,
12+ Processing ,
13+ Error ,
14+ Finished ,
1215}
1316
1417interface AudioDevice extends MediaStreamConstraints {
@@ -23,39 +26,68 @@ var constraints: AudioDevice = {
2326 } ,
2427} ;
2528
29+ const RECORD_MS_TIME = 5500 ;
30+
31+ const handleStart = ( event : Event ) => {
32+ setTimeout ( function ( ) {
33+ let eventRecorder = event . target as MediaRecorder ;
34+ eventRecorder . stop ( ) ;
35+ } , RECORD_MS_TIME ) ;
36+ } ;
37+
38+ const handleStop = ( setRecorderState : ( ) => void , updateState : ( ) => void ) => {
39+ setRecorderState ( ) ;
40+ updateState ( ) ;
41+ } ;
42+
2643const handleDataAvailable = ( event : BlobEvent ) => {
2744 let audioCtx = new AudioContext ( ) ;
2845 event . data . arrayBuffer ( ) . then ( ( arrayBuf ) => {
2946 audioCtx . decodeAudioData ( arrayBuf ) . then ( ( buffer ) => {
30- const float32Array = buffer . getChannelData ( 0 ) ; // get a single channel of sound
31- electron . ipcRenderer . send ( "process-audio" , float32Array ) ;
32- const data = new Uint8Array ( [ 104 , 101 , 108 , 108 , 111 ] ) ; // hello
33- writeSerial ( data ) ;
47+ //sample rate is 48kHz for my device
48+ const rawRecordedData = buffer . getChannelData ( 0 ) ; // get a single channel of sound
49+ const sampleRate = audioCtx . sampleRate ;
50+ electron . ipcRenderer . send ( "process-audio" , rawRecordedData , sampleRate ) ;
3451 } ) ;
3552 } ) ;
3653} ;
3754
3855export default function AudioRecord ( ) {
39- //const audioRef = useRef<HTMLAudioElement>(null);
4056 const [ state , setState ] = useState < AudioState > ( AudioState . Idle ) ;
41- const [ mediaStream , setMediaStream ] = useState < MediaStream > ( ) ;
4257 const [ recorder , setRecorder ] = useState < MediaRecorder > ( ) ;
4358 const [ selectedDevice , setSelectedDevice ] = useState < MediaDeviceInfo > ( ) ;
4459 const [ feedbackMsg , setFeedbackMsg ] = useState < string | null > ( ) ;
4560
4661 useEffect ( ( ) => {
47- electron . ipcRenderer . on ( "audio-finished" , ( event , message ) => {
48- setState ( AudioState . Ready ) ;
49- setFeedbackMsg ( message ) ;
50- } ) ;
62+ electron . ipcRenderer . on (
63+ "audio-finished" ,
64+ ( event , status , message , data ) => {
65+ console . log ( status ) ;
66+ if ( status === true ) {
67+ setState ( AudioState . Finished ) ;
68+ setFeedbackMsg ( message ) ;
69+ writeSerial ( data ) . then ( ( serialStatus ) => {
70+ console . log ( serialStatus ) ;
71+ } ) ;
72+ } else {
73+ setState ( AudioState . Error ) ;
74+ }
75+ }
76+ ) ;
5177 } , [ ] ) ;
5278
5379 function handleSuccess ( stream : MediaStream ) {
54- setMediaStream ( stream ) ;
5580 const options = { mimeType : "audio/webm" } ;
5681 const _recorder = new MediaRecorder ( stream , options ) ;
82+ _recorder . onstart = handleStart ;
83+ _recorder . onstop = ( ) =>
84+ handleStop (
85+ ( ) => setRecorder ( undefined ) ,
86+ ( ) => setState ( AudioState . Processing )
87+ ) ;
88+ _recorder . ondataavailable = handleDataAvailable ;
89+ _recorder . start ( ) ;
5790 setRecorder ( _recorder ) ;
58- //audioRef.current.srcObject = stream;
5991 }
6092
6193 function handleError ( error : Error ) {
@@ -73,13 +105,6 @@ export default function AudioRecord() {
73105 }
74106 } , [ selectedDevice ] ) ;
75107
76- useEffect ( ( ) => {
77- if ( recorder ) {
78- recorder . ondataavailable = handleDataAvailable ;
79- recorder . start ( ) ;
80- }
81- } , [ recorder ] ) ;
82-
83108 const handleClick = ( ) => {
84109 if ( state === AudioState . Ready && selectedDevice ) {
85110 setFeedbackMsg ( null ) ;
@@ -89,15 +114,6 @@ export default function AudioRecord() {
89114 . getUserMedia ( constraints )
90115 . then ( handleSuccess )
91116 . catch ( handleError ) ;
92- } else if ( state === AudioState . Recording ) {
93- setState ( AudioState . Loading ) ;
94- if ( recorder ) {
95- recorder . stop ( ) ;
96- setRecorder ( undefined ) ;
97- }
98- if ( mediaStream ) {
99- setMediaStream ( undefined ) ;
100- }
101117 }
102118 } ;
103119
@@ -112,18 +128,29 @@ export default function AudioRecord() {
112128 break ;
113129 }
114130 case AudioState . Recording : {
115- buttonDisplay = "Click to Stop " ;
116- isDisabled = false ;
131+ buttonDisplay = "Recording... " ;
132+ isDisabled = true ;
117133 break ;
118134 }
119135 case AudioState . Ready : {
120136 buttonDisplay = "Click to Start" ;
121137 isDisabled = false ;
122138 break ;
123139 }
124- case AudioState . Loading : {
140+ case AudioState . Processing : {
125141 buttonDisplay = "Processing..." ;
126142 isDisabled = true ;
143+ break ;
144+ }
145+ case AudioState . Finished : {
146+ buttonDisplay = "Finished" ;
147+ isDisabled = true ;
148+ break ;
149+ }
150+ case AudioState . Error : {
151+ buttonDisplay = "Error" ;
152+ isDisabled = true ;
153+ break ;
127154 }
128155 }
129156 return (
@@ -136,10 +163,12 @@ export default function AudioRecord() {
136163 const getStateMessage = ( ) : string | null => {
137164 if ( state === AudioState . Idle ) {
138165 return "Please select an audio device" ;
139- } else if ( state === AudioState . Loading ) {
166+ } else if ( state === AudioState . Processing ) {
140167 return "Processing..." ;
141168 } else if ( state === AudioState . Recording ) {
142169 return "Recording..." ;
170+ } else if ( state === AudioState . Error ) {
171+ return "An error occured while performing test. Please try again." ;
143172 }
144173 return null ;
145174 } ;
@@ -150,12 +179,11 @@ export default function AudioRecord() {
150179 { getStateMessage ( ) }
151180 { feedbackMsg }
152181 </ div >
153- < AudioDeviceList selectDevice = { setSelectedDevice } />
154- { /*
155- <div className="media-player">
156- <audio id="gum-local" ref={audioRef} controls autoPlay></audio>
157- </div>
158- */ }
182+ { state == AudioState . Recording || state == AudioState . Processing ? (
183+ < Loading />
184+ ) : (
185+ < AudioDeviceList selectDevice = { setSelectedDevice } />
186+ ) }
159187 { getButton ( ) }
160188 </ div >
161189 ) ;
0 commit comments