Text->Tonausgabe / Tonanalyse->Text



  • Hallo,

    ich bin daran ein Programm zu schreiben mit dem Buchstaben in Töne umgewandelt und ein Programm mit dem diese
    Daten Empfangen und wieder in Text umgewandelt werden können.
    Das Ganze soll nachher zu einem Programm zusammengefügt werden, der Einfachheit halber will ich es am Anfang
    in zwei getrennt laufende Programme packen.

    Der Sinn der Sache ist eine Datenübertragung per CB-Funk. Jetzt wird sich jeder denken "es gibt doch schon
    Packetradio..." aber mir geht es darum selbst Abläufe zu verstehen.

    Ich stehe jedoch vor ein paar Problemen. Zum Beispiel habe ich keine Ahnung wie ich einen Ton über die Soundkarte
    ausgeben kann bei dem ich die Frequenz in Hertz und die Dauer des Tones angeben kann ganz nach
    "BOOL Beep (DWORD dwFreq,DWORD dwDuration);"
    Wenn ich diese Funktion einbauen kann dann ist das Senden einer Nachricht kein Problem mehr.

    Hier der Quelltext den ich geschrieben habe:

    #include <iostream.h>
    
    char string[50];
    
    void eingabe()
    {
     cout << "Zu sendender Text: ";
     cin >> string;
    }
    
    void tonausgabe()
    {
     for(unsigned int i=0;i<strlen(String);i++)
     {
      if(string[i]=='a'])
      {
       // Hier muss die Tonausgabe für A hin ...
       // A wäre als 0000 definiert 
       // also wäre die Tonausgabe 300 Hz, 300Hz, 300Hz, 300Hz
      }
      if(string[i]=='b'])
      {
       // Hier muss die Tonausgabe für B hin ...
       // B wäre als 0001 definiert 
       // also wäre die Tonausgabe 300 Hz, 300Hz, 300Hz, 600Hz
      }
      // Weitere Überprüfungen für alle Buchstaben im Alphabet
      eingabe();
    }
    
    void main()
    {
     eingabe();
     verarbeitung();
    }
    

    Dann ist da nur noch das Problem dass ich keine Ahnung habe wie ich einen Ton der über den LineIn
    Eingang in die Soundkarte kommt in C++ "einlese" und die Frequenz erkenne.

    Google war auch nicht sehr ergiebig und in jedem Forum sehe ich "FFT Analyse" doch verständliche
    Quelltexte finde ich keine.

    Im Forum http://www.c-plusplus.net/forum/viewtopic.php?t=46113&postdays=0&postorder=asc&highlight=ton&start=0
    habe ich folgenden Quelltext gefunden:

    WaveInCaps WaveCaps; 
    for(int i=0; i<waveInGetNumDevs()-1; i++) 
    { 
    result = waveInGetCaps(I,WaveCaps,48); 
    cout "(" << i << ") " << WaveCaps.ProductName << "\n"; 
    } 
    // dann den user auswählen lassen von 0 bis waveInGetNumDevs()-1 
    // und das in Device abspeichern 
    int DevHandle; 
    WaveFormatEx WaveFMT; 
    WaveFMT.FormatTag = 1; 
    WaveFMT.Channels = 1; 
    WaveFMT.SamplesPerSec = 11025; // BlockAlign * SamplesPerSec 
    WaveFMT.AvgBytesPerSec = 11025; // (Channels * BitsPerSample) / 8 
    WaveFMT.BlockAlign = 1; 
    WaveFMT.BitsPerSample = 8; 
    WaveFMT.ExtraDataSize = 0; 
    
    waveInOpen(&DevHandle,Device,&WaveFMT,0,0,0); 
    waveInStart(DevHandle); 
    
    char WaveData[512]; 
    WaveHdr WaveHead; 
    WaveHead.lpData = &WaveData[0]; 
    WaveHead.dwBufferLength = 512; 
    waveInPrepareHeader(DevHandle,&WaveHead,32); 
    ... 
    while !quit 
    { 
    ... 
    waveInAddBuffer(DevHandle,&WaveHead,32); 
    // nun steht im WaveData-Array die Amplitudenwerte (0 - 256) 
    // die man jetzt noch grafisch darstellen könnte 
    .... 
    } 
    ... 
    waveInUnprepareHeader(DevHandle,&WaveHead,32); 
    waveInReset(DevHandle); 
    waveInClose(DevHandle);
    ...
    

    damit kann ich aber leider nichts anfangen.

    Wie gesagt wenn mir jemand:

    1. sagen kann wie ich einen Ton über die Soundkarte ausgeben kann bei dem ich die
    Frequenz in Hertz und die Dauer des Tones angeben kann
    2. sagen kann wie ich in C++ die Frequenz eines Tones der über den LineIn erkennen kann

    dann währe ich sehr dankbar!



  • Wie gesagt wenn mir jemand:
    1. sagen kann wie ich einen Ton über die Soundkarte ausgeben kann bei dem ich die Frequenz in Hertz und die Dauer des Tones angeben kann.

    Ein Hertz entspricht einer kompletten Vor-und Rückwärtsbewegung der Lautsprechermebran. *

    Wenn du also im vorzeichenbehafteten 8-Bit Waveformat den Soundbuffer mit 256 Bytes, deren Werte einer Sinuskurve mit der Amplitute 128 entsprechen, und du diesen Puffer 440 mal in der Sekunde an die Lautsprecher schickst, hast du den Kammerton.

    Vielleicht solltest du dir mal FMod anschauen - ist recht benutzerfreundlich die Library.



  • Du könntest auch deine Daten in eine Wave Datei(oder Stream) schreiben, und dann per PlaySound ausgeben. Was für daten in eine Wave kommen steht auf einer guten Seite beschrieben, dessen Link ich leider nicht hab in Moment, da sind alle Dateietypen beschrieben.
    Google mal danach.



  • Das Problem bei PlaySound() ist dass ich ja die Wave Dateien (600 Hz, 300Hz) erstmal erzeugen oder irgendwo runterladen muss ... dann ist auch noch die Frage wie schnell er die Töne nacheinander abspielt.

    Wenn dann auch noch Prüfsummen des gesendeten Textes oder eine schnellere übertragung durch mehrere Tonfrequenzen dazu kommen (z.B. jeder Buchstabe bekommt seinen eigenen Ton) ist es ein großer vorteil wenn ich die Töne im Programm selbst erzeugen kann.

    Vielleicht solltest du dir mal FMod anschauen - ist recht benutzerfreundlich die Library.

    In der FMod Dokumentation habe ich nichts sinnvolles gefunden. Ich kann die BPM ermitteln oder die Lautstärke. Ich kann mit FMod alle möglichen Audioformate abspielen ... Danke für den Tip aber ich denke das ist nicht das Richtige.

    Wenn du also im vorzeichenbehafteten 8-Bit Waveformat den Soundbuffer mit 256 Bytes, deren Werte einer Sinuskurve mit der Amplitute 128 entsprechen, und du diesen Puffer 440 mal in der Sekunde an die Lautsprecher schickst, hast du den Kammerton.

    okay, interessant den Technischen Hintergrund zu sehen aber weitergebracht hat mich das leider nicht ... 🙄



  • Mit waveOutOpen() Soundkarte zur Ausgabe startklar machen.
    Mit waveOutPrepareHeader() und waveOutWrite() dann deine Waveform ausgeben.
    Bei einem 16-Bit Wavestream musst du quasi an waveOutWrite() nur 16-bit signed Werte übergeben (z.B. signed short) die eine sinus-schwingung mit deiner gewünschten Frequenz beinhalten. Bei mehreren Frequenzen gleichzeitig musst du die dann eben überlagern...



  • geeky hast du dazu einen beispielcode? Ich hab mit sowas noch nie gearbeitet...



  • Schau mal hier nach:
    http://www.c-plusplus.net/forum/viewtopic.php?t=97353&highlight=
    Der Rest steht in der MSDN und im Petzold.

    Ausgeben von Frequenzen (Tönen) ist ganz einfach. Erkennen ist ungleich schwerer, die Schwingungen sind ja nicht mehr "rein", sondern verformt.

    26 und mehr verschiedene Frequenzen sind auch nicht so gut im CB-"Sprachband" unterzubringen.
    Vielleicht ist die DTMF-Analyse was für Dich?

    Blackbird



  • Wenn es dir darum geht, nur einen Chat zu schreiben, also keine sonderlich großen Daten wie Bilder zu übertragen, mach es gleich digital.

    Also Ton an/aus ein paar mal die Sekunde mit Festfrequenz.



  • geeky schrieb:

    Bei einem 16-Bit Wavestream musst du quasi an waveOutWrite() nur 16-bit signed Werte übergeben (z.B. signed short) die eine sinus-schwingung mit deiner gewünschten Frequenz beinhalten. Bei mehreren Frequenzen gleichzeitig musst du die dann eben überlagern...

    Hallo, ich hab ein ähnliches Problem mit der Soundausgabe... kann mir zu dem obigen Zitat jemand nähere Infos geben? Ich hab im Moment leider keinen Plan, wie ich das umsetzen soll. Ich muss eine Tonfolge bestehend aus einzeltönen mit definierter Frequenz und definierter Länge ausgeben und diese auf einem anderen PC auswerten.... Puuh!

    Für jeden Tip bin ich dankbar!

    Gruß
    Thomas



  • haben mal im oc bei uns ein programm für`s psk31 geschrieben , die ein und ausgabe erfolgte über die soundkarte und die mmsystem.dll (standart windows)

    mit der mmsystem lasst sich wunderbar samplefrequenz, ein- und ausgabe, tonfrequenz , bandbreite e.t.c arbeiten!

    gug dir mal mmsystem.dll an...

    PS: warum wird hier *S*T*A*N*D*A*R*T* zensiert? 😃 find ich ja lolig^^



  • ink3n schrieb:

    PS: warum wird hier *S*T*A*N*D*A*R*T* zensiert? 😃 find ich ja lolig^^

    Weil man Standard schreibt.



  • 💡 ! 😃



  • du könntest ja z.b. dtmf nehmen. da haste ja die ziffern 0...9 und a...f so dass du 1 byte als 2 dtmf-signale kodieren kannst. die samples für ein dtmf-signal kannste einmalig berechnen und als array speichern (so ca 100 bytes pro ziffer reichen). die schickste dann mit den waveOutXXX-funktionen zur soundkarte. für richtiges drmf musste dann nur noch das puls/pausen-verhältnis einhalten (infos dazu gibbets im internet). zum dekodieren nimmt man sogenannte 'goertzel-filter' (als software). einfach mal danach googlen, man findet auch source codes dazu 😉



  • das mit dem dtmf ist ne gute Idee, aber zum goertzel-filter finde ich im Internet nichts brauchbares



  • Auf meiner Homepage findes du unter AudioDeme einige Beispiele
    wie man einen Ton erzeugt, abspielt und auf nimmt
    Für die Ton-Analyse solltest du dich mal mit der FFT beschäftigen.

    [url]
    http://members.inode.at/anton.zechner/az/index.html
    [/url]



  • Domio schrieb:

    das mit dem dtmf ist ne gute Idee, aber zum goertzel-filter finde ich im Internet nichts brauchbares

    guckst du: http://www.embedded.com/story/OEG20020819S0057


Anmelden zum Antworten