(
state: web::Data<Arc<RwLock<Master<M>>>>,
req: HttpRequest,
body: web::Json<AudioSpeechRequest>,
)
| 48 | } |
| 49 | |
| 50 | pub async fn generate_speech<M: Model>( |
| 51 | state: web::Data<Arc<RwLock<Master<M>>>>, |
| 52 | req: HttpRequest, |
| 53 | body: web::Json<AudioSpeechRequest>, |
| 54 | ) -> impl Responder { |
| 55 | let client = req |
| 56 | .peer_addr() |
| 57 | .map(|a| a.to_string()) |
| 58 | .unwrap_or_else(|| "unknown".to_string()); |
| 59 | |
| 60 | log::info!("starting audio generation for {} ...", &client); |
| 61 | |
| 62 | let mut master = state.write().await; |
| 63 | |
| 64 | if !master.model.as_ref().is_some_and(|m| m.output_modality() == OutputModality::Audio) { |
| 65 | return HttpResponse::NotFound() |
| 66 | .json(serde_json::json!({"error": "No audio model loaded"})); |
| 67 | } |
| 68 | |
| 69 | // Decode base64 voice data if provided |
| 70 | let voice_data = match &body.voice_data { |
| 71 | Some(b64) => match general_purpose::STANDARD.decode(b64) { |
| 72 | Ok(bytes) => Some(bytes), |
| 73 | Err(e) => { |
| 74 | return HttpResponse::BadRequest() |
| 75 | .json(serde_json::json!({"error": format!("Invalid voice_data base64: {e}")})); |
| 76 | } |
| 77 | }, |
| 78 | None => None, |
| 79 | }; |
| 80 | |
| 81 | let args = AudioGenerationArgs { |
| 82 | input: body.input.clone(), |
| 83 | voice_data, |
| 84 | voice_path: body.voice_path.clone(), |
| 85 | cfg_scale: body.cfg_scale, |
| 86 | max_frames: body.max_frames, |
| 87 | diffusion_steps: body.diffusion_steps, |
| 88 | }; |
| 89 | |
| 90 | match master.generate_audio(&args).await { |
| 91 | Ok(output) => { |
| 92 | if body.response_format == "pcm" { |
| 93 | HttpResponse::Ok() |
| 94 | .content_type("audio/pcm") |
| 95 | .body(output.to_pcm_bytes()) |
| 96 | } else { |
| 97 | HttpResponse::Ok() |
| 98 | .content_type("audio/wav") |
| 99 | .body(output.to_wav_bytes()) |
| 100 | } |
| 101 | } |
| 102 | Err(e) => HttpResponse::InternalServerError() |
| 103 | .json(serde_json::json!({"error": format!("{e}")})), |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | #[cfg(test)] |
nothing calls this directly
no test coverage detected