-
Updates - over 768 of them! ;)
11/14/2016 at 01:36 • 0 commentsWoo! Update time again!
Last time we talked, I had branched development of Volume into a second library allowing for custom waveforms like sine or sawtooth.
I've decided to branch again, to provide a third, higher-quality, lower-consumption library. Let's take a look at the specs!VOLUME3 LIBRARY:
10-bit Control - 768 more volume levels!
After adopting the lovely TimerOne library to drive this technique, Volume3 now offers 10-bit volume control, 0 - 1,023.
Only using Timer1!
Because of the lovely TimerOne lib, we can now produce our PWM AND the interrupts for driving waves on a single timer.
No More Awful Prescaler!
We're now producing the ultrasonic PWM on Timer 1, leaving that nasty Timer 0 to manage delay and millis() like normal with it's default 64x prescaler. This means you can now use the native delay/millis functions with Volume3!
No More God-Awful Distortion
As proud as I was of the first version, it had a characteristic "fizzle" when you lowered the volume of certain frequencies. This is virtually gone now, due to raising the PWM carrier frequency from 62,500 Hz to 100,000 Hz. Nice and clean now!
HOWEVER
I'm still going to actively maintain these three as SEPARATE libraries. I'll explain why after this table:
Volume Library Comparison:
Library Volume1 Volume2 Volume3 Accuracy 8-bit 8-bit 10-bit Frequency Range (Hz) 120 - 5,000 1 - 3,400 1 - 4,186 PWM Frequency (Hz) 62,500 62,500 100,000 Polyphony 1 1 1 Needs vol.begin() YES YES NO Compiled Library Size (Bytes) 2,501 2,542 1,054 RAM Usage (Bytes) 39 457 24 Frequency Slide Quality GREAT BAD GOOD Timer Usage 0, 1 0, 1 1 Delay Issue (Timer0 Prescaler) YES YES NO Square Wave YES YES YES Sawtooth Wave NO YES NO Triangle Wave NO YES NO Sine Wave NO YES NO As you can see, each library has it's strengths and weaknesses. Volume1 is best for range and slides, Volume2 is best for custom waveforms, and Volume3 is best for accuracy, size, and ease of use. Speaking of ease of use, here's a comparison of Volume1 and 3:
Volume1:
#include "Volume.h" Volume vol; uint16_t frequency = 440; void setup() { vol.begin(); vol.alternatePin(true); } void loop() { for(byte volume = 0; volume < 255; volume++){ vol.tone(frequency,volume); vol.delay(5); } for(byte volume = 255; volume > 0; volume--){ vol.tone(frequency,volume); vol.delay(5); } vol.noTone(); vol.delay(1000); }
Volume3:
#include "Volume3.h" uint16_t frequency = 440; void setup() {} void loop() { for(int volume = 0; volume < 1023; volume++){ vol.tone(10,frequency,volume); delay(3); } for(int volume = 1023; volume > 0; volume--){ vol.tone(10,frequency,volume); delay(3); } vol.noTone(); delay(1000); }
Several improvements have been made here:
- No more Volume class definition needed
- No more vol.begin() init needed
- No more special delay/millis functions
- Ability to use either Timer1 pin at will, no more vol.alternatePin()
- 10-bit accuracy, adding 768 new volume levels!
I'm still working on catching up Volume3 to include original functions like a master volume control and one-liner fades, but for now I'm sharing in excitement to see how people use the new library!
GIVE IT A GO!
https://github.com/connornishijima/arduino-volume3
I promise I'm not making a Volume4. ;)
- Connor
-
More waveforms? Sine me up!
09/02/2016 at 18:31 • 0 commentsI've branched development of the Volume library to a second version, which now supports multiple waveform types such as sine, sawtooth, and more!
NEW LIBRARY
This new Volume2 Library is not a successor, but a separate project I've decided to library-ize to see if people like it. Just like the Volume1 lib, it provides 8-bit volume control with no extra components. The kicker here is that now you can choose from the following waveform shapes:
SQUARE | Your friendly neighborhood square wave
PWM_12 | PWM "square" at 12.5% duty cycle
PWM_25 | PWM "square" at 25%. The NES used these PWM voices!
SAWTOOTH / SAWTOOTH_HIGH | Sawtooth wave, low and high quality
TRIANGLE / TRIANGLE_HIGH | Triangle wave, low and high quality
SINE / SINE_HIGH | Sine wave, low and high quality
CUSTOM | Custom 32-byte array defined by the user for custom voices
NOISE | Ignores frequency, returns fast volume-controlled RNG
The CUSTOM waveform is an exciting option. You can use this to define you own complex waveshapes to produce sound similar to things like pianos, guitars, cellos, and more. The array given must be 32 8-bit signed values. For example, this is an array for generating several square wave octaves:
byte wave[32] = { 255,255,192,192,192,192,128,128, 192,192,128,128,128,128,64,64, 192,192,128,128,128,128,64,64, 128,128,64,64,64,64,0,0, }; vol.setCustomWave(wave);
With this array, setting the frequency to 220 Hz will generate 220, 440, 880, and 1760 Hz simultaneously!
WHY DEVELOPMENT BRANCHED
While the new library is great at generating waves, it's max frequencies are lower and it doesn't handle fades well yet. For now, I'm keeping the two separate to allow people to choose what's best for their own needs until I can optimize each further for a smooth merge!
IN CONCLUSION
As always, I've provided a ton of documentation on the GitHub, and examples can be found as well. But the easiest way to try the Volume and Volume2 libraries is to grab them through the Arduino Library Manager!
- Connor
-
People were ready for this!
06/14/2016 at 02:41 • 0 commentsI developed this library for my own use in a fake "cricketuino" project.
Now thousands of people have tried it, broke it, forked it, and it even caught the eye of Atmel themselves after being posted on the main HaD blog. (Go follow / like Atmel on here by the way, we owe this awesome hardware platform to them!)
In return for all the love the lib has gotten this week, I've picked development back up, and expanded much-needed compatibility to the ATmega168 / 328 / 1280 / 2560 / 16u2 / 32u4! Because each of these boards ties Timer0 to different pins, the most recent release of the Volume lib no longer allows direct assignment of speaker pins.
Volume vol(speakerPin);
is now just:Volume vol;
With this change, a DEFAULT_PIN for each board is automatically defined, and you have the option to change it to the ALTERNATE_PIN Timer0 is also tied to for that board using:
vol.alternatePin(true);
Supported Pins:
Board DEFAULT_PIN ALTERNATE_PIN Tested (Uno) ATmega168/328(pb) 5 6 YES (Mega) ATmega1280/2560 4 13 YES (Leo/Micro) ATmega16u2/32u4 9 10 YES* *I recently killed my only ATmega32u4 board while stripping it for low-power usage and don't have one to test current releases of the library. If anyone who has a working one wants to report compatibility back to me, please do so as I've only tested the initial release!
Thank you all so much for the awesome support, let's work together to bring beautiful tones to more Arduinos! I'm currently working on the highly-demanded ATtiny support, more on that soon!
- Connor Nishijima