digitalmars.D.learn - Dynamic pitch shift
- Tanel =?UTF-8?B?VGFnYXbDpGxp?= (15/15) Feb 24 2016 Hello!
- Tanel =?UTF-8?B?VGFnYXbDpGxp?= (5/5) Feb 24 2016 Sorry for the confusing state of the codebase.
- Luis (20/25) Feb 25 2016 Be careful with naive wave generators. You could get very funny
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/11) Feb 26 2016 I suggest just porting STK from C++ to D. It is well documented,
- Nicholas Wilson (10/25) Feb 24 2016 So the buffer holds one period of the waveform?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/15) Feb 24 2016 Generating a saw waveform for an LFO is the same as generating
- Guillaume Piolat (6/24) Feb 24 2016 dplug:dsp has mipmapped oscillators
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/6) Feb 24 2016 Why would it help to not use 2^n sized tables? I guess you could
- Guillaume Piolat (4/10) Feb 26 2016 We are not talking of the same thing. I was thinking about the
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (11/13) Feb 26 2016 Ok. I think is most common to use high levels of oversampling for
Hello! I've been making some progress on the native D audio front: https://github.com/clinei/daud/tree/28ac042a16ae6785605a9a501b5f867c8f962055 It's a continuous waveform generator, currently outputting a saw wave that changes pitch every 1K frames. I have a slight problem, however. Due to the frequency changing in the middle of a wave, I have to patch the new waveform together with the last, which I've done with `countUntil` at daud/gen.d:211 (I don't need to call popFrontN because the range is a reference type). However, when calling `RepeatingGenerator.frequency`, the value of `_repeat.front` is not the value of the last frame. app.d:61 is a temporary hack. How could I get the value currently passed through `cont` from `_repeat`?
Feb 24 2016
Sorry for the confusing state of the codebase. Only the saw wave generator is currently functional, the `saw` and `sine` functions are not used and should be left out of analysis. Also, audio output is only to ALSA.
Feb 24 2016
On Wednesday, 24 February 2016 at 11:17:27 UTC, Tanel Tagaväli wrote:Sorry for the confusing state of the codebase. Only the saw wave generator is currently functional, the `saw` and `sine` functions are not used and should be left out of analysis. Also, audio output is only to ALSA.Be careful with naive wave generators. You could get very funny artefacts from aliasing. You should try one of this approximations : - Correct naive wave generator : Use furrier composition to build the wave (ie, sum i=1->n An*sin(Wn*t + phase)), On this case, should drop of the sumatory the sin that generate armonics >= (Niquist freq)/2 This way, at least should be enough for sound testing, but isn't very efficient. See for example (C++) this Square wave generator against OpenAL (It needed some tweaks about just what you asked on the first post. The phase wasn't correct, but was enough for me on these moment) : https://github.com/Zardoz89/trillek-vcomputer-module/blob/78c9dd7bf0ead23cb9a8ccf29fd30c9d0ed7e2e5/tools/src/AlEngine.cpp#L210 - Wavetables - band-limited resampling algorithm aka BLIP or BLEP algorithms (See http://www.cs.cmu.edu/~eli/L/icmc01/hardsync.html and http://slack.net/~ant/libs/audio.html#Blip_Buffer )
Feb 25 2016
On Thursday, 25 February 2016 at 15:15:20 UTC, Luis wrote:- Wavetables - band-limited resampling algorithm aka BLIP or BLEP algorithms (See http://www.cs.cmu.edu/~eli/L/icmc01/hardsync.html and http://slack.net/~ant/libs/audio.html#Blip_Buffer )I suggest just porting STK from C++ to D. It is well documented, suitable for a D-range implementation, is written for clarity over speed and uses a BSD license: https://ccrma.stanford.edu/software/stk/ https://github.com/thestk/stk/blob/master/include/Blit.h It also contains a wide range of physical models (waveguides etc).
Feb 26 2016
On Wednesday, 24 February 2016 at 10:33:56 UTC, Tanel Tagaväli wrote:Hello! I've been making some progress on the native D audio front: https://github.com/clinei/daud/tree/28ac042a16ae6785605a9a501b5f867c8f962055 It's a continuous waveform generator, currently outputting a saw wave that changes pitch every 1K frames. I have a slight problem, however. Due to the frequency changing in the middle of a wave, I have to patch the new waveform together with the last, which I've done with `countUntil` at daud/gen.d:211 (I don't need to call popFrontN because the range is a reference type). However, when calling `RepeatingGenerator.frequency`, the value of `_repeat.front` is not the value of the last frame. app.d:61 is a temporary hack. How could I get the value currently passed through `cont` from `_repeat`?So the buffer holds one period of the waveform? I'm assuming that you are nowhere near the Niquist limit. What is your harmonic distortion rate like? If it's just for audio how much additional distortion would you gain from just resetting the wave from the beginning? Also your static if (false) for debugging ... debug(statement) is a thing for a reason :) Nic
Feb 24 2016
On Wednesday, 24 February 2016 at 10:33:56 UTC, Tanel Tagaväli wrote:Hello! I've been making some progress on the native D audio front: https://github.com/clinei/daud/tree/28ac042a16ae6785605a9a501b5f867c8f962055 It's a continuous waveform generator, currently outputting a saw wave that changes pitch every 1K frames.Generating a saw waveform for an LFO is the same as generating the phase, which is easy to do with using D's modular integers. Just add the delta and let it wrap. If you are generating it for a VCO then you need a bandlimited oscilator: https://ccrma.stanford.edu/~juhan/vas.html (Abrupt changes in pitch will cause a discontinuity in the second derived which is audible, so you might want to interpolate.)
Feb 24 2016
On Wednesday, 24 February 2016 at 14:02:49 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 24 February 2016 at 10:33:56 UTC, Tanel Tagaväli wrote:dplug:dsp has mipmapped oscillators https://github.com/p0nce/dplug/blob/master/dsp/dplug/dsp/wavetable.d Though it isn't fantastic aliasing-wise on the last octave, I should try something than power-of-2s next time I need it.Hello! I've been making some progress on the native D audio front: https://github.com/clinei/daud/tree/28ac042a16ae6785605a9a501b5f867c8f962055 It's a continuous waveform generator, currently outputting a saw wave that changes pitch every 1K frames.Generating a saw waveform for an LFO is the same as generating the phase, which is easy to do with using D's modular integers. Just add the delta and let it wrap. If you are generating it for a VCO then you need a bandlimited oscilator: https://ccrma.stanford.edu/~juhan/vas.html (Abrupt changes in pitch will cause a discontinuity in the second derived which is audible, so you might want to interpolate.)
Feb 24 2016
On Wednesday, 24 February 2016 at 17:52:39 UTC, Guillaume Piolat wrote:Though it isn't fantastic aliasing-wise on the last octave, I should try something than power-of-2s next time I need it.Why would it help to not use 2^n sized tables? I guess you could compute everything at 88khz and decimate...
Feb 24 2016
On Thursday, 25 February 2016 at 07:02:24 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 24 February 2016 at 17:52:39 UTC, Guillaume Piolat wrote:We are not talking of the same thing. I was thinking about the table frequency cutoff which is 2x lower every level of mipmapThough it isn't fantastic aliasing-wise on the last octave, I should try something than power-of-2s next time I need it.Why would it help to not use 2^n sized tables? I guess you could compute everything at 88khz and decimate...
Feb 26 2016
On Friday, 26 February 2016 at 13:21:12 UTC, Guillaume Piolat wrote:We are not talking of the same thing. I was thinking about the table frequency cutoff which is 2x lower every level of mipmapOk. I think is most common to use high levels of oversampling for tables so one can get better SNR using cheap interpolation. But I've lately thought a bit about encoding the complexity of a segment of the function in the table so that the renderer can choose an interpolation technique that matches the location in the table (e.g. straight line, use lerp; high frequency wobble, use sinc). To make it work for realtime one would have to track the cost and revert to lower quality when the budget has been spent.
Feb 26 2016