Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ func Import(jsonString string) error {
return err
}

manager.lock.Lock()
defer manager.lock.Unlock()

manager.config = newConfig

updatedConfigs, err := json.MarshalIndent(manager.config, "", "\t")
Expand All @@ -139,22 +142,50 @@ func Import(jsonString string) error {
}

func Get() Base {
return manager.config
manager.lock.RLock()
defer manager.lock.RUnlock()

base := manager.config
base.ModelToggles = copyModelToggles(manager.config.ModelToggles)
return base
}

func GetSettings() Settings {
manager.lock.RLock()
defer manager.lock.RUnlock()

return manager.config.Settings
}

func GetEngine() Engine {
manager.lock.RLock()
defer manager.lock.RUnlock()

return manager.config.Engine
}

func GetModelToggles() map[string]bool {
return manager.config.ModelToggles
manager.lock.RLock()
defer manager.lock.RUnlock()

return copyModelToggles(manager.config.ModelToggles)
}

func copyModelToggles(source map[string]bool) map[string]bool {
if source == nil {
return nil
}
dst := make(map[string]bool, len(source))
for key, value := range source {
dst[key] = value
}
return dst
}

func GetEngineToggles() map[string]map[string]bool {
manager.lock.RLock()
defer manager.lock.RUnlock()

engineToggles := make(map[string]map[string]bool)

for key, value := range manager.config.ModelToggles {
Expand All @@ -176,6 +207,9 @@ func GetEngineToggles() map[string]map[string]bool {
}

func GetInfo() Info {
manager.lock.RLock()
defer manager.lock.RUnlock()

return manager.config.Info
}

Expand All @@ -185,6 +219,9 @@ func GetValueFromPath(path string) (interface{}, error) {
return nil, fmt.Errorf("Invalid path")
}

manager.lock.RLock()
defer manager.lock.RUnlock()

current := reflect.ValueOf(manager.config)

for _, part := range parts {
Expand Down
6 changes: 3 additions & 3 deletions app/config/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (

type ConfigManager struct {
//defaults map[string]Value `json:"defaults"`
config Base `json:"defaults"`
filePath string `json:"filePath"`
lock sync.Mutex `json:"lock"`
config Base `json:"defaults"`
filePath string `json:"filePath"`
lock sync.RWMutex `json:"lock"`
}

type Base struct {
Expand Down
50 changes: 39 additions & 11 deletions app/tts/modelManager/modelManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,18 @@ func restartEngine(engineName string) {
}

func restartLocalEngines() {
manager.Lock()
defer manager.Unlock()

manager.RLock()
var localEngineIDs []string
for engineID, entry := range manager.Engines {
if entry.Engine.Type == tts.Local {
manager.Unlock()
restartEngine(engineID)
manager.Lock()
localEngineIDs = append(localEngineIDs, engineID)
}
}
manager.RUnlock()

for _, engineID := range localEngineIDs {
restartEngine(engineID)
}
}

func createModelPool(engineID, modelID string) (*ModelPool, error) {
Expand Down Expand Up @@ -368,7 +370,10 @@ func GetEngineInstance(engineID, modelID string) (tts.Base, func(), bool) {
}

// Model exists but has no pool (not enabled in toggles). Create one on demand.
if _, modelExists := entry.Engine.Models[modelID]; modelExists {
manager.RLock()
_, modelExists := entry.Engine.Models[modelID]
manager.RUnlock()
if modelExists {
manager.Lock()
// Double-check after acquiring write lock
if existingPool, exists := entry.Models[modelID]; exists {
Expand Down Expand Up @@ -400,6 +405,9 @@ func GetAllEngines() []tts.Engine {
toggles := config.GetEngineToggles()
var availableEngines []tts.Engine

manager.RLock()
defer manager.RUnlock()

for engineID, entry := range manager.Engines {
filteredEngine := tts.Engine{
ID: engineID,
Expand Down Expand Up @@ -477,6 +485,9 @@ func GetActiveEngines() []tts.Engine {
func GetAllModels() map[string]tts.Model {
result := make(map[string]tts.Model)

manager.RLock()
defer manager.RUnlock()

for _, entry := range manager.Engines {
for _, model := range entry.Engine.Models {
result[model.Engine+":"+model.ID] = model
Expand All @@ -487,25 +498,42 @@ func GetAllModels() map[string]tts.Model {
}

func GetModelVoices(engineName string, modelID string) ([]tts.Voice, error) {
manager.RLock()
selectedEngine, exists := manager.Engines[engineName]

if !exists {
manager.RUnlock()
return nil, response.Err(fmt.Errorf("Engine %s not found", engineName))
}

var instance tts.Base
if modelPool, modelExists := selectedEngine.Models[modelID]; modelExists && len(modelPool.Instances) > 0 {
return modelPool.Instances[0].GetVoices(modelID)
instance = modelPool.Instances[0]
}

var fallbackEngine tts.Base
if instance == nil {
if _, modelExists := selectedEngine.Engine.Models[modelID]; modelExists {
fallbackEngine = selectedEngine.Engine.Engine
}
}
manager.RUnlock()

if instance != nil {
return instance.GetVoices(modelID)
}

// Fall back to the engine directly (handles models not yet pooled/enabled)
if _, modelExists := selectedEngine.Engine.Models[modelID]; modelExists {
return selectedEngine.Engine.Engine.GetVoices(modelID)
if fallbackEngine != nil {
return fallbackEngine.GetVoices(modelID)
}

return nil, response.Err(fmt.Errorf("Model %s not found for engine %s", modelID, engineName))
}

func GetInstanceCount(engineID string, modelID string) int {
manager.RLock()
defer manager.RUnlock()

if selectedEngine, exists := manager.Engines[engineID]; exists {
if modelPool, modelExists := selectedEngine.Models[modelID]; modelExists {
return len(modelPool.Instances)
Expand Down
2 changes: 2 additions & 0 deletions app/tts/modelManager/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ type EngineEntry struct {
}

func (entry *EngineEntry) GetModelInstance(modelID string) (tts.Base, *ModelPool, bool) {
manager.RLock()
pool, exists := entry.Models[modelID]
manager.RUnlock()
if !exists {
return nil, nil, false
}
Expand Down