From: Steve K. <st...@st...> - 2003-11-11 01:11:58
|
I forget what I've announced to the list, and what I haven't. The main new features added to the library recently are: 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. 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. 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. 5) echo cancellation: I modularized the echo cancellation a bit. You can include one of speex' echo cancellation, MEC2/3, or Steve underwood's echo canceller via compile-time options. Speex' echo canceller is included by default. Echo cancellation via speex is still "experimental" in nature. In particular, it is not very effective when you're also using AGC, because residual echo is boosted back up to full strength. When you're not using AGC, it is somewhat effective in my limited testing. Each of the denoiser, AGC, and echo cancellation can be enabled/disabled by calls to the library through this API: #define IAXC_FILTER_DENOISE (1<<0) #define IAXC_FILTER_AGC (1<<1) #define IAXC_FILTER_ECHO (1<<2) int iaxc_get_filters(void); void iaxc_set_filters(int filters); 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. 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. -SteveK |
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); } |