CFD Voice Input/ Routing

Sieht interessant aus. Mir ist aber nicht ersichtlich, wie die Audiofiles gepickt werden. Bei 1to3 steigt es bei mir aus, weil ich ja nun an den 0-9 "Sekundentakt" denke!
Die C# Funktion liefert einen 'zufälligen' String mit Inhalt "1", "2" oder "3" zurück, evtl. immer mal einen anderen. Der Dynamic Audio File Prompt nimmt den Standard Audio Dateipfad dieses (deines) CFD Projektes in deiner 3CX, hängt ein "/" + den Namen der Datei + den Rückgabewert der 'Zufallsfunktion' + die Endung ".wav" an und fertig. Nix mit Sekunden. Das wechselt evtl. bei jedem Aufruf. Manchmal ist es eben auch gleich, sind halt nur 3 Möglichkeiten. Wenn mehr gewünscht sind, dann im C# Schnipsel die Zahl erhöhen und mehr entspr. benannte Audio Dateien (Achtung wg. Groß- und Kleinschreibung) in das CFD Projekt hochladen.

Schau dir mal das Bild des 3CXCallFlow.log an, die letzte Zeile. Das wird ausgeführt - wenn die Datei denn da ist.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: ciscoX
Ach sooo, jetzt leuchtet es ein! Ich belasse es aber vorerst so. Hätte ich mehr als 3 Audiodateien, würde es Sinn machen, aber in diesem Fall finde ich die vorherige Lösung für mich übersichtlicher.
 
  • Like
Reaktionen: fxbastler
aber in diesem Fall finde ich die vorherige Lösung für mich übersichtlicher.
Naja, es verschlingt ohne Ende Platz im CFD in der Ansicht und das geklicker beim Bauen würde mich nerven. Das mit dem Rand ist eleganter. Aber wie du willst. Es gibt viele Wege nach Rom.
 
Nee, ich kann's doch einklappen, dann sehe ich nur "Freizeichen":
 

Anhänge

  • Foto4.png
    Foto4.png
    233,5 KB · Aufrufe: 5
Nein, es ist doch alles beschriftet.
 
Das wiederum finde ich gefährlich. Dann sucht man irgendwann etwas und findet es nicht.
Die Elemente werden so oder so nach jedem Neustart des CFDs neu ausgeklappt und komplett angezeigt. Teilweise echt nervig.

@CISCOX: @fxbastler's Idee mit dem Zufallsgen via Rand im C# ist die Beste und einfachste für das was du vor hast.

Alternativ könntest du auch mit einer Variablen arbeiten die ein Global Property liest, schreibt und immer im Kreis plus 1 setzt bzw. beim Überschreiten von X, die Zahl zurücksetzt. So hast du bei jedem Anruf ein anderes Audio und minimierst das Risiko das Rand dir jedes mal das selbe Audio zurückgibt.
 
  • Like
  • Love
Reaktionen: ciscoX und fxbastler
Das klingt genau nach dem, was ich möchte. Wie kann ich das umsetzen? Kannst du mir da ein Beispiel zeigen?
 
Ersatzantwort:

Man benutzt eine globale Variable der 3CX (einen 3CX Parameter mit einem Namen der noch nicht benutzt wird, z.B. CFAVAR), schreibt da eine Zahl rein, erhöht mit jedem Aufruf der CFA diesen Zähler (bzw. setzt ihn zurück wenn das Ende erreicht ist) und benutzt diese Variable zum Erzeugen des Dateinamen und damit zum Abspielen einer dazu gehörigen Datei.

In der CFA:
  1. im CFD Projekt eine Variable definieren (rechtsklick oben rechts auf den Namen des Projekts, Variables, Sammlung, eine hinzufügen, z.B. eine Projektvariable mit Namen PROJEKTVAR
  2. CFD Block 1: Get Global Property (den Namen der globalen 3CX Variablen / Parameter hier verwenden, CFAVAR), den 3CX PArameter lesen
  3. CFD Block 2: Assign a Variable, den Namen der Projektvariablen angeben (PROJEKTVAR), den Wert der gelesenen 3CX Variablen zuweisen (CFAVAR)
  4. CFD Block 3: Increment Variable, die Projektvariable (PROJEKTVAR) um eins erhöhen
  5. CFD Block 4: Create a Condition, wenn Wert der Projektvariablen (PROJEKTVAR) zu hoch ist (z.B. 4,
    GREAT_THAN(project$.PROJEKTVAR,"3")) dann mit Assign a Variable den Wert der Projektvariablen (PROJEKTVAR) auf den Startwert (1) zurücksetzen, das ist quasi die Schleife in der von 1 bis 3 gezählt wird
  6. CFD Block 5: Set Global Property (den Namen der globalen 3CX Variablen / Parameter hier verwenden, CFAVAR) und dieser den Wert der Projektvariablen (PROJEKTVAR) zuweisen, damit wird der Wert wieder in der 3CX gespeichert
  7. die Audio Datei abspielen, der Dateiname wird ähnlich gebildet wie hier im Bild 2, nur wird der Wert der Projektvariablen PROJEKTVAR genutzt, der lautet dann CONCATENATE(session.audioFolder,"/Audiofile",project$.PROJEKTVAR,".wav")
Die Schritte 1 bis 7 kann man auch komplett mit einem C# Schnipsel realisieren, das übersteigt evtl. dein Verständnis, daher von Hand zu Fuss mit einzelnen originalen CFD Blöcken wie @patrickb es beschrieben hat.
 
  • Like
Reaktionen: ciscoX und patrickb
Ersatzantwort:

Man benutzt eine globale Variable der 3CX (einen 3CX Parameter mit einem Namen der noch nicht benutzt wird, z.B. CFAVAR), schreibt da eine Zahl rein, erhöht mit jedem Aufruf der CFA diesen Zähler (bzw. setzt ihn zurück wenn das Ende erreicht ist) und benutzt diese Variable zum Erzeugen des Dateinamen und damit zum Abspielen einer dazu gehörigen Datei.

In der CFA:
  1. im CFD Projekt eine Variable definieren (rechtsklick oben rechts auf den Namen des Projekts, Variables, Sammlung, eine hinzufügen, z.B. eine Projektvariable mit Namen PROJEKTVAR
  2. CFD Block 1: Get Global Property (den Namen der globalen 3CX Variablen / Parameter hier verwenden, CFAVAR), den 3CX PArameter lesen
  3. CFD Block 2: Assign a Variable, den Namen der Projektvariablen angeben (PROJEKTVAR), den Wert der gelesenen 3CX Variablen zuweisen (CFAVAR)
  4. CFD Block 3: Increment Variable, die Projektvariable (PROJEKTVAR) um eins erhöhen
  5. CFD Block 4: Create a Condition, wenn Wert der Projektvariablen (PROJEKTVAR) zu hoch ist (z.B. 4,
    GREAT_THAN(project$.PROJEKTVAR,"3")) dann mit Assign a Variable den Wert der Projektvariablen (PROJEKTVAR) auf den Startwert (1) zurücksetzen, das ist quasi die Schleife in der von 1 bis 3 gezählt wird
  6. CFD Block 5: Set Global Property (den Namen der globalen 3CX Variablen / Parameter hier verwenden, CFAVAR) und dieser den Wert der Projektvariablen (PROJEKTVAR) zuweisen, damit wird der Wert wieder in der 3CX gespeichert
  7. die Audio Datei abspielen, der Dateiname wird ähnlich gebildet wie hier im Bild 2, nur wird der Wert der Projektvariablen PROJEKTVAR genutzt, der lautet dann CONCATENATE(session.audioFolder,"/Audiofile",project$.PROJEKTVAR,".wav")
Die Schritte 1 bis 7 kann man auch komplett mit einem C# Schnipsel realisieren, das übersteigt evtl. dein Verständnis, daher von Hand zu Fuss mit einzelnen originalen CFD Blöcken wie @patrickb es beschrieben hat.
Ergänzung: Du musst ein TO_INTEGER nutzen da der Global Property immer als String zurückgegeben wird oder es in einem C# Element in einen INT umwandeln. Ansonsten gibts Probleme beim hochzählen der Variable.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: fxbastler
Oder das o.g. CFD Block Gefrickel (Punkt 1 bis 6) gleich komplett in C# bauen, dazu das C# Schnipsel von hier wie folgt ersetzen:
C#:
string strTCXVarName="CFAVAR";
int iStartNr=1;
int iEndNr=3;
int i=iStartNr;
var vara=PhoneSystem.Root.GetParameterByName(strTCXVarName);
if( vara != null ) {
    if( int.TryParse(vara.Value, out i) ) {
        if( i < iEndNr ) {
            i++;
        }
    }
}
PhoneSystem.Root.SetParameter(strTCXVarName,i.ToString());
return i.ToString();
Schon werden wieder nur zwei CFD Blöcke und nun eine umlaufende 3CX Variable benutzt (gelesen, verändert, geschrieben / erzeugt).
 
Zuletzt bearbeitet:
  • Like
Reaktionen: ciscoX
Erst einmal besten Dank für. eure umfangreichen Beispiele. Ich hätte also folgendes. Ich habe mal beide Varianten zusammengestellt, wie in den Anhängen zu sehen ist. Wäre das soweit richtig?

Variante 1:

Foto1.png Foto2.png Foto3.png Foto4.png Foto5.png Foto6.png Foto7.png

Variante 2:

Foto8.png
_ _ _

Deine Lösung das C# Schnipsel von hier liefert bei mir folgendes Ergebnis:

Foto9.png
 
Zuletzt bearbeitet:
  • Like
Reaktionen: fxbastler
Ok, vergiss den vorherigen Post. Ich bin bereits einen Schritt weiter.

Das funktioniert:

Code:
CONCATENATE(session.audioFolder,"/Audiofile",ExecuteCSharpCode1.ReturnValue,".wav")

Code:
Random rnd=new Random();
return rnd.Next(1,4);

Dieser C# Code spielt jedoch immer die gleiche Audiofile ab:

Code:
string strTCXVarName="CFAVAR";
int iStartNr=1;
int iEndNr=3;
int i=iStartNr;
var vara=PhoneSystem.Root.GetParameterByName(strTCXVarName);
if( vara != null ) {
    if( int.TryParse(vara.Value, out i) ) {
        if( i < iEndNr ) {
            i++;
        }
    }
}
PhoneSystem.Root.SetParameter(strTCXVarName,i.ToString());
return i.ToString();

Foto12.png
 
Zuletzt bearbeitet:
Ok so funktioniert es nun endgültig:

C# Code:
Code:
string strTCXVarName = "CFAVAR";
int iStartNr = 1;
int iEndNr = 3;
int i = iStartNr;
var vara = PhoneSystem.Root.GetParameterByName(strTCXVarName);
if (vara != null)
{
    if (int.TryParse(vara.Value, out i))
    {
        i++;
        if (i > iEndNr)
        {
            i = iStartNr;
        }
    }
}
PhoneSystem.Root.SetParameter(strTCXVarName, i.ToString());
string audioFile = "Audiofile" + i + ".wav";
return audioFile;

Audio File Expression:
Code:
CONCATENATE(session.audioFolder,"/",GetRandom1To3.ReturnValue)
 
  • Like
Reaktionen: fxbastler
Ist es eigentlich möglich ein Prompt Playback abzuspielen, während das STT auf das Voice Input wartet, beispielsweise ein Hintergrundgeräusch wie ein G711 rauschen oder sprechende Menschen?
 
Was mich nun auch noch interessiert wäre diese Lösung:
Es gibt wohl die Möglichkeit (ich habe es nur aus der Ferne gehört ...), den Audio Stream irgendwie per Netzwerk (API, Socket?) zu verschicken, um z.B. das Prozessing anderswo laufen zu lassen. Damit würde man diesen speziellen Teil der Aufgabe auslagern. Man kann z.B. so einen ext. Chat / andere Automaten / Erkennung anbinden.

Was genau meinst du damit? OpenAI?
Geht da auch ein Python Server?
Wie kann man das im CFD realisieren?
 
Ok so funktioniert es nun endgültig:
Alle bisher von mir geposteten Lösungen funktionieren. Ich habe das selbst je kurz anlaufen lassen. Deine Fehlermeldung #1 basiert auf deiner anderen Benennung der C# Routine (siehe mein Bild hier, Method Name sollte immer noch GetRandom1to3 sein und nicht CFAVAR laut dem Prompt Playback String deiner Fehlermeldung erste Zeile hier, da steht GetR ...). Die andere bemängelt das falsche .wav Format. Das muss wie geschrieben 8 kHz, 16 bit mono sein. 3CX bietet eine online Konverter an.

Ist es eigentlich möglich ein Prompt Playback abzuspielen, während das STT auf das Voice Input wartet, beispielsweise ein Hintergrundgeräusch wie ein G711 rauschen oder sprechende Menschen?
nein
Was mich nun auch noch interessiert wäre diese Lösung:

Was genau meinst du damit? OpenAI?
Geht da auch ein Python Server?
Wie kann man das im CFD realisieren?
Wenn das geht, dann kann man den Stream mit egal was verarbeiten lassen. OpenAI ist da nur eine von vielen Möglichkeiten. Aber wie geschrieben: ich weiss nicht genau wie das funktionieren soll und wo man da ansetzen kann. Die Frage die sich mir dabei stellt: wie kann ein CFD einen Audio Stream nach außen abbiegen und womöglich gar noch weiterlaufen bis die Verarbeitung gesteuert zu Ende ist.

Frag doch mal Ernesto, du kennst ihn.

Aber schön, was du dir für eine Mühe mit der Umsetzung der Ansätze gemacht und das hier auch haarklein dokumentiert hast. Insbesonders mit der Variante 1, alles richtig erkannt und gemacht. :)
 
Zuletzt bearbeitet:
  • Like
Reaktionen: ciscoX
Frag doch mal Ernesto, du kennst ihn.
Der 3CX-Geheimdienst lässt Grüßen :cool:

Na ja, ihr habt auch sehr gut und geduldig erklärt, daher geht mein Dank an euch.

Nee, es lag nicht an der Audio File, zumindest nicht die .DS_Store Meldung, es lag wahrscheinlich daran, dass ich Windows in einer VM ausführe und das Projekt aber im Downloads Ordner des Macs ist, dieser mit Windows geteilt wird. Ich habe alle Blöcke in ein neues Projekt kopiert und dann ging es, keine Fehlermeldung. Jedoch habe ich mal die WAV Files der IVR Ansage „Null“ „Eins“ „Zwei“ verwendet und es kam immer „Zwei“.

Als ich die Zeile
Code:
string strTCXVarName = "CFAVAR";

bzw. den Variablen Namen geändert habe, wurde dauerhaft „Null“ gesagt. Zu diesem Zeitpunkt hatte ich 2 Blöcke. Das C# Code und das Prompt Playback.

Woran das dann lag weiß ich nicht und konnte das nicht lösen. Ich denke irgendwo muss sich ein Fehler bei mir eingeschlichen haben oder etwas fehlt, z.B. eine Definition der Variablen.

Hauptsache das geht erst Mal. Schade, dass das parallele Prompt Playback nicht funktioniert, unter anderem auch das Background Detection, aber man kann nicht alles haben! :)
 
Zuletzt bearbeitet:
Oje
Jedoch habe ich mal die WAV Files der IVR Ansage „Null“ „Eins“ „Zwei“ verwendet und es kam immer „Zwei“.

Als ich die Zeile
Code:
string strTCXVarName = "CFAVAR";
bzw. den Variablen Namen geändert habe, wurde dauerhaft „Null“ gesagt. Zu diesem Zeitpunkt hatte ich 2 Blöcke. Das C# Code und das Prompt Playback.
Du hast Recht.

Erklärung:
Ich hatte das Schnipsel usw. alles fertig, hatte das kurz probiert, hier in's Forum geschrieben aber habe noch etwas wegen der Lesbarkeit hier im Forum im Text 'optimiert', es letztendlich damit aber kaputt gemacht ohne es zu sehen und ohne es noch einmal zu probieren. Mit dem o.g. Schnipsel zählt der Rundlauf nur von 1 bis 3 und bleibt danach dauerhaft bei 3 stehen. Entschuldigung dafür, mein Fehler.

Hier nun das Schnipsel ohne diese Optimierung. Eben noch einmal getestet: es läuft rundum von 1 bis 3 und wieder von vorn:
C#:
// old code, true 'random', not sequentially:
// Random rnd=new Random();
// return rnd.Next(1,4);
//
string strTCXVarName="CFAVAR";
int iStartNr=1;
int iEndNr=3;
int i=iStartNr;
var vara=PhoneSystem.Root.GetParameterByName(strTCXVarName);
if( vara != null ) {
    if( int.TryParse(vara.Value, out i) ) {
        i=(i<iEndNr)?i+1:iStartNr;
    }
}
PhoneSystem.Root.SetParameter(strTCXVarName,i.ToString());
return i.ToString();

Anbei das Projekt zum testen einmal komplett (aber ohne die Audio Dateien, d.h. es spielt nichts ab, würde es aber gern).

Ich würde das Schnipsel gern weiter um einige Zeilen einkürzen. Da gibt es noch Potential. Das dient dann evtl. aber nicht mehr der Lesbarkeit für Andere, daher bleibt es so.
 

Anhänge

Zuletzt bearbeitet:
  • Love
Reaktionen: ciscoX
Kein Problem und Danke für deinen Post.

Ist es möglich, dass ich im Voice Input die ganzen Hints und Dictionary Prompts in einen C# Code auslagere, damit ich quasi den ganzen Duden hochladen könnte?

Ich meine, es ist nicht sonderlich übersichtlich, alles in dieser Ansicht zu haben:

Foto1.png

So langsam habe ich das Gefühl, es wäre sinnvoller gewesen das Thema "CFD übersichtlich aufbauen" zu benennen, so hat/ hätte Jeder etwas davon, der dieses Thema ebenfalls benötigt! :D
 

Statistik des Forums

Themen
44.765
Beiträge
233.684
Mitglieder
78.501
Neuestes Mitglied
Erich Gasser