mehrere VoIP streams mischen



  • Hi!

    Mein VoIP Programm funkt wunderbar wenn man nur zu zweit ist. Doch sobald ein dritter hinzukommt habe ich das Problem, dass die streams quasi nacheinander abgespielt werden.

    Wie ihr sicher wisst nimmt man bei VoIP einfach permanent mit dem Mikro auf. Teilt das in 10 millisekunden lange Aufnahmen und sendet diese. D.h. Client A empfängt von Client B und Client C bestenfalls alle 10 millisekunden eine 10 millisekunden lange Aufnahme. Das Problem ist nun, das zuerst die ersten 10 millisekunden von Client B abgespielt werden und dann die 10 millisekunden von Client C. Das hört sich dann im Endeffekt an als würden beide währenden des Sprächens ruckartig unterbrochen werden.

    Zur Lösung des Problems sind mir 2 Möglichkeiten eingefallen:

    1. 2 sperate Ausgabethread (per waveOutOpen())
    2. 1 Ausgabethread, warten bis beide Pakete angekommen sind, diese zu einer Aufnahme mischen und dann ausgeben. (kann mir nicht vorstellen, dass das bei mehr als 3 Teilnehmern noch klappt da zu große Verzögerungen zu Stande kommen würden; wenn 1 Teilnehmer plötzlich nichts mehr sendet können die anderen auch nichts mehr hören)

    Gibts noch ne andere Möglichkeit bzw. welche wird tatsächlich angewandt?

    Edit: Wie kann man überhaupt zwei Streams zu einem mischen? Beide miteinander multiplizieren?



  • normalerweise addiert man die beiden streams einfach.

    je nachdem was du für eine ausgabebibliothek verwendest, sollte mischen drin sein.
    directsound z.b. macht das automatisch. und es kann auch aufnehmen 😉



  • Ich benutze waveform. Das macht das scheinbar nicht automatisch (oder es liegt irgendwie an meinem code). Sobald ich waveOutWrite aufrufe, wird zuerst der sound fertig abgespielt bis erst der nächste abgespielt werden kann.

    Hier der Ausgabecode:

    //...
    //Hier wird waveform Output initialisiert:
    WaveOutThreadHandle = CreateThread (NULL, 0, WaveOutThread, NULL, 0, &WaveOutThreadId );
    if(WaveOutThreadHandle == NULL) {return -1;}
    rv = waveOutOpen(&hWaveOut,WAVE_MAPPER,&waveform,(DWORD)WaveOutThreadId,0,CALLBACK_THREAD);
    if(rv != MMSYSERR_NOERROR) {return -1;}
    //...
    
    DWORD WINAPI WaveOutThread (void *Arg)
    {
      MSG Msg;
      int rv;
    
      rv = SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
    
      while (GetMessage (&Msg, NULL, 0, 0) == TRUE) {
        if (MM_WOM_DONE == Msg.message) {
          WAVEHDR *Hdr = (WAVEHDR *) Msg.lParam;
    
          Hdr->dwUser = 0;  // Buffer frei melden
        }
      }
      return 0; 
    }
    
    //...
    //Das wird in dem Thread in dem per UDP Empfangen wird aufgerufen (startet die Ausgabe)
    for (i = 0; i < voip_num_bufs; ++i) {
         if (0 == WaveHdrOut[i].dwUser) {
               WaveHdrOut[i].dwUser = 1;       // Buffer belegt markieren
               waveOutWrite(hWaveOut, WaveHdrOut + i, sizeof(WaveHdrOut[0]));
    }
    //...
    

    Auch wenn waveOutWrite aufgerufen wird während der andere Sound noch abgespielt wird, werden die 2 sounds nicht gemischt sondern der 2. Sound wird erst nach dem der 1. beendet wurde abgespielt.



  • Also nochmal mein Problem konkret formuliert:

    Ich möchte mit waveform 2 oder mehrere streams gleichzeitig abspielen. Die streams starten jedoch nicht zum selben Zeitpunkt mit dem Abspielen, weswegen sie nicht einfach addieret werden können.

    Was/Wie tun?

    Danke für eure Hilfe!


Anmelden zum Antworten