Nik Afiq 5238298b55
Some checks failed
CI / test (push) Successful in 6s
CI / build-ai-gateway (push) Failing after 28s
CI / build-ha-gateway (push) Failing after 24s
CI / build-discord-bot (push) Failing after 29s
Add TTS model components and inference server
- Implemented core model components in `modules.py` including various convolutional layers and normalization techniques.
- Added transformation functions in `transforms.py` for piecewise rational quadratic transformations.
- Created utility functions in `utils.py` for checkpoint management, logging, and hyperparameter handling.
- Introduced monotonic alignment functionality with Cython optimization in `monotonic_align`.
- Developed a minimal inference server in `server.py` to handle synthesis requests.
- Updated requirements to include necessary dependencies for Cython and scipy.
2026-07-24 22:38:36 +09:00

65 lines
2.0 KiB
Go

package grpc
import (
"context"
"errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
ttsv1 "gitea.nik4nao.com/nik/home-services/gen/tts/v1"
"gitea.nik4nao.com/nik/home-services/tts-gateway/internal/app"
"gitea.nik4nao.com/nik/home-services/tts-gateway/internal/core/domain"
"gitea.nik4nao.com/nik/home-services/tts-gateway/internal/core/ports/driving"
)
type TTSGRPC struct {
ttsv1.UnimplementedTTSServiceServer
svc driving.TTSService
}
// NewTTSGRPC constructs the gRPC adapter for TTSService.
func NewTTSGRPC(svc driving.TTSService) *TTSGRPC {
return &TTSGRPC{svc: svc}
}
// Synthesize translates a protobuf request into a domain call, applying
// uma-tts-api's sampling defaults for any knob the client omits.
func (h *TTSGRPC) Synthesize(ctx context.Context, req *ttsv1.SynthesizeRequest) (*ttsv1.SynthesizeResponse, error) {
params := domain.SynthesisParams{
NoiseScale: domain.DefaultNoiseScale,
NoiseScaleW: domain.DefaultNoiseScaleW,
LengthScale: domain.DefaultLengthScale,
}
if req.NoiseScale != nil {
params.NoiseScale = *req.NoiseScale
}
if req.NoiseScaleW != nil {
params.NoiseScaleW = *req.NoiseScaleW
}
if req.LengthScale != nil {
params.LengthScale = *req.LengthScale
}
clip, err := h.svc.Synthesize(ctx, req.SpeakerName, req.Text, params)
if err != nil {
return nil, grpcError(err)
}
return &ttsv1.SynthesizeResponse{Audio: clip.Data, MimeType: clip.MimeType}, nil
}
// ListSpeakers returns the (optionally filtered) speaker roster.
func (h *TTSGRPC) ListSpeakers(ctx context.Context, req *ttsv1.ListSpeakersRequest) (*ttsv1.ListSpeakersResponse, error) {
names := h.svc.ListSpeakers(ctx, req.Search)
return &ttsv1.ListSpeakersResponse{SpeakerNames: names}, nil
}
// grpcError maps domain errors to appropriate gRPC status codes, mirroring
// uma-tts-api's /synthesize 400 response for an unknown speaker name.
func grpcError(err error) error {
if errors.Is(err, app.ErrSpeakerNotFound) {
return status.Errorf(codes.InvalidArgument, "%v", err)
}
return status.Errorf(codes.Internal, "%v", err)
}