veus SAPI i OneCore (modernes)

Add-Type -AssemblyName System.Speech
$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
$synth.GetInstalledVoices() | Select-Object -ExpandProperty VoiceInfo | Select-Object Name, Culture

Name Culture
—- ——-
Microsoft Helena Desktop es-ES
Microsoft Hedda de-DE
Microsoft Katja de-DE
Microsoft Stefan de-DE
Microsoft George en-GB
Microsoft Hazel en-GB
Microsoft Susan en-GB
Microsoft David en-US
Microsoft Mark en-US
Microsoft Zira en-US
Microsoft Helena es-ES
Microsoft Laura es-ES
Microsoft Pablo es-ES
Microsoft Hedda Desktop de-DE
Microsoft Hazel Desktop en-GB
Microsoft David Desktop en-US
Microsoft Zira Desktop en-US
Microsoft Herena ca-ES


La diferència entre les veus SAPI i les OneCore (modernes) a Windows és força significativa, tant pel que fa a la tecnologia com a l’ús que se’n pot fer. Aquí tens un resum clar:


?️ Veus SAPI (Speech API)

CaracterísticaDetalls
? TecnologiaBasades en la interfície clàssica System.Speech.Synthesis
?️ CompatibilitatUtilitzades per aplicacions de Windows antigues o clàssiques
?️ Qualitat de veuMés robòtica o sintètica, menys natural
? Instal·lacióVe amb Windows o s’instal·la amb paquets específics
? Accés via PowerShellSystem.Speech.Synthesis.SpeechSynthesizer
? Ruta al registreHKLM:\SOFTWARE\Microsoft\SPEECH\Voices\Tokens

? Veus OneCore (Modernes)

CaracterísticaDetalls
? TecnologiaUtilitzen la nova API Windows.Media.SpeechSynthesis (UWP)
?️ CompatibilitatPensades per aplicacions modernes (UWP, apps de Windows 10/11)
?️ Qualitat de veuMés natural, algunes amb tecnologia neural TTS
? Instal·lacióEs descarreguen des de Configuració > Idioma > Opcions > Veu
? Accés via PowerShellCal accedir al registre o usar APIs modernes
? Ruta al registreHKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens

? Compatibilitat entre elles

  • Les veus SAPI poden ser utilitzades directament per moltes aplicacions clàssiques.
  • Les veus OneCore no són visibles per SAPI per defecte, però es poden exposar manualment (copiant claus del registre).
  • Algunes veus OneCore poden aparèixer a SAPI si el sistema les ha registrat correctament.

? En resum:

AspecteSAPIOneCore (Modernes)
QualitatSintèticaMés natural, algunes amb neural
CompatibilitatAplicacions clàssiquesAplicacions modernes (UWP)
Instal·lacióIncloses o via paquetsConfiguració de Windows
AccésFàcil via PowerShellMés complex, sovint via registre

Si vols, et puc ajudar a:

  • Fer que les veus OneCore funcionin amb aplicacions SAPI
  • Instal·lar veus noves (com en català, valencià, etc.)
  • Comparar la qualitat entre dues veus concretes

instal·la-veus-onecore.ps1

# Llengües que vols instal·lar
$Languages = @("ca-ES", "es-ES", "en-US", "en-GB", "fr-FR")

# Components de veu i reconeixement per a cada llengua
$CapabilitiesBase = @(
  "Language.Basic~~~{0}~0.0.1.0",
  "Language.Handwriting~~~{0}~0.0.1.0",
  "Language.Speech~~~{0}~0.0.1.0",
  "Language.TextToSpeech~~~{0}~0.0.1.0"
)

foreach ($lang in $Languages) {
    Write-Host "? Processant idioma: $lang" -ForegroundColor Cyan
    foreach ($capTemplate in $CapabilitiesBase) {
        $cap = [string]::Format($capTemplate, $lang)
        $capState = Get-WindowsCapability -Online -Name $cap -ErrorAction SilentlyContinue

        if ($capState -and $capState.State -eq "Installed") {
            Write-Host "✅ Ja instal·lat: $cap" -ForegroundColor Green
        }
        else {
            Write-Host "? Instal·lant: $cap" -ForegroundColor Yellow
            try {
                Add-WindowsCapability -Online -Name $cap -ErrorAction Stop
                Write-Host "✅ Instal·lat correctament: $cap" -ForegroundColor Green
            } catch {
                Write-Host "❌ Error instal·lant $cap: $_" -ForegroundColor Red
            }
        }
    }
    Write-Host "----------------------------`n"
}

Write-Host "? Quan acabi TOT, reinicia Windows manualment per activar les veus." -ForegroundColor Magenta

es-ES (Espanyol)

en-US (Anglès EUA)

en-GB (Anglès UK)

fr-FR (Francès)

ca-ES (Català)


? Com usar-lo

  1. Desa el contingut anterior com a fitxer:
    • Exemple: C:\tts\instal·la-veus-onecore.ps1
  2. Obre PowerShell com a administrador
  3. Executa:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
C:\tts\instal·la-veus-onecore.ps1

? Després de córrer-lo

  1. Reinicia l’ordinador
  2. Executa el teu script Python de detecció (Speech_OneCore) per veure les veus noves
  3. Ja podràs usar-les via Python o integració a la web

Publicat dins de Veus

? Test de veus SAPI i OneCore (tts)

C:\
├── tts\
|   ├──tts-to-wav.py       ← Script Python per generar l’àudio
│   ├── tts-to-wav.ps1     ← Script PowerShell per generar l’àudio
│   └── list-voices.ps1    ← Script PowerShell per llistar veus
└── AppServ\
    └── www\
        └── tts\
            ├── index.php    ← Interfície web
            └── tts.wav      ← Fitxer d’àudio generat

Index.php
--------

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Executa PowerShell per obtenir la llista de veus disponibles
$voiceListCmd = "powershell -ExecutionPolicy Bypass -File C:\\tts\\list-voices.ps1";
exec($voiceListCmd, $voices, $voiceStatus);

// Si falla, utilitza una llista per defecte
if ($voiceStatus !== 0 || empty($voices)) {
    $voices = [
        "SAPI5|Microsoft Helena Desktop",
        "SAPI5|Microsoft Hazel Desktop",
        "SAPI5|Microsoft Zira Desktop"
    ];
}else 
//-----------provisional fins la sol·lucio definitiva----
{
    // Afegim manualment Herena a OneCore (només si no està ja)
    $herena = "ONECORE|Microsoft Herena - Catalan (Catalan)";
    if (!in_array($herena, $voices)) {
        $voices[] = $herena;
    }
}
//------fi del provisional ❌ Error generant l’àudio.---
$text = $_GET['text'] ?? '';
$voice = $_GET['voice'] ?? $voices[0]; // ? AIXÒ ÉS ON TOCA
$audioFile = '/tts/tts.wav';

$audioTag = '';

if ($text) {
    $escapedText = escapeshellarg($text);
    $escapedVoice = escapeshellarg($voice);
    $escapedOutput = escapeshellarg(__DIR__ . DIRECTORY_SEPARATOR . 'tts.wav');


//$cmd = "powershell -ExecutionPolicy Bypass -File C:\\tts\\tts-to-wav.ps1 -text $escapedText -voiceName $escapedVoice -outputPath $escapedOutput";
    $cmd = "python C:\\tts\\tts-to-wav.py $escapedText $escapedVoice $escapedOutput";



    exec($cmd, $outputLines, $status);

    if ($status === 0 && file_exists(__DIR__ . '/tts.wav')) {
        $audioTag = "<audio controls autoplay style='margin-top:20px;'>
            <source src=\"$audioFile\" type=\"audio/wav\">
            El teu navegador no suporta àudio.
        </audio>";
    } else {
        $audioTag = "<p style='color:red;'>❌ Error generant l’àudio.</p>";
    }
}
?>

<!-- Interfície HTML -->
<!DOCTYPE html>
<html lang="ca">
<head>
    <meta charset="UTF-8">
    <title>Conversió TTS</title>
</head>
<body>
    <form method="get">
        <label for="text">Text:</label><br>
        <textarea name="text" rows="4" cols="50"><?= htmlspecialchars($text) ?></textarea><br><br>
        
        <label for="voice">Veu:</label>
        <select name="voice">
            <?php foreach ($voices as $v): ?>
                <option value="<?= htmlspecialchars($v) ?>" <?= $v === $voice ? 'selected' : '' ?>><?= htmlspecialchars($v) ?></option>
            <?php endforeach; ?>
        </select><br><br>

        <button type="submit">Generar àudio</button>
    </form>

    <?= $audioTag ?>
</body>
</html>

=========


 tts-to-wav.ps1 (usarem tts-to-wav.py)

param (
    [string]$text = "Hola món",
    [string]$voiceName,
    [string]$outputPath = "C:\tts\tts.wav"
)

try {
    if ($voiceName -like "ONECORE|*") {
        $realVoice = $voiceName.Substring(8)

        Add-Type -AssemblyName Windows.Media.SpeechSynthesis
        $synth = New-Object Windows.Media.SpeechSynthesis.SpeechSynthesizer

        $voice = $synth.AllVoices | Where-Object { $_.DisplayName -eq $realVoice }

        if (-not $voice) {
            Write-Error "Veu '$realVoice' no trobada a OneCore."
            exit 1
        }

        $synth.Voice = $voice

        $streamOp = $synth.SynthesizeTextToStreamAsync($text)
        $streamOp.Wait()
        $stream = $streamOp.GetResults()

        # Llegir el stream
        $reader = New-Object Windows.Storage.Streams.DataReader($stream)
        $reader.LoadAsync($stream.Size).AsTask().Wait()
        $data = New-Object byte[] $stream.Size
        $reader.ReadBytes($data)

        [System.IO.File]::WriteAllBytes($outputPath, $data)
    }
    elseif ($voiceName -like "SAPI5|*") {
        $realVoice = $voiceName.Substring(6)

        Add-Type -AssemblyName System.Speech
        $synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
        $synth.SelectVoice($realVoice)
        $synth.SetOutputToWaveFile($outputPath)
        $synth.Speak($text)
    }
    else {
        Write-Error "Format de veu desconegut: $voiceName"
        exit 1
    }
}
catch {
    Write-Error "Error inesperat: $_"
    exit 1
}
========================
tts-to-wav.py

import sys
import os
import pyttsx3

text = sys.argv[1]
voice_name = sys.argv[2]
output_path = sys.argv[3]

engine = pyttsx3.init()

# Buscar la veu exacta
found = False
for voice in engine.getProperty('voices'):
    if voice.name.strip() == voice_name.strip():
        engine.setProperty('voice', voice.id)
        found = True
        break

if not found:
    print(f"❌ Veu '{voice_name}' no trobada.")
    sys.exit(1)

engine.save_to_file(text, output_path)
engine.runAndWait()
print(f"✅ Àudio generat a {output_path}")

======================

list-voices.ps1

# Llista de veus SAPI5
Add-Type -AssemblyName System.Speech
$sapi = New-Object System.Speech.Synthesis.SpeechSynthesizer
$sapiVoices = $sapi.GetInstalledVoices() | ForEach-Object { $_.VoiceInfo.Name }

# Llista de veus OneCore
Add-Type -AssemblyName Windows.Media.SpeechSynthesis
$core = New-Object Windows.Media.SpeechSynthesis.SpeechSynthesizer
$coreVoices = $core.AllVoices | ForEach-Object { $_.DisplayName }

# Sortida combinada amb etiquetes
$sapiVoices | ForEach-Object { "SAPI5|$_" }
$coreVoices | ForEach-Object { "ONECORE|$_" }
Publicat dins de Veus

?️ Script PowerShell complet i robust per instal·lar veus OneCore

powershell:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
C:\tts\instal·la-veus-onecore.ps1

Idiomes i veus que vols instal·lar

$languageTags = @(
“en-US”, # English (US)
“en-GB”, # English (UK)
“es-ES”, # Spanish (Spain)
“ca-ES”, # Catalan (Spain)
“fr-FR”, # French (France)
“de-DE” # German
)

Obté la llista actual d’idiomes

$currentLangs = Get-WinUserLanguageList | ForEach-Object { $_.LanguageTag }

foreach ($lang in $languageTags) {
Write-Host “? Processant $lang…” -ForegroundColor Cyan
try {
# Afegeix l’idioma si no hi és
if (-not ($currentLangs -contains $lang)) {
Write-Host “➕ Afegint idioma $lang…”
$langList = Get-WinUserLanguageList
$langList.Add($lang)
Set-WinUserLanguageList $langList -Force
} else {
Write-Host “✔️ L’idioma $lang ja està instal·lat.”
}

    # Comprova si la veu bàsica ja està instal·lada
    $capability = "Language.$lang~Basic~~~"
    $installed = Get-WindowsCapability -Online | Where-Object { $_.Name -eq $capability }
    if ($installed.State -ne "Installed") {
        Write-Host "⬇️ Instal·lant veu bàsica per a $lang..."
        Add-WindowsCapability -Online -Name $capability -ErrorAction Stop
    } else {
        Write-Host "✔️ Veu bàsica ja instal·lada per a $lang."
    }

    # Instal·la reconeixement de veu si no hi és
    $speechCap = "Language.$lang~Speech~~~"
    $speechInstalled = Get-WindowsCapability -Online | Where-Object { $_.Name -eq $speechCap }
    if ($speechInstalled.State -ne "Installed") {
        Write-Host "?️ Instal·lant reconeixement de veu per a $lang..."
        Add-WindowsCapability -Online -Name $speechCap -ErrorAction SilentlyContinue
    } else {
        Write-Host "✔️ Reconeixement de veu ja instal·lat per a $lang."
    }

} catch {
   Write-Warning ("Error instal·lant per a $lang: " + $_.Exception.Message)

}

}

Mostra les veus disponibles al final

Write-Host “`n? Veus SAPI instal·lades:” -ForegroundColor Yellow
Add-Type -AssemblyName System.Speech
(New-Object System.Speech.Synthesis.SpeechSynthesizer).GetInstalledVoices() |
ForEach-Object { “• ” + $_.VoiceInfo.Name }

Publicat dins de Veus

Script PowerShell per instal·lar veus OneCore per idioma

Aquest script utilitza Add-WindowsCapability per instal·lar els paquets de veu oficials de Microsoft via DISM (eina integrada).

varificar la versió de powershell

$PSVersionTable.PSVersion
powershellCopiaModifica
# Idiomes i veus que vols instal·lar
$languageTags = @(
    "en-US",   # English (US)
    "en-GB",   # English (UK)
    "es-ES",   # Spanish (Spain)
    "ca-ES",   # Catalan (Spain)
    "fr-FR",   # French (France)
    "de-DE"    # German
)

foreach ($lang in $languageTags) {
    Write-Host "Instal·lant veu per a $lang..." -ForegroundColor Cyan
    try {
        # Instal·la la llengua si no existeix
        $langList = Get-WinUserLanguageList
        if (-not ($langList.LanguageTag -contains $lang)) {
            $langList.Add($lang)
            Set-WinUserLanguageList $langList -Force
        }

        # Instal·la la veu OneCore associada
        $capability = "Language.$lang~Basic~~~"
        Add-WindowsCapability -Online -Name $capability -ErrorAction Stop

        # Opcional: activa reconeixement de parla
        $speechCap = "Language.$lang~Speech~~~"
        Add-WindowsCapability -Online -Name $speechCap -ErrorAction SilentlyContinue
    }
    catch {
        Write-Warning "Error instal·lant per a $lang: $_"
    }
}

? Què fa aquest script?

✔️ Funciona amb PowerShell 5.x (Windows PowerShell): parcialment en 7

  • Afegeix l’idioma si cal.
  • Instal·la la veu (OneCore).
  • Intenta afegir també el reconeixement de veu (opcional).
  • Funciona en Windows 10 i 11, però cal accés d’administrador.

2. ? Comprova que les veus apareixen a OneCore:

Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens" | ForEach-Object {
    $keyPath = $_.PSPath
    $subkeys = Get-ChildItem -Path $keyPath -ErrorAction SilentlyContinue
    $displayName = $null

    foreach ($subkey in $subkeys) {
        $subProps = Get-ItemProperty -Path $subkey.PSPath -ErrorAction SilentlyContinue
        if ($subProps.DisplayName) {
            $displayName = $subProps.DisplayName
            break
        }
    }

    [PSCustomObject]@{
        VoiceId = $_.PSChildName
        Name    = $displayName
        Path    = $keyPath
    }
}

i a powerhshell

——- —- —-
MSTTS_V110_caES_Herena Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_deDE_HeddaM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_deDE_KatjaM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_deDE_StefanM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enGB_GeorgeM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enGB_HazelM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enGB_SusanM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enUS_DavidM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enUS_MarkM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_enUS_ZiraM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_esES_HelenaM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_esES_LauraM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…
MSTTS_V110_esES_PabloM Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCor…


veus clàssiques (SAPI5)

# Carrega la biblioteca TTS clàssica
Add-Type -AssemblyName System.Speech

# Crea un objecte per accedir al sintetitzador de veu
$voiceSynth = New-Object System.Speech.Synthesis.SpeechSynthesizer

# Obtenir totes les veus instal·lades
$voices = $voiceSynth.GetInstalledVoices()

# Mostra informació detallada de cada veu
foreach ($v in $voices) {
    [PSCustomObject]@{
        Name        = $v.VoiceInfo.Name
        Culture     = $v.VoiceInfo.Culture
        Gender      = $v.VoiceInfo.Gender
        Age         = $v.VoiceInfo.Age
        Description = $v.VoiceInfo.Description
        Attributes  = $v.VoiceInfo.OtherProperties
    }
}

PS C:\Users\urqte> # Carrega la biblioteca TTS clàssica
PS C:\Users\urqte> Add-Type -AssemblyName System.Speech
PS C:\Users\urqte>
PS C:\Users\urqte> # Crea un objecte per accedir al sintetitzador de veu
PS C:\Users\urqte> $voiceSynth = New-Object System.Speech.Synthesis.SpeechSynthesizer
PS C:\Users\urqte>
PS C:\Users\urqte> # Obtenir totes les veus instal·lades
PS C:\Users\urqte> $voices = $voiceSynth.GetInstalledVoices()
PS C:\Users\urqte>
PS C:\Users\urqte> # Mostra informació detallada de cada veu
PS C:\Users\urqte> foreach ($v in $voices) {

[PSCustomObject]@{
    Name        = $v.VoiceInfo.Name
    Culture     = $v.VoiceInfo.Culture
    Gender      = $v.VoiceInfo.Gender
    Age         = $v.VoiceInfo.Age
    Description = $v.VoiceInfo.Description
    Attributes  = $v.VoiceInfo.OtherProperties
}

}

1 Name : Microsoft Helena Desktop
Culture : es-ES
Gender : Female
Age : Adult
Description : Microsoft Helena Desktop – Spanish (Spain)
Attributes :

2 Name : Microsoft Hazel Desktop
Culture : en-GB
Gender : Female
Age : Adult
Description : Microsoft Hazel Desktop – English (Great Britain)
Attributes :

3 Name : Microsoft David Desktop
Culture : en-US
Gender : Male
Age : Adult
Description : Microsoft David Desktop – English (United States)
Attributes :

4 Name : Microsoft Zira Desktop
Culture : en-US
Gender : Female
Age : Adult
Description : Microsoft Zira Desktop – English (United States)
Attributes :

5 Name : Microsoft Hedda Desktop
Culture : de-DE
Gender : Female
Age : Adult
Description : Microsoft Hedda Desktop – German
Attributes :

6 Name : Vocalizer Expressive Jordi Harpo 22kHz
Culture : ca-ES
Gender : Male
Age : Adult
Description : Vocalizer Expressive Jordi Harpo 22kHz
Attributes :


Script PowerShell — Prova de veus SAPI (Desktop)

Add-Type -AssemblyName System.Speech
$tts = New-Object System.Speech.Synthesis.SpeechSynthesizer

$proves = @(
@{ Nom = “Microsoft Helena Desktop”; Missatge = “Hola! Esta es la voz española de Microsoft Helena.” },
@{ Nom = “Microsoft Hazel Desktop”; Missatge = “Hello! This is the British English voice of Microsoft Hazel.” },
@{ Nom = “Microsoft David Desktop”; Missatge = “Hi there! I’m Microsoft David, the American English voice.” },
@{ Nom = “Microsoft Zira Desktop”; Missatge = “Welcome! I am Zira, the female voice for American English.” },
@{ Nom = “Microsoft Hedda Desktop”; Missatge = “Hallo! Ich bin Hedda, die deutsche Stimme von Microsoft.” },
@{ Nom = “Vocalizer Expressive Jordi Harpo 22kHz”; Missatge = “Bon dia! Sóc en Jordi, la veu en català del sistema.” }
)

foreach ($prova in $proves) {
Write-Host “`n? Prova amb veu: $($prova.Nom)” -ForegroundColor Cyan
try {
$tts.SelectVoice($prova.Nom)
$tts.Speak($prova.Missatge)
} catch {
Write-Warning “⚠️ No s’ha pogut trobar o usar la veu: $($prova.Nom)”
}
}

Publicat dins de Veus

Veus disponibles

Script per mostrar noms visibles de totes les veus OneCore:

Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens" | ForEach-Object {
    $keyPath = $_.PSPath
    $voiceProps = Get-ItemProperty -Path $keyPath

    # Cerquem DisplayName dins dels subvalors (per exemple, en-US, es-ES...)
    $subkeys = Get-ChildItem -Path $keyPath -ErrorAction SilentlyContinue

    $displayName = $null

    foreach ($subkey in $subkeys) {
        $subProps = Get-ItemProperty -Path $subkey.PSPath -ErrorAction SilentlyContinue
        if ($subProps.DisplayName) {
            $displayName = $subProps.DisplayName
            break
        }
    }

    [PSCustomObject]@{
        VoiceId = $_.PSChildName
        Name    = $displayName
        Path    = $keyPath
    }
}

PS C:\WINDOWS\system32> Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens" | ForEach-Object {
>>     $keyPath = $_.PSPath
>>     $voiceProps = Get-ItemProperty -Path $keyPath
>>
>>     # Cerquem DisplayName dins dels subvalors (per exemple, en-US, es-ES...)
>>     $subkeys = Get-ChildItem -Path $keyPath -ErrorAction SilentlyContinue
>>
>>     $displayName = $null
>>
>>     foreach ($subkey in $subkeys) {
>>         $subProps = Get-ItemProperty -Path $subkey.PSPath -ErrorAction SilentlyContinue
>>         if ($subProps.DisplayName) {
>>             $displayName = $subProps.DisplayName
>>             break
>>         }
>>     }
>>
>>     [PSCustomObject]@{
>>         VoiceId = $_.PSChildName
>>         Name    = $displayName
>>         Path    = $keyPath
>>     }
>> }

VoiceId                 Name Path
-------                 ---- ----
MSTTS_V110_caES_Herena       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_caES_Herena
MSTTS_V110_deDE_HeddaM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_deDE_HeddaM
MSTTS_V110_deDE_KatjaM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_deDE_KatjaM
MSTTS_V110_deDE_StefanM      Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_deDE_StefanM
MSTTS_V110_enGB_GeorgeM      Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enGB_GeorgeM
MSTTS_V110_enGB_HazelM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enGB_HazelM
MSTTS_V110_enGB_SusanM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enGB_SusanM
MSTTS_V110_enUS_DavidM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enUS_DavidM
MSTTS_V110_enUS_MarkM        Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enUS_MarkM
MSTTS_V110_enUS_ZiraM        Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_enUS_ZiraM
MSTTS_V110_esES_HelenaM      Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_esES_HelenaM
MSTTS_V110_esES_LauraM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_esES_LauraM
MSTTS_V110_esES_PabloM       Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\MSTTS_V110_esES_PabloM


PS C:\WINDOWS\system32>

Add-Type -AssemblyName System.Speech
$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
$synth.GetInstalledVoices() | ForEach-Object {
    $_.VoiceInfo.Name
}

? 4. (Opcional) Llistar també les veus modernes (OneCore)

Aquestes veus (com Microsoft Aria, Microsoft Jenny) no apareixen amb System.Speech, però pots veure-les així:

powershellCopiaModificaGet-ChildItem "HKLM:\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens" | ForEach-Object {
    $_.GetValue("")
}

sadsd

profile

Qwen3-235B-A22B

Perfecte! ?

Les veus que veus són les veus TTS (Text-to-Speech) instal·lades al teu Windows 11. I sí, les mantindras de forma estable al sistema sempre que no les desinstal·lis o restableixis el sistema a valors d’origen.


✅ Què vol dir això?

Les veus que tens actualment:

Microsoft Hazel Desktopen-GBFemeníAnglès del Regne Unit
Microsoft David Desktopen-USMasculíAnglès dels EUA
Microsoft Zira Desktopen-USFemeníAnglès dels EUA
Microsoft Hedda Desktopde-DEFemeníAlemany
Vocalizer Expressive Jordi Harpoca-ESMasculíCatalà (amb motor de tercers)

? Aquestes veus són compatibles amb l’API clàssica (System.Speech.Synthesis) i poden ser utilitzades per programes com Narrador, Cortana, PowerShell, etc.


? Seran estables? Sí ?

Publicat dins de Veus

Canviar [audio mp3=”http://192.168.1.140 a [audio mp3=”https://192.168.1.140

mp3=”http://192.168.1.140/english_note/wp-content/uploads/2016/03/3.44.mp3″][/audio]

mp3=”https://192.168.1.140/english_note/wp-content/uploads/2016/03/3.44.mp3″][/audio]

OPCIÓ 2: Consulta SQL directa (avançat)

appMyAdmin/ Base de dades: eng/SQL

UPDATE wp_posts
SET post_content = REPLACE(post_content, '[audio mp3="http://192.168.1.140', '[audio mp3="https://192.168.1.140')
WHERE post_content LIKE '%[audio mp3="http://192.168.1.140%';

Renovar urquizu.info Certificat SSL amb RapidSSLonline

1. Accedeix al servidor via SSH

ssh usuari@ip_del_servidor

Warning: Data should only be stored in shared folders. Data stored elsewhere
may be deleted when the system is updated/restarted.

urqtejmi@syn_beseit:~$

2. Navega fins a la carpeta o bé indica la ruta completa

Si vols estar dins del directori on es troba la clau:

cd /volume1/web/csr/

urqtejmi@syn_beseit:~$ cd /volume1/web/csr/
urqtejmi@syn_beseit:/volume1/web/csr$ dir
total 8
drwxrwxrwx+ 1 urqtejmi users 52 Jun 28 12:46 .
drwxrwxrwx+ 1 root root 5170 Jun 28 14:04 ..
-rwxrwxrwx+ 1 urqtejmi users 1704 Jul 24 2024 server.key
-rwxrwxrwx+ 1 urqtejmi users 2230 Jul 24 2024 urquizu_info.crt
urqtejmi@syn_beseit:/volume1/web/csr$

? 3. Genera el CSR utilitzant la clau privada existent

openssl req -new -key server.key -out server.csr

urqtejmi@syn_beseit:/volume1/web/csr$ openssl req -new -key server.key -out server.csr
Can’t load /var/services/homes/urqtejmi/.rnd into RNG
139961559664448:error:2406F079:random number generator:RAND_load_file:Cannot open file:crypto/rand/randfile.c:98:Filename=/var/services/homes/urqtejmi/.rnd
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,

If you enter ‘.’, the field will be left blank.

Country Name (2 letter code) [TW]:—>ES, TE, Beceite,

Organization Name (eg, company) [Synology Inc.]:MUT

Organizational Unit Name (eg, section) []:

Common Name (e.g. server FQDN or YOUR name) []:urquizu.info

Email Address [product@synology.com]:urqtejmi@gmail.com

Please enter the following ‘extra’ attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:

urqtejmi@synology_vall:~$

urqtejmi@syn_beseit:/volume1/web/csr$ dir
total 12
drwxrwxrwx+ 1 urqtejmi users   72 Jun 28 17:57 .
drwxrwxrwx+ 1 root     root  5170 Jun 28 14:04 ..
-rwxrwxrwx+ 1 urqtejmi users 1021 Jun 28 17:57 server.csr
-rwxrwxrwx+ 1 urqtejmi users 1704 Jul 24  2024 server.key
-rwxrwxrwx+ 1 urqtejmi users 2230 Jul 24  2024 urquizu_info.crt
urqtejmi@syn_beseit:/volume1/web/csr$

FITXERTIPUSPROPOSIT
server.keyClau privadaNo es comparteix mai. És necessària per desxifrar connexions.
server.csrSol·licitud de certificatCertificat públic
Es lliura a la CA per obtenir un certificat signat.
server.crtCertificat públicÉs retornat per la CA. Es fa servir amb la clau privada per activar HTTPS.

SMB carpeta www i altres a el ‘Meu ordinador”

El servei SMB Service de Synology és el que et permet veure carpetes del teu NAS (com WWW) com si fossin carpetes locals al teu Windows 11, dins de l’apartat “Aquest ordinador”.

Perquè això funcioni correctament, cal:

  1. Tenir activat el servei SMB al teu NAS (a Panell de control > Serveis de fitxers > SMB/AFP/NFS).
  2. Que la carpeta WWW estigui compartida a través de File Station amb permisos adequats.
  3. Que al Windows, vagis a l’Explorador d’arxius i escriguis \\nom_del_tu_nas\WWW a la barra d’adreces — o mapejar-la com a unitat de xarxa perquè sempre hi tinguis accés fàcil.

A més, com que la carpeta WWW normalment forma part d’un entorn web, és habitual usar-la conjuntament amb paquets com Web Station, phpMyAdmin o WordPress — i és aquí on SMB et facilita accedir-hi des de qualsevol ordinador.

Moon+ Reader

All Boocs: /sdcsr/Books+(2) /sdcsr/Books/moonReader(3)+ /sdcsr/Books/moonReader/Cloud (1)/sdcard/download (1)-> total 7

L’he trobat molt interessant perquè té la seva llibreria local (Prestatge)

també es pot llegir directament a calibre