How to calculate # of samples for creating a tuned single cycle wave?

Take sampling rate, divide by something, add this or that, what’s the formula? Can’t seem to find it.

Sampling rate (Hz) / Note frequency (Hz) = Samples per cycle.

For example, Middle C:
48000 Hz / 261.626 Hz = 183 samples (rounded down from 183.468…)

For a note frequency chart, you can use this:

dblue wins. :)

Does the rounding create non-ideal frequencies?

It certainly does, but usually only by a very small amount, which some people may not even be able to easily perceive. Nevertheless, you will need to compensate the fine tune value a bit if you care enough about this.

Quite a while ago, I’ve written my own Lua function to take care of this. I did not bother to turn it into a tool yet, so I just run it directly from the script editor whenever I need to.

To use it, you can select a single cycle within your sample waveform (or simply select the entire waveform if the whole thing is the cycle), then run this tuning function with your desired base frequency. It will then set the Transpose and Finetune properties to the closest possible match for that given frequency. You should obviously provide the most accurate base frequency you can, in order to get the best results, although 18 decimal places may be slightly overkill in this case, heh. Alternatively, you could simply use exactly A=440Hz and then manually adjust your Transpose afterwards to bring it back up to C. Your mileage may vary :slight_smile:

Code is included below. Feel free to use it in a tool, if you wish. I do seem to recall that someone has created a very similar tool, but the who/where/when of it escapes me at the moment.

(Another small note: This code is obviously geared towards the typical western tuning, aka 12-tone equal temperament)

local function tune_sample(sample, base_frequency)  
 local function round(value)  
 return math.floor(value + 0.5)  
 local buffer = sample.sample_buffer  
 local sample_rate = buffer.sample_rate  
 local loop_length = buffer.selection_end - buffer.selection_start + 1  
 local loop_frequency = sample_rate / loop_length  
 local ratio = base_frequency / loop_frequency  
 local cents = 1200.0 * math.log(ratio) / math.log(2)  
 local transpose = math.max(-120, math.min(120, round(cents / 100)))  
 local finetune = math.max(-127, math.min(127, round((cents - (transpose * 100)) * 1.27)))  
 sample.transpose = transpose  
 sample.fine_tune = finetune  
tune_sample(, 261.625565300598623000)  

Thanks dblue, I didn’t think of that before. I might use it to improve the tuning of Overtune
Isn’t finetune supposed to have


at the end though?
Ugh it’s too difficult to think about it right now :P

That would (potentially) result in a finetune value of -128 to 128, which is obviously out of bounds of the -127 to 127 range that finetune can be set to.

I’ve actually updated the code snippet above to clamp the transpose and finetune values to valid ranges. Thanks for reminding me that I needed to do that!

Similar to this tool then…