@@ -100,7 +100,7 @@ mod test {
100100 use super :: types;
101101 use super :: * ;
102102
103- // cargo test --package esp_assistant --bin esp_assistant -- ai::gemini::test::test_live_client --exact --show-output
103+ // cargo test --package echokit_server --bin echokit_server -- ai::gemini::test::test_live_client --exact --show-output
104104 #[ tokio:: test]
105105 async fn test_live_client ( ) -> anyhow:: Result < ( ) > {
106106 env_logger:: init ( ) ;
@@ -121,24 +121,96 @@ mod test {
121121 ) ] ,
122122 } ) ,
123123 input_audio_transcription : Some ( types:: AudioTranscriptionConfig { } ) ,
124+ output_audio_transcription : None ,
125+ realtime_input_config : Some ( types:: RealtimeInputConfig {
126+ automatic_activity_detection : Some ( types:: AutomaticActivityDetectionConfig {
127+ disabled : true ,
128+ } ) ,
129+ } ) ,
124130 } ;
125131 client. setup ( setup) . await ?;
126132 log:: info!( "Setup completed" ) ;
127133
128134 // let submit_data = std::fs::read("sample.pcm").unwrap();
129- let data = std:: fs:: read ( "asr.fc012ccfcd71 .wav" ) . unwrap ( ) ;
135+ let data = std:: fs:: read ( "tmp .wav" ) . unwrap ( ) ;
130136 let mut reader = wav_io:: reader:: Reader :: from_vec ( data) . unwrap ( ) ;
131137 let header = reader. read_header ( ) . unwrap ( ) ;
132138 log:: info!( "WAV Header: {:?}" , header) ;
133- let x = reader . get_samples_f32 ( ) . unwrap ( ) ;
139+ let x = crate :: util :: get_samples_f32 ( & mut reader ) . unwrap ( ) ;
134140 let x = wav_io:: resample:: linear ( x, 1 , header. sample_rate , 16000 ) ;
135- let data = wav_io:: convert_samples_f32_to_i16 ( & x) ;
141+ let submit_data = crate :: util:: convert_samples_f32_to_i16_bytes ( & x) ;
142+
143+ // let input = types::RealtimeInput {
144+ // audio: None,
145+ // text: Some("你是谁".to_string()),
146+ // };
147+ client
148+ . send_realtime_input ( types:: RealtimeInput :: ActivityStart { } )
149+ . await ?;
136150
137- let mut submit_data = Vec :: with_capacity ( data. len ( ) * 2 ) ;
138- for sample in data {
139- submit_data. extend_from_slice ( & sample. to_le_bytes ( ) ) ;
151+ let input = types:: RealtimeInput :: Audio ( types:: RealtimeAudio {
152+ data : types:: Blob :: new ( submit_data) ,
153+ mime_type : "audio/pcm;rate=16000" . to_string ( ) ,
154+ } ) ;
155+ log:: info!( "Sending realtime input" ) ;
156+ client. send_realtime_input ( input) . await ?;
157+ log:: info!( "Sent realtime input" ) ;
158+ // client
159+ // .send_realtime_input(types::RealtimeInput::AudioStreamEnd(true))
160+ // .await?;
161+ client
162+ . send_realtime_input ( types:: RealtimeInput :: ActivityEnd { } )
163+ . await ?;
164+
165+ log:: info!( "Sent realtime input" ) ;
166+ loop {
167+ let content = client. receive ( ) . await ?;
168+ log:: info!( "Received content: {:?}" , content) ;
169+ if let types:: ServerContent :: TurnComplete ( true ) = content {
170+ log:: info!( "Generation complete" ) ;
171+ break ;
172+ }
140173 }
141174
175+ Ok ( ( ) )
176+ }
177+
178+ // cargo test --package echokit_server --bin echokit_server -- ai::gemini::test::test_live_client_audio --exact --show-output
179+ #[ tokio:: test]
180+ async fn test_live_client_audio ( ) -> anyhow:: Result < ( ) > {
181+ env_logger:: init ( ) ;
182+ let api_key = std:: env:: var ( "GEMINI_API_KEY" ) . unwrap ( ) ;
183+ log:: info!( "api_key={api_key}" ) ;
184+ let mut client = LiveClient :: connect ( & api_key) . await ?;
185+ log:: info!( "Connected to Gemini Live Client" ) ;
186+
187+ let mut cfg = types:: GenerationConfig :: default ( ) ;
188+ cfg. response_modalities = Some ( vec ! [ types:: Modality :: AUDIO ] ) ;
189+
190+ let setup = types:: Setup {
191+ model : "models/gemini-2.0-flash-exp" . to_string ( ) ,
192+ generation_config : Some ( cfg) ,
193+ system_instruction : Some ( types:: Content {
194+ parts : vec ! [ types:: Parts :: Text (
195+ "You are a helpful assistant and answer in a friendly tone." . to_string( ) ,
196+ ) ] ,
197+ } ) ,
198+ input_audio_transcription : Some ( types:: AudioTranscriptionConfig { } ) ,
199+ output_audio_transcription : Some ( types:: AudioTranscriptionConfig { } ) ,
200+ realtime_input_config : None ,
201+ } ;
202+ client. setup ( setup) . await ?;
203+ log:: info!( "Setup completed" ) ;
204+
205+ // let submit_data = std::fs::read("sample.pcm").unwrap();
206+ let data = std:: fs:: read ( "tmp.wav" ) . unwrap ( ) ;
207+ let mut reader = wav_io:: reader:: Reader :: from_vec ( data) . unwrap ( ) ;
208+ let header = reader. read_header ( ) . unwrap ( ) ;
209+ log:: info!( "WAV Header: {:?}" , header) ;
210+ let x = crate :: util:: get_samples_f32 ( & mut reader) . unwrap ( ) ;
211+ let x = wav_io:: resample:: linear ( x, 1 , header. sample_rate , 16000 ) ;
212+ let submit_data = crate :: util:: convert_samples_f32_to_i16_bytes ( & x) ;
213+
142214 // let input = types::RealtimeInput {
143215 // audio: None,
144216 // text: Some("你是谁".to_string()),
@@ -147,12 +219,14 @@ mod test {
147219 data : types:: Blob :: new ( submit_data) ,
148220 mime_type : "audio/pcm;rate=16000" . to_string ( ) ,
149221 } ) ;
222+ log:: info!( "Sending realtime input" ) ;
150223 client. send_realtime_input ( input) . await ?;
224+ log:: info!( "Sent realtime input" ) ;
151225 client
152226 . send_realtime_input ( types:: RealtimeInput :: AudioStreamEnd ( true ) )
153227 . await ?;
154228
155- log:: info!( "Sent realtime input " ) ;
229+ log:: info!( "Sent realtime AudioStreamEnd " ) ;
156230 loop {
157231 let content = client. receive ( ) . await ?;
158232 log:: info!( "Received content: {:?}" , content) ;
0 commit comments