- 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.
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
// Package ffmpeg implements driven.AudioEncoder: WAV framing done by hand,
|
|
// then a shell-out to the system ffmpeg binary to transcode to AAC/M4A,
|
|
// matching uma-tts-api's pydub `.export(..., format="ipod")` step
|
|
// (mimetype audio/aac, despite the "ipod" format name being an M4A/AAC
|
|
// container alias).
|
|
package ffmpeg
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
)
|
|
|
|
type Encoder struct{}
|
|
|
|
func NewEncoder() *Encoder {
|
|
return &Encoder{}
|
|
}
|
|
|
|
// Encode transcodes PCM samples to AAC. The output goes to a temp file
|
|
// rather than a stdout pipe because the M4A/MP4 muxer needs a seekable
|
|
// destination to write its moov atom.
|
|
func (e *Encoder) Encode(ctx context.Context, pcm []float32, sampleRate int) ([]byte, string, error) {
|
|
wavBytes := encodeWAV(pcm, sampleRate)
|
|
|
|
tmpFile, err := os.CreateTemp("", "tts-gateway-*.m4a")
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("ffmpeg: create temp output file: %w", err)
|
|
}
|
|
tmpPath := tmpFile.Name()
|
|
_ = tmpFile.Close()
|
|
defer os.Remove(tmpPath)
|
|
|
|
cmd := exec.CommandContext(ctx, "ffmpeg",
|
|
"-y",
|
|
"-f", "wav", "-i", "pipe:0",
|
|
"-f", "ipod",
|
|
tmpPath,
|
|
)
|
|
cmd.Stdin = bytes.NewReader(wavBytes)
|
|
var stderr bytes.Buffer
|
|
cmd.Stderr = &stderr
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return nil, "", fmt.Errorf("ffmpeg: transcode failed: %w: %s", err, stderr.String())
|
|
}
|
|
|
|
data, err := os.ReadFile(tmpPath)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("ffmpeg: read transcoded output: %w", err)
|
|
}
|
|
return data, "audio/aac", nil
|
|
}
|