Welcome, Guest |
Qui si parla italiano
TOPIC:
Eseguire un file audio 04 Feb 2022 17:19 #21446
|
Salve a tutti, ho la necessità di allertare gli utenti con un messaggio sonoro (file audio) al verificarsi di un evento sul database MySQL. L'applicazione potrebbe essere iconizzata o addirittura non presidiata (l'utente potrebbe essere occupato nell'ufficio adiacente) C'è un modo per "eseguire" un file audio in background? Pensavo di utilizzare SELF:RegisterTimer(30, false) METHOD Timer() Vi ricordo che adopero X# nel dialetto VO Grazie a tutti Claudio |
Please Log in or Create an account to join the conversation. Last edit: by claudiocarletta. |
Eseguire un file audio 04 Feb 2022 17:43 #21449
Puoi usare la classe System.Speech.Synthesis.SpeechSynthesizer che ti permette di far parlare il tuo PC facendogli "leggere" una qualsiasi stringa con la velocità ed il volume che vuoi. Ho estratto da una mia applicazione quello che serve,spero di aver messo tutto, contattami se ho dimenticato qualcosa. Danilo FUNCTION Parla(cTesto AS STRING) AS VOID LOCAL _Lettura AS Lettura _Lettura := Lettura{} _Lettura:ImpostaVoce() _Lettura:Voce(cTesto,TRUE) _Lettura:ChiudiParlato() RETURN CLASS Lettura EXPORT oVoce AS System.Speech.Synthesis.SpeechSynthesizer EXPORT Nome_SV AS STRING EXPORT nVolume AS INT EXPORT nRate AS INT EXPORT Nome AS STRING EXPORT Attivo AS STRING METHOD ImpostaVoce() AS VOID LOCAL oXMLFile AS XML_File LOCAL cVolume,cRate AS STRING /* Microsoft Elsa Desktop - Italian (Italy) Microsoft Zira Desktop - English (United States) ScanSoft Silvia_Dri40_16kHz */ SELF:Nome_SV := "Microsoft Elsa Desktop" //"ScanSoft Silvia_Dri40_16kHz" SELF:nVolume := 100 SELF:nRate := -3 IF File(WorkDir()+"parla.xml") oXMLFile := XML_File{WorkDir()+"parla.xml"} IF oXMLFile:ExistSection("SET") SELF:Nome_SV := iif(!Empty(oXMLFile:GetEntry("SET","NOME")),oXMLFile:GetEntry("SET","NOME"),"ScanSoft Silvia_Dri40_16kHz") cVolume := iif(!Empty(oXMLFile:GetEntry("SET","VOLUME")),oXMLFile:GetEntry("SET","VOLUME"),"30") SELF:nVolume := Val(cVolume) cRate := iif(!Empty(oXMLFile:GetEntry("SET","RATE")),oXMLFile:GetEntry("SET","RATE"),"-3") SELF:nRate := Val(cRate) IF SELF:nRate > 10 SELF:nRate := 10 ENDIF IF SELF:nRate < -10 SELF:nRate := -10 ENDIF ENDIF ENDIF IF !Empty(SELF:Nome_SV) //Contiene il nome della Dll SELF:oVoce := System.Speech.Synthesis.SpeechSynthesizer{} SELF:oVoce:SelectVoice(SELF:Nome_SV) //Self:Nome_SV SELF:oVoce:SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.Female , System.Speech.Synthesis.VoiceAge.Adult) SELF:oVoce:Rate := SELF:nRate SELF:oVoce:Volume := SELF:nVolume //contiene il valore della variabile Self:nVolume: 0=nessun volume 30=medio basso // Voce("benvenuti nel programma di gestione del parlato",TRUE) ELSE SELF:oVoce := NULL_OBJECT ENDIF RETURN METHOD ScriviImpostaVoce() AS VOID LOCAL oXMLFile AS XML_File LOCAL oStream AS System.IO.StreamWriter LOCAL cTesto AS STRING LOCAL cSpazi AS STRING IF File(WorkDir()+"parla.xml") oXMLFile := XML_File{WorkDir()+"parla.xml"} oXMLFile:WriteEntry( "SET", "NOME",SELF:Nome_SV) oXMLFile:WriteEntry( "SET", "VOLUME",NTrim(SELF:nVolume)) oXMLFile:WriteEntry( "SET", "RATE",NTrim(SELF:nRate)) //oXMLFile:WriteEntry( "SET", "LINGUA",SELF:Lingua) oXMLFile:WriteEntry( "SET", "ATTIVO",SELF:Attivo) oXMLFile:Close() ELSE cSpazi := Space(2) cTesto := "<?xml version='1.0' encoding='utf-8' ?>"+CRLF cTesto += "<Configurazione>"+CRLF cTesto += cSpazi+"<SET>"+CRLF cSpazi := Space(4) cTesto += cSpazi+"<NOME>"+SELF:Nome_SV+"</NOME>"+CRLF cTesto += cSpazi+"<VOLUME>"+NTrim(SELF:nVolume)+"</VOLUME>"+CRLF cTesto += cSpazi+"<RATE>"+NTrim(SELF:nRate)+"</RATE>"+CRLF cTesto += cSpazi+"<ATTIVO>"+SELF:Attivo+"</ATTIVO>"+CRLF cSpazi := Space(2) cTesto += cSpazi+"</SET>"+CRLF cTesto += "</Configurazione>"+CRLF oStream := System.IO.StreamWriter{WorkDir()+"parla.xml"} oStream:Write(cTesto) oStream:Close() ENDIF RETURN METHOD ChiudiParlato() AS VOID //5) Per chiudere, quando esci dal programma: IF IsInstanceOf(SELF:oVoce,"SpeechSynthesizer") SELF:oVoce:Dispose() ENDIF RETURN METHOD Voce(cTesto AS STRING,lFlag := FALSE AS LOGIC) AS VOID IF IsInstanceOf(SELF:oVoce,"SpeechSynthesizer") IF lFlag SELF:oVoce:Speak(cTesto) //il programma si blocca fino alla fine della lettura del testo ELSE SELF:oVoce:SpeakAsync(cTesto) //Il programma continua l'esecuzione mentre parla ENDIF ENDIF RETURN METHOD Stop() AS VOID IF IsInstanceOf(SELF:oVoce,"SpeechSynthesizer") SELF:oVoce:Speak("") //il programma si blocca fino alla fine della lettura del testo ENDIF RETURN METHOD Avviso(cTesto AS STRING) AS VOID //Oppure la tua Mostra SELF:Voce(cTesto) //Viele letto il testo System.Windows.Forms.MessageBox.Show(cTesto,"Avviso",System.Windows.Forms.MessageBoxButtons.OK,System.Windows.Forms.MessageBoxIcon.Information) RETURN END CLASS #USING System.IO #USING System.Data #USING System.Windows.Forms CLASS XML_File PROTECT cFileXML AS STRING PROTECT oDataTable AS DataTable //La tabella corrente (il nodo e le variabili) PROTECT oDataSet AS DataSet //Contiene la struttura delfile XML //Tante tabelle quanti sono i nodi, tante colonne // quanto sono le variabili del nodo e tante //righe quanti sono i nodi ripetuti. PROTECT nNodi AS INT //Contiene il numero di tabelle lette dall'XML //Ogni nodo è una tabella PROTECT cSezione AS STRING // La tabella/il nodo corrente PROTECT cVariabile AS STRING PROTECT cValore AS STRING PROTECT aSezioni AS ARRAY //Contiene il nome delle tabelle e la posizione //nel DataSet PROTECT aColonne AS ARRAY //Contiene le colonne della tabella CONSTRUCTOR(cFile := "" AS STRING) IF ! Empty(cFile) IF File.Exists(cFile) SELF:cFileXML := cFile SELF:oDataSet := DataSet{} SELF:oDataSet:ReadXml(SELF:cFileXML) SELF:LeggiSezioni() SELF:GetSection(SELF:aSezioni[1,1]) ELSE MessageBox.Show("Attenzione, il file "+cFile+" non esiste." ,"Avviso",MessageBoxButtons.OK,MessageBoxIcon.Information) ENDIF ENDIF RETURN METHOD CreateFile(cFile AS STRING) AS VOID SELF:oDataSet := DataSet{} SELF:oDataSet:ReadXml(cFile) SELF:LeggiSezioni() SELF:GetSection(SELF:aSezioni[1,1]) RETURN METHOD CreateSection(cNomeSezione AS STRING,cNomeVariabile := "" AS STRING,cValore := "" AS STRING) AS VOID LOCAL oTable AS DataTable LOCAL oColonna AS System.Data.DataColumn LOCAL oDataRow AS DataRow IF ! Empty(cNomeSezione) .and. ! Empty(cNomeVariabile) oTable := DataTable{} oTable:TableName := Upper(cNomeSezione) oColonna := DataColumn{} oColonna:DataType := System.Type.GetType("System.String") oColonna:ColumnName := Upper(cNomeVariabile) oTable:Columns:Add(oColonna) oDataRow := oTable:NewRow() oDataRow[cNomeVariabile] := cValore oTable:Rows:Add(oDataRow) SELF:oDataSet:Tables:Add(oTable) SELF:LeggiSezioni() ENDIF RETURN METHOD DeleteSection(uNomeNodo AS USUAL) AS LOGIC LOCAL lOK := FALSE AS LOGIC LOCAL nPos AS INT LOCAL cNomeTabella AS STRING IF ValType(uNomeNodo) == "C" nPos := (INT) AScan(SELF:aSezioni,{|x| Upper(x[1]) == Upper(uNomeNodo)}) ELSEIF ValType(uNomeNodo) == "N" nPos := (INT) AScan(SELF:aSezioni,{|x| x[2] == uNomeNodo}) ENDIF IF nPos > 0 cNomeTabella := SELF:aSezioni[nPos,1] SELF:oDataSet:Tables:Remove(cNomeTabella) SELF:LeggiSezioni() lOK := TRUE ENDIF RETURN lOK METHOD CreateElement(cElemento AS STRING,cValore AS STRING,nPos := 0 AS INT) AS VOID LOCAL nCol AS INT SELF:oDataTable:Columns:Add(cElemento) nCol := SELF:oDataTable:Columns:Count -1 SELF:oDataTable:Rows[nPos]:Item[nCol] := cValore SELF:LeggiColonne(SELF:oDataTable) RETURN METHOD DeleteColumn(cSezione AS STRING, uElemento AS STRING) AS VOID LOCAL nPos AS INT SELF:GetSection(cSezione) nPos := (INT) AScan(SELF:aColonne,{|x| Upper(x[1]) == Upper(uElemento)}) IF nPos > 0 SELF:oDataTable:Columns:RemoveAt(nPos-1) SELF:LeggiColonne(SELF:oDataTable) SELF:SaveXML(SELF:cFileXML) ENDIF RETURN METHOD DeleteElement(uElemento AS USUAL) AS VOID LOCAL nPos AS INT IF ValType(uElemento) == "C" nPos := (INT) AScan(SELF:aColonne,{|x| Upper(x[1]) == Upper(uElemento)}) ELSEIF ValType(uElemento) == "N" nPos := (INT) AScan(SELF:aColonne,{|x| x[2] == uElemento}) ENDIF IF nPos > 0 SELF:oDataTable:Columns:RemoveAt(nPos-1) SELF:LeggiColonne(SELF:oDataTable) ENDIF RETURN METHOD DeleteValue(cNomeSezione AS STRING,cColonna AS STRING, cValore AS STRING) AS VOID LOCAL oDataView AS DataView LOCAL n AS INT SELF:GetSection(cNomeSezione) oDataView := DataView{SELF:oDataTable} oDataView:Sort := cColonna n := oDataView:Find(cValore) IF n <> -1 oDataView:Delete(n) ENDIF SELF:SaveXML(SELF:cFileXML) RETURN METHOD ExistSection(cNomeSezione AS STRING) AS LOGIC RETURN ((INT) AScan(SELF:aSezioni,{|x| Upper(x[1]) == Upper(cNomeSezione)})) > 0 METHOD GetNodi() AS INT RETURN SELF:nNodi METHOD GetEntry(cNomeSezione AS STRING,cNomeVariabile AS STRING) AS STRING LOCAL cValore AS STRING LOCAL nPos AS INT LOCAL oTable AS DataTable TRY cValore := "" IF ! Empty(cNomeSezione) .and. ! Empty(cNomeVariabile) IF (SELF:oDataTable:TableName == cNomeSezione) cValore := Convert.ToString(SELF:oDataTable:Rows[0]:Item[cNomeVariabile]) ELSE nPos := (INT) AScan(SELF:aSezioni,{|x| Upper(x[1]) == Upper(cNomeSezione)}) IF nPos > 0 oTable := SELF:oDataSet:Tables[nPos-1] IF SELF:oDataSet:Tables[nPos-1]:Columns:Contains(cNomeVariabile) cValore := Convert.ToString(oTable:Rows[0]:Item[cNomeVariabile]) ELSE cValore := "" ENDIF ENDIF ENDIF ENDIF CATCH cValore := "" END TRY RETURN cValore METHOD GetSection(uNomeNodo AS USUAL) AS DataTable LOCAL nPos AS INT SELF:oDataTable := DataTable{} IF ValType(uNomeNodo) == "C" nPos := (INT) AScan(SELF:aSezioni,{|x| Upper(x[1]) == Upper(uNomeNodo)}) ELSEIF ValType(uNomeNodo) == "N" nPos := (INT) AScan(SELF:aSezioni,{|x| x[2] == uNomeNodo}) ENDIF IF nPos > 0 SELF:oDataTable := SELF:oDataSet:Tables[nPos-1] SELF:LeggiColonne(SELF:oDataTable) ENDIF RETURN SELF:oDataTable METHOD GetArraySection(uNomeNodo AS USUAL) AS ARRAY LOCAL nCount,xx AS INT LOCAL aMat AS ARRAY SELF:GetSection(uNomeNodo) nCount := SELF:oDataTable:Columns:Count aMat := {} FOR xx := 0 UPTO nCount - 1 AAdd(aMat,{SELF:oDataTable:Columns[xx]:ColumnName,Convert.ToString(SELF:oDataTable:Rows[0]:Item[xx])}) NEXT RETURN aMat METHOD GetArraySectionColumnName(uNomeNodo AS USUAL,uNomeColonna AS USUAL) AS ARRAY LOCAL nCount,xx,nPos AS INT LOCAL aMat AS ARRAY SELF:GetSection(uNomeNodo) nCount := SELF:oDataTable:Rows:Count IF ValType(uNomeColonna) == "C" nPos := (INT) AScan(SELF:aColonne,{|x| Upper(x[1]) == Upper(uNomeColonna)}) ELSEIF ValType(uNomeColonna) == "N" nPos := (INT) AScan(SELF:aColonne,{|x| x[2] == uNomeColonna}) ENDIF aMat := {} IF nPos > 0 FOR xx := 0 UPTO nCount - 1 AAdd(aMat,{SELF:oDataTable:Columns[nPos-1]:ColumnName,Convert.ToString(SELF:oDataTable:Rows[xx]:Item[nPos-1])}) NEXT ENDIF RETURN aMat METHOD GetSections() AS ARRAY RETURN AClone(SELF:aSezioni) METHOD GetXML() AS STRING RETURN SELF:oDataSet:GetXML() METHOD InsRow(cNomeSezione AS STRING,cNomeVariabile AS STRING,cValore AS STRING) AS VOID LOCAL oRow AS DataRow LOCAL oDT AS DataTable oDT := SELF:GetSection(cNomeSezione) oRow := oDT:NewRow() oRow[cNomeVariabile] := cValore oDT:Rows:Add(oRow) SELF:oDataTable:AcceptChanges() SELF:oDataSet:AcceptChanges() SELF:oDataTable := oDT SELF:SaveXML() oRow := NULL_OBJECT RETURN PRIVATE METHOD LeggiSezioni() AS VOID LOCAL xx AS INT LOCAL cNomeTabella AS STRING SELF:nNodi := SELF:oDataSet:Tables:Count SELF:aSezioni := {} FOR xx := 0 UPTO SELF:nNodi-1 cNomeTabella := SELF:oDataSet:Tables[xx]:TableName AAdd(SELF:aSezioni,{cNomeTabella,xx}) NEXT SELF:oDataTable := SELF:oDataSet:Tables[0] SELF:LeggiColonne(SELF:oDataTable) RETURN PRIVATE METHOD LeggiColonne(oTable AS DataTable) AS VOID LOCAL nCol,xx AS INT nCol := oTable:Columns:Count SELF:aColonne := {} FOR xx := 0 UPTO nCol-1 AAdd(SELF:aColonne,{oTable:Columns[xx]:ColumnName,xx }) NEXT RETURN METHOD SaveXML(cFile := "" AS STRING) AS VOID IF ! Empty(cFile) SELF:oDataSet:WriteXml(cFile) ELSE SELF:oDataSet:WriteXml(SELF:cFileXML) ENDIF RETURN METHOD WriteEntry(cNomeSezione AS STRING,cNomeVariabile AS STRING,cValore AS STRING) AS VOID LOCAL nPos AS INT IF ! Empty(cNomeSezione) .and. ! Empty(cNomeVariabile) IF SELF:ExistSection(cNomeSezione) SELF:GetSection(cNomeSezione) IF (SELF:oDataTable:TableName == cNomeSezione) nPos := (INT) AScan(SELF:aColonne,{|x| Upper(x[1]) == Upper(cNomeVariabile)}) IF nPos > 0 SELF:oDataTable:Rows[0]:Item[nPos-1] := cValore ELSE SELF:CreateElement(Upper(cNomeVariabile),cValore) ENDIF ENDIF SELF:SaveXML() ELSE SELF:CreateSection(Upper(cNomeSezione),Upper(cNomeVariabile),cValore) SELF:SaveXML() ENDIF ENDIF RETURN METHOD Close() AS VOID SELF:oDataSet:Clear() SELF:oDataSet := NULL_OBJECT SELF:oDataTable:Clear() SELF:oDataTable := NULL_OBJECT SELF:aSezioni := {} SELF:aColonne := {} RETURN END CLASS |
Please Log in or Create an account to join the conversation. |
Eseguire un file audio 04 Feb 2022 17:48 #21450
|
Claudio, There's also the SoundPlayer class which can play sounds, but it has limited functionality and can only play .wav files: LOCAL oPlayer AS System.Media.SoundPlayer
oPlayer := System.Media.SoundPlayer{"C:\wav\Ring10.wav"}
oPlayer:Play() XSharp Development Team chris(at)xsharp.eu |
Please Log in or Create an account to join the conversation. |
Eseguire un file audio 04 Feb 2022 17:48 #21451
|
Claudio, Ho fatto una prova veloce dell'applicazione Vo StdMDI in XIDE, usando il metodo Timer nella shell, nessun problema. La variante più semplice potrebbe essere: METODO Timer() AS USUAL IF yourDBCheck_Alert() Tone(440,5) Tone(660,5) Tone(880,5) Tone(1000,5) ENDIF RETURN TRUE Regards Karl (X# 2.15.0.3; Xide 2.15; W8.1/64 German) |
Please Log in or Create an account to join the conversation. |
Eseguire un file audio 04 Feb 2022 17:57 #21452
|
Oppure, per essere un po' più fantasiosi, usate questo mio vecchio metodo di test come punto di partenza per farlo parlare: USING System.Speech.Synthesis USING System.Speech.AudioFormat USING System.IO FUNCTION EncodeNewNumbers(d AS STRING, val AS STRING ) AS LOGIC LOCAL oSAFI AS SpeechAudioFormatInfo oSAFI:=SpeechAudioFormatInfo{32000, AudioBitsPerSample.Sixteen, AudioChannel.Mono} LOCAL Synth AS SpeechSynthesizer Synth := SpeechSynthesizer{} LOCAL cEinleitung AS STRING cEinleitung:="Am" + d + " Dezember wurden folgende Nummern gezogen:" Synth:Speak(cEinleitung + val) /* FOREACH v AS System.Speech.Synthesis.InstalledVoice IN Synth:GetInstalledVoices() ? v:VoiceInfo:Name NEXT */ // Var 1 -> WAV File schreiben //Synth:SetOutputToWaveFile( cPath, oSAFI) RETURN TRUE Regards Karl (X# 2.15.0.3; Xide 2.15; W8.1/64 German) |
Please Log in or Create an account to join the conversation. |
Moderators: wriedmann