Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 35

Thread: Teensy Hearing Aid

Hybrid View

  1. #1
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167

    Teensy Hearing Aid

    Hi All,

    I started a new project to see what could be done to make an open-source hearing aid. I'm not attempting to make it small, or attractive, or long-lived. Maybe those qualities will come in time. My goal is to make a platform where I (and maybe others) can try out their own hearing aid algorithms.

    After playing with the Teensy (especially the fast new Teensy 3.6) I chose to base my initial device on Teensy hardware...

    Click image for larger version. 

Name:	TeensyHearingAidLead2.png 
Views:	118 
Size:	112.2 KB 
ID:	8851

    If your interested in more details, or if you'd like to see a quick demo (video), you can check out my post at: http://openaudio.blogspot.com/2016/1...aring-aid.html

    I'm not aware of any other attempts at making an open-source hearing aid. Are any of you familiar with any that got anywhere?

    Chip

  2. #2
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    In using a powerful Teensy 3.6, I was concerned that my power consumption might be painfully high. So, I looked into it. By adding a single WFI command, I increased my battery life by 50%. I had no idea it could work out so easily. Sweet!

    Power-saving thread here: https://forum.pjrc.com/threads/40315...er-Consumption

    Chip

  3. #3
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    Being a hearing aid, understanding how the different gain settings work is important. So, I started by quantifying the effect of the volume knob on the Teensy Audio Board. Here's the quick summary:

    Click image for larger version. 

Name:	HeadphoneLevel.png 
Views:	131 
Size:	28.7 KB 
ID:	8950

    So, for my full-scale sine wave, the output starts to saturate at a setting of about 0.85. The saturation occurs because I'm asking for a signal level that is bigger than the power rails supplying the SGTL5000, so it's understandable. I'm going to keep my volume setting at 0.8 or below.

    If you're interested in a bit more detail: http://openaudio.blogspot.com/2016/1...one-level.html

    Chip

  4. #4
    Member
    Join Date
    Nov 2015
    Location
    Norway
    Posts
    70
    cool project! Maybe it will shrink one day and be the sister or brother of the google glasses..?

  5. #5
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    Yeah, definitely looking to make it smaller. First, I'm heading towards integrating everything into daughter card for the Teensy. Then, maybe I'll integrate the microcontroller to put it all into one package. It still probably won't fit into something as svelte as google glasses, but it could probably fit behind the ear. That'd be cool (to me, at least).

    Chip

  6. #6
    Senior Member
    Join Date
    Oct 2014
    Posts
    167
    Hearing Aids are not just amps, they are frequency gain in areas that people are hard of hearing too.
    Overall amp is no good.
    In my teens years, I would listen to ROCK on a stereo at almost full volume. As my parents would say "Your going to go deaf" Well, yes.. But its the higher frequencies that I have lost.
    My Lows are ok, but just doing an amplifier for overall, not so good.
    The only reason I see is the teensy maybe has to adjust a notch filter to reduce lows and allow Highs to pass in my case. The more use of notch filters, the better the device.

    Or equalizers ...
    The other thing is tinnitus, I have a constant noise at high end that is all the time. I think it puts me to sleep type noise.. That is another function that has a unique feature.
    Finding that noise and blanking it.
    But being the 1st step is kool., My hearing aids cost close to $1,000 each. Enough payback for loud music.

  7. #7
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    Quote Originally Posted by Wayne View Post
    Hearing Aids are not just amps, they are frequency gain in areas that people are hard of hearing too.
    Overall amp is no good.
    In my teens years, I would listen to ROCK on a stereo at almost full volume. As my parents would say "Your going to go deaf" Well, yes.. But its the higher frequencies that I have lost.
    My Lows are ok, but just doing an amplifier for overall, not so good.
    The only reason I see is the teensy maybe has to adjust a notch filter to reduce lows and allow Highs to pass in my case. The more use of notch filters, the better the device.

    Or equalizers ...
    The other thing is tinnitus, I have a constant noise at high end that is all the time. I think it puts me to sleep type noise.. That is another function that has a unique feature.
    Finding that noise and blanking it.
    But being the 1st step is kool., My hearing aids cost close to $1,000 each. Enough payback for loud music.
    Yes, I'm definitely aware that gain (loudness) alone is not helpful. If just gain were needed, you could just use an analog amplifier. I chose to use the Teensy 3.6 because it has a good bit of computational power that can be put to use on signal processing aimed at improving hearing. Frequency shaping and dynamic range compression are the first simple steps, but after that you can go into all sorts of frequency-domain techniques.

    For algorithms, I've been working through this book "Digital Hearing Aids" by James Kates. It's not the newest book around, but I like that it's written from the time when most hearing aids were just making the jump to digital. Therefore, the signal processing techniques that he describes are modest, which makes them simple enough for me to understand. After mastering the basics, then maybe I'll have the ability to understand the modern.

    Sorry about your hearing loss and tinnitus. I know a lot of folks in that position. I'll probably be there too, soon enough. All of this has given me a good amount of motivation to help make some progress. This effort with my Teensy Hearing Aid is just one cog in a larger effort to make open-source hearing technologies. My work is attempting to be just one teensy (ha!) contribution.

    Chip

  8. #8
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    Starting down the path of adding dynamic range compression. Starting with a little discussion of why the heck you need to do such a thing...written while killing time in a overly-loud airport.

    Click image for larger version. 

Name:	TooQuietTooLoud%u00252B-%u00252BColor.png 
Views:	108 
Size:	90.5 KB 
ID:	9403
    http://openaudio.blogspot.com/2017/0...mpression.html


    Chip

  9. #9
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    Quote Originally Posted by chipaudette View Post
    Starting down the path of adding dynamic range compression. Starting with a little discussion of why the heck you need to do such a thing...written while killing time in a overly-loud airport.

    Click image for larger version. 

Name:	TooQuietTooLoud%u00252B-%u00252BColor.png 
Views:	108 
Size:	90.5 KB 
ID:	9403
    http://openaudio.blogspot.com/2017/0...mpression.html


    Chip
    And I've now implemented my Dynamic Range Compressor as part of my floating-point extension of the Teensy Audio Library. If you're interested, you can check it out here:

    http://openaudio.blogspot.com/2017/0...ompressor.html

    Click image for larger version. 

Name:	CompressorSignalFlow.png 
Views:	136 
Size:	14.9 KB 
ID:	9434

    Chip

  10. #10
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    44
    I have hearing damage similar to Wayne's description. Seems to me that a key part of this project is going to be audiometrics--determining exactly what frequencies need boosting by how much.

    For me, tinnitus sounds like a steam radiator hissing in my ears 24/7, with occasion sine-like tones (but I'm unable to identify the exact pitch) that last for a few seconds and then fade out. I don't see help for tinnitus coming from this source, unfortunately, since it seems to be neurologically generated. I think of it as analogous to phantom limb syndrome for dead audio nerves.

    --Michael

  11. #11
    Member
    Join Date
    Sep 2016
    Location
    NYC, USA
    Posts
    44
    Looking forward to following your progress.

    Single band is what I'll need for the experiments I have in mind, at least at first--simply a box that sits between amplifier and source (computer's analog out in my workroom and Roku with spdif out in living room). I imagine that the width of the band can be changed using the audio lib's filter capability.

    But I don't want to get into this too deeply yet, before I'm ready to follow through on it.

    --Michael
    Last edited by Michael Ward; 01-18-2017 at 06:52 PM.

  12. #12
    Member
    Join Date
    Nov 2015
    Location
    Norway
    Posts
    70
    Really good work Chip! I have tested the compressor for use with instruments and it works very well!
    But now I'm in need of a level detector (or envelope follower) for the audio signal.
    And you have made a very good one in the compressor. So I tried to just do a tweak in your code to get the audio_level_dB_block out from the module instead of the compressed audio signal:

    Code:
     void update(void) {
          //Serial.println("AudioEffectGain_F32: updating.");  //for debugging.
          audio_block_f32_t *audio_block = AudioStream_F32::receiveWritable_f32();
          if (!audio_block) return;
    
          //apply a high-pass filter to get rid of the DC offset
          if (use_HP_prefilter) arm_biquad_cascade_df1_f32(&hp_filt_struct, audio_block->data, audio_block->data, audio_block->length);
          
          //apply the pre-gain...a negative gain value will disable
          if (pre_gain > 0.0f) arm_scale_f32(audio_block->data, pre_gain, audio_block->data, audio_block->length); //use ARM DSP for speed!
    
          //calculate the level of the audio (ie, calculate a smoothed version of the signal power)
          audio_block_f32_t *audio_level_dB_block = AudioStream_F32::allocate_f32();
          calcAudioLevel_dB(audio_block, audio_level_dB_block); //returns through audio_level_dB_block
    
          //compute the desired gain based on the observed audio level
          audio_block_f32_t *gain_block = AudioStream_F32::allocate_f32();
          calcGain(audio_level_dB_block, gain_block);  //returns through gain_block
    
          //apply the desired gain...store the processed audio back into audio_block
          arm_mult_f32(audio_block->data, gain_block->data, audio_block->data, audio_block->length);
    
          //transmit the block and release memory
          AudioStream_F32::transmit(audio_level_dB_block);
          AudioStream_F32::release(audio_block);
          AudioStream_F32::release(gain_block);
          AudioStream_F32::release(audio_level_dB_block);
        }
    Is there any obvious reason that this should not work? I will use the signal strength to control a state variable filter.
    Last edited by omjanger; 02-25-2017 at 09:44 AM.

  13. #13
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    @omjanger, yeah, I totally thinkk that your approach would work.

  14. #14
    Member
    Join Date
    Nov 2015
    Location
    Norway
    Posts
    70
    Quote Originally Posted by chipaudette View Post
    @omjanger, yeah, I totally thinkk that your approach would work.
    But it didn't.. I put the intToFloat in front of the compressor and the FloatToInt after. But it was only 0 out.. will search more and see if there is another reason=)

  15. #15
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    I just assessed the self-noise and dynamic range of our new Tympan audio board. We were successful in lowering the noise floor relative to the Teensy Audio Board, which permits it to have a wider dynamic range. It's fun when things work out as planned! [going according to plan isn't something that usually happens]

    http://openaudio.blogspot.com/2017/0...elf-noise.html

    Click image for larger version. 

Name:	CompareDynamicRange.png 
Views:	109 
Size:	30.1 KB 
ID:	9974

    Chip

  16. #16
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    After working with my crazy breadboard version of my Teensy Hearing Aid, I decided to make a custom PCB. It still uses a Teensy 3.6, but it brings together all of the other components onto one board...

    Click image for larger version. 

Name:	Parts%u00252Bof%u00252BTympan.png 
Views:	372 
Size:	716.4 KB 
ID:	9886

    It's so much more robust that my breadboard version. If you're interested, a few more details (as well as links to schematics and whatnot) are here: http://openaudio.blogspot.com/2017/0...ke-tympan.html

    This sure is fun!

    Chip

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,799
    That's looking good! Didn't read enough to see what part the Bluetooth plays? Other than that I suppose the T_3.6 is the most expensive part by far? (saying only that the rest is simple components)

  18. #18
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    The bluetooth isn't much used at the moment. The idea was that the bluetooth link would allow me to control the settings on the device without having to plug in USB. I could simply open up my phone and shoot a few messages to the device and its settings would change.

    Alternatively, I figured that I could use the Bluetooth link to send data out from the hearing aid. I could log that data on a PC or phone in order to see how the device responds to certain sound environments, or I could use it to monitor the sound environment itself. I could use the device as a wireless sound level meter or something.

    Or, less scientific or more silly, one could image having the link to the phone that enables you to play an audio version of Pokemon Go. The hearing aid continues to process the ambient natural audio, but upon Bluetooth commands from the phone based on your location (or whatever), would inject additional sounds based on whatever game scenario you're playing.

    So, yeah, the bluetooth is for connectivity for basic user control or for future advanced interactions. It currently has nothing to do with making hearing better.

    Chip

  19. #19
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,799
    Good - I didn't miss that part Communication and control/feedback sounds good. I was wondering if perhaps there was a tie to Bluetooth earphones I didn't see.

    The intermediate result looks much better than the post #1 mock up.

  20. #20
    Member
    Join Date
    Nov 2015
    Location
    Norway
    Posts
    70
    I have a question...
    I am trying to extend chipaudettes compressor class with an option to add another input and use it as a sidechain compressor. Where one of the inputs are analyzed and the other input gets the compression based on the analyze.
    But the program freeze when I try to read the other input:
    Code:
    	  audio_block_sc = AudioStream_F32::receiveReadOnly_f32(1);
    I can put this
    Code:
    	  audio_block_sc = AudioStream_F32::receiveReadOnly_f32(0);
    and the program will run, but does not what it should obviously.

    I have tried a lot of different methods and variants of receiveReadOnly, made new audioStreams etc.

    Does anyone have an idea what I am missing?

    Code:
    #ifndef _AudioEffectCompressor2_F32
    #define _AudioEffectCompressor2_F32
    
    #include <arm_math.h> //ARM DSP extensions.  https://www.keil.com/pack/doc/CMSIS/DSP/html/index.html
    #include <AudioStream_F32.h>
    
    class AudioEffectCompressor2_F32 : public AudioStream_F32
    {
      //GUI: inputs:2, outputs:1  //this line used for automatic generation of GUI node
      public:
        //constructor
        AudioEffectCompressor2_F32(void) : AudioStream_F32(2, inputQueueArray_f32 ) {
          setThresh_dBFS(-20.0f);     //set the default value for the threshold for compression
          setCompressionRatio(5.0f);  //set the default copression ratio
          setAttack_sec(0.005f, AUDIO_SAMPLE_RATE);  //default to this value
          setRelease_sec(0.200f, AUDIO_SAMPLE_RATE); //default to this value
          setHPFilterCoeff();  enableHPFilter(true);  //enable the HP filter to remove any DC offset from the audio
          resetStates();	setSideChain(0);
        };
    
        //here's the method that does all the work
        void update(void) {
          //Serial.println("AudioEffectGain_F32: updating.");  //for debugging.
    	  audio_block_f32_t *audio_block, *audio_block_sc;
          audio_block = AudioStream_F32::receiveWritable_f32(0);
    	  if (!audio_block) return;
    	  
    	  audio_block_sc = AudioStream_F32::receiveReadOnly_f32(1);	  
          /*if (!audio_block_sc) {
    		release(audio_block);
    		return;
    		}
    		*/
          //apply a high-pass filter to get rid of the DC offset
          if (use_HP_prefilter) arm_biquad_cascade_df1_f32(&hp_filt_struct, audio_block->data, audio_block->data, audio_block->length);
      
    	  //apply the pre-gain...a negative gain value will disable
          //if (pre_gain > 0.0f) arm_scale_f32(audio_block->data, pre_gain, audio_block->data, audio_block->length); //use ARM DSP for speed!
    
          //calculate the level of the audio (ie, calculate a smoothed version of the signal power)
          audio_block_f32_t *audio_level_dB_block = AudioStream_F32::allocate_f32();
          calcAudioLevel_dB(audio_block, audio_level_dB_block); //returns through audio_level_dB_block
    
          //compute the desired gain based on the observed audio level
          audio_block_f32_t *gain_block = AudioStream_F32::allocate_f32();
          calcGain(audio_level_dB_block, gain_block);  //returns through gain_block
    	 
          //apply the desired gain...store the processed audio back into audio_block
    	  //if sideChain is activated it affects the other input with the calculated gain.
    	   if (!sideChain) arm_mult_f32(audio_block->data, gain_block->data, audio_block->data, audio_block->length);
    	   else arm_mult_f32(audio_block_sc->data, gain_block->data, audio_block->data, audio_block->length);
    	  
    	  //arm_mult_f32(audio_block->data, gain_block->data, audio_block->data, audio_block->length);
    
          //transmit the block and release memory
          AudioStream_F32::transmit(audio_block);
          AudioStream_F32::release(audio_block_sc);	  
          AudioStream_F32::release(audio_block);		  
          AudioStream_F32::release(gain_block);
          AudioStream_F32::release(audio_level_dB_block);	  
        }

  21. #21
    Senior Member
    Join Date
    Jul 2014
    Posts
    139
    Add this as a private variable to your class:
    Code:
    audio_block_t *inputQueueArray_i16[2];
    Edit: Looking at the float fork of AudioConnection, I'm not sure if my suggestion is helpful. It would be how you'd fix it in the standard library.
    Last edited by macaba; 05-08-2017 at 10:44 PM.

  22. #22
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    macaba nailed it (except for the data type). The problem is that I defined my class to only accept a single channel of data. The class definition needs to be tweaked to permit the second channel of input. Sorry that I didn't do that before. So, taking macaba's suggestion (but correcting the data type), you should modify the private section of AudioEffectCompressor o read:

    Code:
      private:
        //state-related variables
        audio_block_f32_t *inputQueueArray_f32[2]; //expand to allow *two* channels of input
    This will allow two float32_t audio blocks to be passed as inputs. In the update() function of the class, you can access the two inputs using the syntax that you've already shown....

    Code:
    audio_block_f32_t *block1 = AudioStream_F32::receiveReadOnly_f32(0); //first input
    audio_block_f32_t *block2 = AudioStream_F32::receiveReadOnly_f32(1); //second input
    Chip

  23. #23
    Member
    Join Date
    Nov 2015
    Location
    Norway
    Posts
    70
    Thank you both! That works perfectly =)

  24. #24
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    I made an enclosure for our device. Enclosures are hard!

    Basically, I had to give up on making something attractive and I simply had to focus on making it functional.

    Click image for larger version. 

Name:	Enclosed Tympan in Hand.png 
Views:	91 
Size:	758.5 KB 
ID:	10638

    More pictures and a link to CAD files: http://openaudio.blogspot.com/2017/0...ectronics.html

    It sure does take special skills to make something both functional and attractive. Electronics and software is way easier than industrial design. Wow.

    Chip

  25. #25
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    167
    I tested the Tympan with three different microphones.

    Click image for larger version. 

Name:	three mics.png 
Views:	71 
Size:	51.0 KB 
ID:	10646

    I measured their frequency response and scale factor. It was interesting to see how the microphones performed similarly and how they performed differently.

    Click image for larger version. 

Name:	Calibration for All Mics.png 
Views:	62 
Size:	42.9 KB 
ID:	10647

    If you want more details on how I did the calibration (including Arduino sketches, spectrograms and whatnot), you can check it out here: http://openaudio.blogspot.com/2017/0...th-tympan.html

    What other kinds of microphones might people find interesting?

    Chip

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •