57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package speech
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Test_hardware opens a temporary client; it never replaces the reader's
|
|
// transport. Keep the connection while the device speaks: Close cancels its
|
|
// buffer, and these devices provide no speech-completion acknowledgement.
|
|
func Test_hardware(ctx context.Context, driverID string, options Options, text string) error {
|
|
driver, err := Find_driver(driverID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !driver.Hardware {
|
|
return fmt.Errorf("selected driver is not a hardware synthesizer")
|
|
}
|
|
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
|
defer cancel()
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
client, err := Open_driver(driverID, options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stop, stopped := make(chan struct{}), make(chan struct{})
|
|
go func() {
|
|
defer close(stopped)
|
|
select {
|
|
case <-ctx.Done():
|
|
_ = client.Cancel()
|
|
case <-stop:
|
|
}
|
|
}()
|
|
defer func() { close(stop); <-stopped; client.Close() }()
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
if err := client.Say(text); err != nil {
|
|
return err
|
|
}
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
<-ctx.Done()
|
|
if ctx.Err() == context.DeadlineExceeded {
|
|
return nil
|
|
}
|
|
return ctx.Err()
|
|
}
|