Formant Isolation

Status
Not open for further replies.
I am wondering if anyone has done any work with formants using teensy? I would like to experiment with processing formants separately from the fundamental frequency content. For example, this can be used to create a gender knob by pitch shifting the formants alone. This is done in a few products such as the TC-Helicon VoiceTone C1 (very cool product). I have done some research but it is a pretty niche topic and while I have found mentions of formant filtering, I have yet to find details on an implementation.
 
Moving all the formants up and down isn't particularly difficult...if you've already got a frequency-domain processing algorithm stack going. Getting the round trip FFT/IFFT processing needed to into and out of the frequency domain, however, can be difficult, if you've never done it before. For example, you really don't want to use fixed-point FFT and IFFT, so you'll need to use one of the floating-point extensions to the Teensy Audio library. Both of mine include a formant-shifting example.

From my (and Bob Larkin's) OpenAudio library, you can use the formant shifter: https://github.com/chipaudette/OpenAudio_ArduinoLibrary/tree/master/examples/FormantShifter_FD_OA

Or, from my Tympan library (which can work with any Teensy 3.5/3.6 based hardware, not just the Teensy 3.6-based Tympan), you can use it's formant shifting algorithm: https://github.com/Tympan/Tympan_Library/tree/master/examples/04-FrequencyDomain/FormantShifter_FD

Chip
 
Moving all the formants up and down isn't particularly difficult...if you've already got a frequency-domain processing algorithm stack going. Getting the round trip FFT/IFFT processing needed to into and out of the frequency domain, however, can be difficult, if you've never done it before. For example, you really don't want to use fixed-point FFT and IFFT, so you'll need to use one of the floating-point extensions to the Teensy Audio library. Both of mine include a formant-shifting example.

From my (and Bob Larkin's) OpenAudio library, you can use the formant shifter: https://github.com/chipaudette/OpenAudio_ArduinoLibrary/tree/master/examples/FormantShifter_FD_OA

Or, from my Tympan library (which can work with any Teensy 3.5/3.6 based hardware, not just the Teensy 3.6-based Tympan), you can use it's formant shifting algorithm: https://github.com/Tympan/Tympan_Library/tree/master/examples/04-FrequencyDomain/FormantShifter_FD

Chip

Chip,

I am wondering if this is a linear shift, meaning it is a frequency shift. From what I can tell this is moving frequencies by a fixed amount regardless of the frequency. I am probably neglecting to use the proper term but from what I understand pitch shifting and frequency shifting are distinct where the former retains harmonic relationships and the latter does not. I am very interested in efficient pitch shifting methods that retain the harmonic relationships between freq components.
 
Formant shifting and pitch shifting are indeed different things. My links are for formant shifters that work in the frequency domain. They move the amplitude of the FFT bins up or down but leave the FFT phase values in place. If they were pitch shifters, they would move the phase values, too.

The links that I sent are formant shifters. They shift the formants up or down. They are what you might want for gender bending or for making it sound like you're breathing helium (helium only changes your voice's formants, not your voice's fundamental pitch).

Chip
 
Chip: pardon me for butting in on this thread- following is an issue I opened on the OpenAudio GitHub site:
Great work on this F.P. audio library, Chip.
I'm using Arduino 1.8.9 and Teensyduino 1.52. Until I remove the #include "DSP_Teensyduino_32.h" line from the TestEqualizer1 example, it won't compile. I don't see this file in the OpenAudio_Arduino library, so its not surprising. Compiles and works great without that line though. I'm using Teensy 4.x but it was the same when I tried to compile it with T3.6.
Am I missing something, or should the examples be edited to reflect this?
 
Chip: pardon me for butting in on this thread- following is an issue I opened on the OpenAudio GitHub site:
Great work on this F.P. audio library, Chip.
I'm using Arduino 1.8.9 and Teensyduino 1.52. Until I remove the #include "DSP_Teensyduino_32.h" line from the TestEqualizer1 example, it won't compile. I don't see this file in the OpenAudio_Arduino library, so its not surprising. Compiles and works great without that line though. I'm using Teensy 4.x but it was the same when I tried to compile it with T3.6.
Am I missing something, or should the examples be edited to reflect this?

The OpenAudio library is a collaboration between me and Bob Larkin. Since I don't recognize the file "DSP_Teensyduino_32.h", I'm assuming that it's something that Bob added. If it fails to compile with the #include but correctly compiles by removing it, I think that you're right to remove it. It sounds like our fault, not yours.

As for the implications of using T4 instead of T3.6, I'm less familiar with those issues. I've compiled some of the code for T4, but I'm nearly 100% still in the T3.6 world. Sorry I can't be more help there.

Chip
 
Thanks Chip. That's what I figured. I am using the T4.1 and could see that the full F.P. audio library wasn't adapted to T4.x yet.

DD4WH and I have written floating point Convolution FIR filters using (FFT/iFFT) including segmented FFT routines that have very low latencies even on FIR tap lengths up to 20K (for guitar cabinet simulation, for example). DD4WH did most of the original coding, and I ported it to a conventional PJRC audio library object. While the filter only accepts 16-bit stereo input/output, all the processing is in floating point, including of course the FIR coefficients.
In the past, I had tried to implement a multiband EQ using this routine and 513 tap FIR coefficients. In theory, I figured I should be able to just add the filter coefficients for each individual band together, but it worked poorly. When I came across your work, I could see that you also calculate the individual filter coefficients but use a window function, which I hadn't done.
When I use your equalizerNew routine to calculate the FIR coefficients, our filter is now working very nicely. Thanks;)
 
Status
Not open for further replies.
Back
Top