SpVoice mit Bass.dll abfangen

  • Hey @ all,
    in Windows gibt es ja die Microsoft Speech API, mit der man einen Text "abspielen" lassen kann.
    Das geht ungefähr so:

    Spoiler anzeigen
    [autoit]

    Global $voice = ObjCreate("Sapi.SpVoice")
    Speak("This is a test!", 0.75, 100)
    Func Speak($Text, $Rate, $Vol)
    $voice.Rate = $Rate
    $voice.Priority = 0
    $voice.Volume = $Vol
    $voice.Speak ($Text)
    EndFunc

    [/autoit]


    Jetzt frag ich mich, wie ich das ganze in eine Audiodatei bekomme, bzw in einem Bass-Mixer benutzen könnte. Bisher habe ich HIER ein paar Informationen gefunden. Bis jetzt bin ich noch nicht auf eine Funktion gestoßen, die mir irgendwelche Daten zurückgeben könnte, die man mit der Bass.dll nutzen kann. Kennt jemand eine Lösung hierzu?

    mfG Developer30

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."

    Einmal editiert, zuletzt von Developer30 (10. November 2010 um 13:28)

  • bitteschön:

    Spoiler anzeigen
    [autoit]

    #include "Bass.au3"

    [/autoit] [autoit][/autoit] [autoit]

    _SpeakToWAV("speak to wav file", @ScriptDir & "\Output.wav")

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Startup()
    _BASS_Init(0, -1, 44100, 0, "")
    _SpeakToStream("speak to bass memory stream")
    _BASS_Free()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _SpeakToWAV($sText, $sFile)
    Local $oVoice = ObjCreate("Sapi.SpVoice")
    Local $oFileStream = ObjCreate("SAPI.SpFileStream.1")
    $oFileStream.Open($sFile, 3)
    $oVoice.AudioOutputStream = $oFileStream
    $oVoice.Speak($sText)
    EndFunc ;==>_SpeakToWAV

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _SpeakToStream($sText, $iTimeout = 10000)
    Local $oVoice = ObjCreate("Sapi.SpVoice")
    Local $oMemStream = ObjCreate("SAPI.SpMemoryStream.1")
    $oVoice.AudioOutputStream = $oMemStream
    $oVoice.Speak($sText)
    $oVoice.WaitUntilDone($iTimeout)

    [/autoit] [autoit][/autoit] [autoit]

    Local $bData = $oMemStream.GetData()
    Local $iSize = BinaryLen($bData)
    Local $tData = DllStructCreate("byte[" & $iSize & "]")
    DllStructSetData($tData, 1, $bData)

    [/autoit] [autoit][/autoit] [autoit]

    Local $hStream = _BASS_StreamCreate(22050, 1, 0, $STREAMPROC_PUSH)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_ChannelPlay($hStream, True)
    _BASS_StreamPutData($hStream, DllStructGetPtr($tData), $iSize)
    Sleep(_BASS_ChannelBytes2Seconds($hStream, $iSize) * 1000)
    _BASS_StreamFree($hStream)
    EndFunc ;==>_SpeakToStream

    [/autoit]

    mfgE

    Edit:
    Wenn man den Sampledaten noch einen Wav-Header hinzufügt, kann man einen "normalen" Stream daraus erstellen.

    Spoiler anzeigen
    [autoit]

    #include "Bass.au3"
    ;#include "BassExt.au3"

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_Startup()
    _BASS_Init(0, -1, 44100, 0, "")

    [/autoit] [autoit][/autoit] [autoit]

    $tWave = _BASS_EXT_SpVoice2Memory("this is a test")
    $hStream = _BASS_StreamCreateFile(True, DllStructGetPtr($tWave), 0, DllStructGetData($tWave, "Len"), 0)

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_ChannelPlay($hStream, True)

    [/autoit] [autoit][/autoit] [autoit]

    While _BASS_ChannelIsActive($hStream)
    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    _BASS_StreamFree($hStream)
    _BASS_Free()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _BASS_EXT_SpVoice2Memory($sText, $iRate = 0, $iVolume = 100)
    Local $oVoice = ObjCreate("Sapi.SpVoice")
    If @error Or Not IsObj($oVoice) Then Return SetError(1, 1, 0)

    [/autoit] [autoit][/autoit] [autoit]

    Local $oMemStream = ObjCreate("SAPI.SpMemoryStream.1")
    If @error Or Not IsObj($oVoice) Then Return SetError(1, 2, 0)
    Local $vSpAudioFormat = $oMemStream.Format
    $vSpAudioFormat.Type = 0x00000023

    [/autoit] [autoit][/autoit] [autoit]

    $oVoice.AudioOutputStream = $oMemStream
    $oVoice.Rate = $iRate
    $oVoice.Volume = $iVolume

    [/autoit] [autoit][/autoit] [autoit]

    $oVoice.Speak($sText)

    [/autoit] [autoit][/autoit] [autoit]

    Local $bData = $oMemStream.GetData()
    Local $iSize = BinaryLen($bData)
    If $iSize <= 0 Then Return SetError(1, 2, 0)

    [/autoit] [autoit][/autoit] [autoit]

    Local $tWave = DllStructCreate("char RIFF [4];uint FileSize;char WAVE [4];char fmt [4];uint fmt_len;word Format;word Channels;uint Samplerate;uint Bytes;word Block;word BitsPerSample;char DATA [4];uint Len;byte WAVDATA[" & $iSize & "]")
    DllStructSetData($tWave, "RIFF", "RIFF")
    DllStructSetData($tWave, "FileSize", $iSize + 44 - 8)
    DllStructSetData($tWave, "WAVE", "WAVE")
    DllStructSetData($tWave, "fmt", "fmt ")
    DllStructSetData($tWave, "fmt_len", 16)
    DllStructSetData($tWave, "Format", 1)
    DllStructSetData($tWave, "Channels", 2)
    DllStructSetData($tWave, "Samplerate", 44100)
    DllStructSetData($tWave, "Bytes", 176400)
    DllStructSetData($tWave, "Block", 4)
    DllStructSetData($tWave, "BitsPerSample", 16)
    DllStructSetData($tWave, "DATA", "data")
    DllStructSetData($tWave, "Len", $iSize)
    DllStructSetData($tWave, "WAVDATA", $bData)

    [/autoit] [autoit][/autoit] [autoit]

    Return SetError(0, $iSize, $tWave)
    EndFunc ;==>_BASS_EXT_SpVoice2Memory

    [/autoit]
  • echt genial :thumbup:
    thx

    "Je mehr Käse, desto mehr Löcher; je mehr Löcher, desto weniger Käse. Ergo: Je mehr Käse, desto weniger Käse. 8| "
    "Programmers never die: they just GOSUB without RETURN"
    "I tried to change the world but I couldn't find the source code."