Go Down

Topic: How to calculate hyperbolic sine curves - for sound effects (Read 1 time) previous topic - next topic


I'm trying to build sound effects using code.  Ideally I want to manipulate the frequency curves to match the sounds of capacitors loading (like the old style photography flashes where you had to wait for the batteries to charge the capacitors).

A simple "X" for/next loop and changing the frequency multiplied by "X" makes a straight linear line and that's too vanilla for me.  I think I need a hyperbolic sine curve, but I am uncertain since this google-research has me almost as confused as trying to study a datasheet on a 128 pin chip, that's written in Chinese.

The closest thing I found was google search:

"graph of hyperbolic sine"

and it comes up with a little u/i where I can study the plotted numbers, and it gives me equasion:

Graph for (exp(​x)-​exp(​‑x))/​2

So this starts me off in the right direction.  I was hoping someone here had some advice what I can read about how to calculate these sine curves in a tutorial for dummies.  I really tried reading this for a bit, but most of the tutorials seem to assume I know what all these greek symbols are.  I am guessing whatever I am trying to do is probably an expert level math calculation for people trying to plot the course of a meteor.


Jan 06, 2017, 03:30 pm Last Edit: Jan 06, 2017, 10:59 pm by charliesixpack
You can do this by creating a digital filter and exciting it with either an impulse or the appropriate initial conditions.  This is how I created a sine wave on the Arduino.  Interestingly, the filters for sine and sinh have the same coefficients but different signs for the coefficients.

But, before you take the time to actually do that you should determine if that is the sound you want. You can do this with one line using Mathematica.  You can probably do it easily using puredata also.

Addendum:  Thinking about it I do not understand what you expect to hear.  There is no oscillation in the sinh function.  There is no audible content.  Are you looking to somehow modulate some audible signal with a sinh variation?


Jan 07, 2017, 02:13 pm Last Edit: Jan 07, 2017, 03:13 pm by GypsumFantastic Reason: Felt I should add a bit more
Addendum:  Thinking about it I do not understand what you expect to hear.  There is no oscillation in the sinh function.  There is no audible content.  Are you looking to somehow modulate some audible signal with a sinh variation?
DocStein is talking about the graph of frequency vs time, not the waveform

I think hyperbolic sine is an odd choice for what you need, but it's in math.h as sinh()


I think something like this might sound about right:

Code: [Select]

int endFreq = 5000; //final frequency in Hz adjust it to suit
int timebase = 5000; //sets the rate of change adjust it to suit

int freq = endFreq * (1 - exp(-(float)millis()/timebase));

I don't have an arduino to test this at the moment so you might have to tinker with it a bit.

A final note - camera flashes get quieter as they approach their final charge level too.


It is difficult for me to explain something when I don't know what I am doing, my apologies.

I'm not trying to manipulate the wave that generates the tone or pitch.  I want pitch modulation, change the value of a tone across a 1 second period of time.  I change the output steps of a pitch to climb in a sloped arc (like the camera flash sound).  The tone function from Arduino is a square wave by default - it works for the purposes of demonstration.

If I ramp from 100 HZ to 5000 hz, using a for/next loop and just change the tone based on the for/next variable "FREQ" it would produce a linear line from 100 - 5000.  I would like to learn the function I need to calculate "FREQ" a ease-in ease-out curve.

The volume of a camera flash is trivial, and my curve doesn't have to be exactly like the same curve of the charging capacitor of an actual camera - I just used this as an example to help me describe the sound effect I am trying to make.


Ah cool.

So how did the sinh() based pitch curve sound?


Jan 07, 2017, 07:34 pm Last Edit: Jan 07, 2017, 07:35 pm by charliesixpack
Something to consider is your sample rate.  Modulating the frequency with a sinh variation gives vastly different results depending on the sampling rate.  At the higher frequencies with a lower sampling rate you can get aliasing which gives a wah-wah effect.


I want pitch modulation, change the value of a tone across a 1 second period of time.  I change the output steps of a pitch to climb in a sloped arc (like the camera flash sound)
I would suggest that you use an exponential function to modify the frequency, after all that is what is really happening when a flash charges.


Jan 08, 2017, 01:18 pm Last Edit: Jan 08, 2017, 01:19 pm by charliesixpack
I would suggest that you use an exponential function to modify the frequency, after all that is what is really happening when a flash charges.
Hyperbolic sine IS exponential.


Jan 09, 2017, 02:41 pm Last Edit: Jan 09, 2017, 02:46 pm by Paul Stoffregen
On top of all these other issues, you're probably going to encounter problems due to limitations in Arduino's tone() function.

The main issue is calling tone() instantly reconfigures the hardware timer.  At least the tone() implementation currently in Arduino's core library for AVR does this.  Arduino Zero (Atmel SAMD), Arduino Due (Atmel SAM), Arduino 101 (Intel Curie) all have different tone implementations that may behave slightly differently, but most commonly a timer is used and the timer is immediately reconfigured while it's running.

Depending on the timing of the moment your code requests a new frequency, relative to the waveform's phase, you can get a variety of different results until the timer resets.  Then it will begin a new cycle which will be at the desired frequency.  But before that next cycle begins, the previous waveform cycle can become something much shorter (higher frequency) or longer (low frequency), depending on whether the hardware timer happened to be incrementing with a value lower or higher than the new setting.

If you only call tone() infrequently, it's not noticeable.  One bad cycle (neither the old nor the new frequency) among many thousands of good ones before and after the change isn't easily perceptible to humans.  But as you call tone() more rapidly, the effect becomes worse.  Depending on how the timer works in the chip you're using, it's also quite possible you'll sometimes reduce the timer threshold after the timer has already incremented past it.  That can result in 1 much longer stuck-high or stuck-low pulse until the timer rolls over and begins a new cycle at the new frequency.  You might think of 1 long pulse as a low frequency, but it actually has broad spectral content.

This issue came up several times with Teensy.  Many people attempt more complex projects on Teensy...  This tone issue is very subtle and difficult to understand.  Believe me, it's a hard issue that I've put a lot of effort into solving this problem well (on the newer 32 bit boards).  Several months ago, I redesigned tone() on Teensy 3.x to queue changes.  The current cycle is always completed, and then the new frequency begins when the waveform phase is at exactly zero degrees.  Any new tone() changes during the new waveform are written to the buffer, and the last tone setting during the current waveform becomes the next waveform's period.

Perhaps this will all be a non-issue for you.  Or maybe you'll even prefer the rich (but very code timing dependent) spread of other spectral content.  I actually have heard from someone who wanted that behavior, even believing that sound containing lots of other frequencies was correct because it's what you get out of Arduino Uno when running a tight loop that changes the tone.  But usually it's pretty easy to notice you're getting other sounds than you requested, if your code changes the tone setting rapidly enough.

Anyway, if you've taken the time to read this long-winded message, at least you'll know to look for this possible issue.


I can only understand so much at a given time, and between all the libraries I use there is no way for me to tell to be exact what's going on unless I straight out write everything from scratch myself.  I don't know if the timing from a frequency will change the serial port behavior or midi control translation.  I thought it would be nice to have nice shaped sounds for effects in my projects.  It seems the only safe way to do that is by slaving another Arduino as a dedicated synth out to use THAT as the sound generator while the other one does the controlling, timing and whatever else.

Go Up