From: Steve K. <st...@st...> - 2003-11-11 14:34:31
|
>>A bunch of signal processing stuff from speex: >> >>1) A denoising filter: This is a very effective filter which reduces >>background noise. >>2) New AGC: This AGC implementation from speex seems to work much better >>than the compander implementation I've been using previously. >> >> > >So it really was something like that in the old library... >I have screwed up with the Silence Threshold a lot to see why that companded >sound. >It was great. > > The silence threshold didn't affect the compander at all; they're two separate things. But now, the sox "compander" is only used to get audio levels. And, you can turn AGC (based on speex) on and off if you'd like. >>3) A new "automatic" silence detection based on speex' VAD. If you set >>the silence threshold to a positive number, you now get speex' VAD, >>instead of my hacky noise-threshold code. >> >> >This is great! > > Well, it's relatively good, but it's still not perfect. The 3GPP VAD implementations still work better, but this is servicable. One note: When you're using VAD, iaxclient will send _no packets_ (of course) when it detects silence. Asterisk usually is OK with this, but some asterisk apps may use incoming voice frames as timing for outgoing frames. (I think the hold music is one in particular that works this way). So, if you're using VAD, some of these apps may not work correctly. This all seems to work fine when you're making and receiving calls, though, switched through to a zaptel line, for example. Also, playsound works fine. >>4) Bias removal: Removes bias from input signals. This makes other DSP >>functions work correctly, including the level metering, which was often >>incorrect when bias was present. >> >> >This was one of the issues with the old library... during a conversation, >even the >sound was of a very low amplitude, the level was around 40-50%. > > Yeah. It was something I've been meaning to fix for a long time. >>Another thing that was added was automatic call disconnection when the >>remote endpoint is no longer reachable. This happens if the remote >>endpoint crashes, for example. Previously, there would be no indication >>of this to users. Now, the call will be disconnected. >> >> >That one works even with your code posted on Oct 30....:-) > > > >>There have also been a bunch of bugfixes recently. One important one >>was for the virtualMono implementation, where when there were no >>incoming frames (or you were just playing a sound), some garbage would >>be sent along to the sound card. This made sound playback without an >>active call work improperly. >> >>Also of note, I just found out that there's another libiaxclient library >>user out there: DIAX is based on iaxclient. I think that the author >>is presenly trying to migrate to a newer version of our library, with >>IAX2 support. >> >> >> > >I hope to be able to implement all those great features during this week. > > > Let me know how it turns out. I think that by default, for most clients, I'd enable AGC and denoise, but keep VAD and echo cancellation disabled. In my test client, I made a "filters" cascading menu with checkboxes for the user to choose amongst the modes: (Michael or anyone working on wx-based implementations are free to plug this in to their clients). [incomplete] Code snippets from that: filtersMenu = new wxMenu(); // silence detection filtersMenu->AppendCheckItem(ID_SILDET, _T("Silence Detection")); filtersMenu->Check(ID_SILDET, true); silenceDetect = true; // AGC filtersMenu->AppendCheckItem(ID_AGC, _T("Automatic Gain Control")); filtersMenu->Check(ID_AGC, true); gainFilter = true; // Denoise filtersMenu->AppendCheckItem(ID_DENOISE, _T("Noise Reduction")); filtersMenu->Check(ID_DENOISE, true); denoiseFilter = true; // Echo Cancellation filtersMenu->AppendCheckItem(ID_ECHO, _T("Echo Cancellation")); filtersMenu->Check(ID_ECHO, false); echoFilter = false; controlMenu->Append(ID_FILTERS_MENU, "Filters", filtersMenu); // Handle Filter Changes void HLFrame::OnFilterChange(wxCommandEvent &evt) { bool checked = evt.IsChecked(); int id = evt.GetId(); int flag; // silence detection is related to call state, and handled separately. if(id == ID_SILDET) { silenceDetect = checked; // call ChangeTalkState to reset silence? ChangeTalkState(0, talkState); return; } // these all toggle a flag in the library; first, figure out which flag. switch (id) { case ID_AGC: flag = IAXC_FILTER_AGC; break; case ID_DENOISE: flag = IAXC_FILTER_DENOISE; break; case ID_ECHO: flag = IAXC_FILTER_ECHO; break; } if(checked) iaxc_set_filters(iaxc_get_filters() | flag); else iaxc_set_filters(iaxc_get_filters() & ~flag); } |