sensorium / Mozzi

sound synthesis library for Arduino
https://sensorium.github.io/Mozzi/
GNU Lesser General Public License v2.1
1.05k stars 184 forks source link

High pitched squeal #4

Closed mtedesco closed 11 years ago

mtedesco commented 11 years ago

On an Arduino Diecimila (ATmega168), when running the Example sketches, I hear a high pitched squeal somewhere in the vicinity of dog-whistle frequency space.

Is the library specific to certain Arduino boards (e.g. for timing purposes) ?

sensorium commented 11 years ago

Hi Mike, thanks for the alert. Mozzi's been developed and tested with 328 processors so far. I'm in the process of expanding the range of boards it can work on, so it will be more flexible soon.

Having not had the opportunity to test it myself, I'm surprised that it's not working properly on the 168. Do all of the examples have the same whistling sound? Would you be able to check what frequency it's at (by plotting the spectrum with Audacity or similar)?

Section 2.2 of the atmega document for the ATmega48P, ATmega88P, ATmega168P, and ATmega328P says they differ only in memory sizes, boot loader support, and interrupt vector sizes. atmega 168p 16k flash 512b eeprom 1k ram 2 instruction words per interrupt vector atmega 328p 32k flash 1k eeprom 2k ram 2 instruction words per interrupt vector

I wonder if there's a problem with something not fitting into memory (but there'd be a compiler error, I'd expect)?

Thanks again, I'd appreciate if you can let me know more about the frequency and perhaps you could send the compiler output (Arduino preferences -> show verbose output from compiler).

Cheers Tim

ps. I'll be away from the internet for a few days so apologies if I'm slow to reply.

mtedesco commented 11 years ago

Tim -

Thank you for the quick and detailed reply!

Given the level of precision and care that you took to author this library*, I'm amazed it doesn't just work out of the box myself, because I triple-checked the ATmega specs after encountering this issue, and saw the same as you did - that the specs claim very little difference between the chips.

I would be happy to capture the generated detailed compiler output, upload output, sound output, and frequency spectrum from the older 168 class atmega and send it to you.

I should have the time to get back to the workbench this weekend, and I will do it then. Meantime, enjoy your travels.

Best,

Mike

sensorium commented 11 years ago

Hi Mike, no camping, the weather's too bad.

I wonder if your board/chip is running at 16MHz? I noticed quite a few versions clocked at 8MHz - saves power I guess. Something to check, anyway.

Otherwise, thanks, it would be great if you can send that info and a recording.

Tim

mtedesco commented 11 years ago

Tim -

Sorry about the weather!!

For the record, do not feel you need to waste time on fixing support for arduinoized 168's if it turns out they are hard to deal with... I'm happy to buy a 328 class arduino for sound projects since that is what has been tested and verified. I assume you are academically curious, as am I, so I will provide the details you requested. But please feel comfortable stating the hardware requirement as a firm 328 if that should indeed turn out to be the best course for your project.

I don't think GitHub allows attachments to the issues in the issue tracker, so I have placed the files here: http://app1.venturesoft.com/mozzi/168whistle.tar.gz

I tested the sine wave example and was able to see a spike on the frequency chart @ around 16Khz.

I decided to go further and modify the audio output routine to return Zero. This also generated a spike on the frequency chart @ 16Khz. This, to me, is the most convincing representation of the issue.

Frequency analysis was done using Audacity as requested. The log/spectrum view helps make the spike apparent and distinct from the generated sine, and also from the noise floor.

I'm pretty sure the board is at 16Mhz, that the crystal it is clocked to. (It is an official Arduino board). I have not modified the bootloader, so I think the bootloader is clocked to 16Mhz but I do not know how to check that offhand.

Let me know if I have made any errors or missed/misunderstood something along the way.

Tim, thanks again for the replies. I'll wish for better weather in your part of the world!

Mike Tedesco Venturesoft.com

sensorium commented 11 years ago

Hi Mike,

ah! Yes I could hear that sound via the fillings in my teeth.

Thanks very much for posting your tests, it's not a waste of time for me, it helps in the process of development.

OK, long reply, skip to the bottom if you want.

I'm glad you've brought this up, because it's got me re-thinking a few things.

I haven't taken much notice of that sound before, assuming it's an unavoidable side-effect of PWM, a 16kHz sample rate and 8 bit audio. I've usually low pass filtered the audio to reduce the PWM artifacts, smooth the lo-fi character and make it easier to read in a wave editor.

While reproducing your tests here, I noticed the sample rate of your files at 41000Hz. I've been recording at 96000 (for no particular reason) and thought you might be getting more audible aliasing between the PWM and your lower sample rate. Trying a few different recording frequencies, I found (duh) that using Mozzi's sample rate of 16384Hz gave a clear waveform without all the messy PWM scribble, and without any filtering. A signal of 0 looks flat, instead of showing a full-volume PWM aliasing signal. The spectrum of a 0 signal still has a spike at 16384Hz, but it's narrower than at eg. 41000Hz, and there are no side-bands.

So I could say to low pass filter the audio at about 8kHz or a bit lower, but I'm going to look again at how the PWM is working. As I understand it at the moment, a signal of 0 gives a duty cycle of 50%. I need to see if that's what's really happening and if it's the only way to do it.

If you do just want to filter it for now, it seems OK for me with an RC filter consisting of a 270 ohm resistor between the audio out pin 9 and whatever you use for the actual line out, and a .1uf capacitor from there to ground. I think this rolls off at about 6000Hz. I can't hear the squeal with this on.

Any corrections or help are welcome if anyone reads this and has other ideas!

Tim

mtedesco commented 11 years ago

Thanks Tim. I'll give the RC filter a try and reply back with results. Might not get to it until next weekend, full plate of work this week.

sensorium commented 11 years ago

Mike, while checking things I came across this clear explanation of PWM audio: http://www.youtube.com/watch?v=4byHVqXD-UI And this link shows how filtering works with PWM: http://electronics.stackexchange.com/questions/34843/how-determine-the-rc-time-constant-in-pwm-digital-to-analog-low-pass-filter

In Mozzi, when updateAudio() returns 0, it gets translated behind the scenes to 244, the halfway point of the PWM counter ramp, and it's an audible 16kHz ripple. I tried returning -244 from updateAudio(), and there's a flat silent output, since the PWM counter stays down at the bottom of its range.

mtedesco commented 11 years ago

Thanks Tim. Links were helpful, thanks for providing them. Yes, -244 has a flat silent output, and 0 is 50% duty cycle.

However, one RC filter alone isn't enough to make the output tolerable for kids. The high pitch squeal bothered them far too much when testing. To be honest, it was too audible for me too, but it REALLY hurt the kids ears. Since the project I'm working on is for schools, that's a usability issue I can't ignore. I've added four RC filters in series (220 ohm, 0.1uf) for now.... but its a real hack.

If you're curious, we've made a PING-ultrasonic "theremin" - so the output is amplified quite a bit.

I have a separate set of questions that aren't issues so I don't want to open up an issue on Github unless that's what you'd prefer. The questions relate to handling serial input in/out (serial display, potentially midi input) in a way that avoids delay() and other interrupts that interfere with Mozzi's timing routines. Is there a better way to contact you regarding these questions or is Git preferred?

Mike

sensorium commented 11 years ago

Hi Mike, that's really interesting about the kids, and also your hearing the squeal. I think I might have damaged the high frequency response of my ears through working as a musician with high sound levels, so even though it's clear to see in spectrum graphs, I haven't taken much notice.

Your experience provides a good reason to look further into better filter designs, but also perhaps an option for higher sample rate(s) for situations where the synthesis is not too cpu-intensive.

four RC filters in series What sort of waveform are you playing? You might be able to use just one filter with a much lower cutoff frequency, if you're using a sine tone, for example.

I'm very pleased that Mozzi's being used in for a project for schools. Will you have any online record, which could link off a projects page on the wiki?

I reckon the best place to ask/work out questions (which might turn into issues) is the Mozzi-users list ( https://groups.google.com/forum/#!forum/mozzi-users), which I hope will eventually turn into a useful resource. There's a topic started there about midi input which might be helpful if you need that.

Ask away with the serial questions...

Tim

On 9 September 2012 10:09, Mike Tedesco notifications@github.com wrote:

Thanks Tim. Links were helpful, thanks for providing them. Yes, -244 has a flat silent output, and 0 is 50% duty cycle.

However, one RC filter alone isn't enough to make the output tolerable for kids. The high pitch squeal bothered them far too much when testing. To be honest, it was too audible for me too, but it REALLY hurt the kids ears. Since the project I'm working on is for schools, that's a usability issue I can't ignore. I've added four RC filters in series (220 ohm, 0.1uf) for now.... but its a real hack.

If you're curious, we've made a PING-ultrasonic "theremin" - so the output is amplified quite a bit.

I have a separate set of questions that aren't issues so I don't want to open up an issue on Github unless that's what you'd prefer. The questions relate to handling serial input in/out (serial display, potentially midi input) in a way that avoids delay() and other interrupts that interfere with Mozzi's timing routines. Is there a better way to contact you regarding these questions or is Git preferred?

Mike

— Reply to this email directly or view it on GitHubhttps://github.com/sensorium/Mozzi/issues/4#issuecomment-8399294.

mtedesco commented 11 years ago

Not sure if they'll record anything - schools in Connecticut have all sorts of privacy rules - but I can ask!

I've been sticking to the SIN, TRI, SAW, and SQUARE waveforms, but I've tried all of them except the bamboo collection. It doesn't matter what waveform is used.

One other thing I forgot to mention - the issue is present on an Uno (328) as well as a Diecimila (168). I was unable to compile and load Mozzi onto a Mega 2560 - not sure why.

Anyhow, thanks again for the replies and education. I will close this ticket, I can't imagine a software resolution to it unless Mozzi's sample rate is more than doubled, and I'll stick with the 4 RC filters. Will see you in Google Groups regarding midi/serial-

Best, Mike

mgalardini commented 11 years ago

Hi,

i'm experimenting your amazing library with some friends on an Arduino UNO r3, and we have noticed the same high pitched squeal as @mtedesco: we tried to subtract 244 to the final value in the updateAudio() function. The high pitch disappears, but the sound becomes quite distorted as well.

We are using some Wii nunchuk signals in the updateControl() function, so we can't use an high CONTROL_RATE value, otherwise the communication with the nunchuk doesn't work properly (we currently use a value of 64).

We haven't tested a RC filter yet, but i was wondering if you may have any other suggestion to solve this problem or if you have already planned some modifications to your code.

Thanks a lot, and keep up with the amazing work. Marco

mtedesco commented 11 years ago

I personally haven't found a solution past the 4-staged RC filters. Even then I can still hear the squeal at loud volumes. I would be very interested in any results, fixes, or alternatives you come up with.

sensorium commented 11 years ago

Have you tried the notch filter described here? https://github.com/sensorium/Mozzi/wiki/Output-circuits,-filters,-amplifiers,-etc.-%28*-this-has-content%29

I'm also exploring adding an option to use this kind of output: http://blog.makezine.com/2008/05/29/makeit-protodac-shield-fo/ It has the advantage of no PWM carrier frequency noise which you're hearing, but the disadvantages of limiting output to 8 bits and using lots of pins on the Arduino.

doctroid commented 11 years ago

Has anyone looked into getting Mozzi working on the Arduino Due?

The Due has much higher clock speed, more I/O pins, and, addressing this particular issue, two 10-bit DACs built in. I'm no expert on these things but I have the impression it could be a killer synthesis board.

sensorium commented 11 years ago

Yes this is an excellent suggestion.
Mozzi should be ported to the ARM cortex processors.
I don't know if it's going to be me who does it!
I would like it very much if Mozzi eventually grows into a community project.
As it is, every time I start work on a creative project, I find another part of the existing library needs developing.
I'm not an engineer or programmer, but (failing as) an artist. The thought of diving into a 1,467 page technical manual doesn't appeal much at the moment!

sensorium commented 11 years ago

As of update 0.01.1v, Mozzi has a "hifi" audio option with 14 bit resoltuion and 125kHz PWM, moving the carrier frequency out of hearing range.