Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: FM modulation of wavetable

  1. #1

    FM modulation of wavetable

    Hello all,

    I am looking to begin creating a custom audio block for wavetable modulation. Any pointers on how to get it done? I have compiled 400+ single cycle waveforms into an Sf2 that will fit in the teensy 4.0 flash, and would like to be able to use those as carriers. I have also wondered if it would be more advisable to approximate the single cycle wave forms with power series or linear piecewise approximation thereof? Thus far I have avoided this as it seems it would be rather time consuming to do this for 500+ waveforms
    Last edited by RABB17; 01-17-2020 at 07:38 PM. Reason: clarity

  2. #2
    This link demonstrates what I am trying to achieve. http://https://youtu.be/K2u7b21JYVo?t=156 I imagine it would go something like subbing in the wavetable audio block into the shapedata in AudioSynthWaveformModulated?

  3. #3
    Code:
    /**
     * @brief Set various integer offsets to values that will produce intended frequencies
     * @details the main integer offset, tone_incr, is used to step through the current sample's 16-bit PCM audio sample.
     * Specifically, the tone_incr is the rate at which the interpolation code in update() steps through uint32_t space.
     * The remaining offset variables represent a minimum and maximum offset allowed for tone_incr, which allows for low-frequency
     * variation in playback frequency (aka vibrato). Further details on implementation in update() and in sample_data.h.
     *
     * @param freq frequency of the generated output (between 0 and the board-specific sample rate)
     */
    ^does this indicate that FM would be possible by adjusting the offsets?

  4. #4
    Senior Member
    Join Date
    Feb 2015
    Posts
    163
    Why not use the multiply block to modulate the wavetable waveform with some other waveform?

  5. #5
    Quote Originally Posted by wcalvert View Post
    Why not use the multiply block to modulate the wavetable waveform with some other waveform?
    You know, considering I was just messing with the very same thing, I don't know why I didn't consider that. I think I put it out of my mind because when I compared the multiply fm output to the waveformmod output I was noticing variations with the waveforms generated. I wasn't sure which one was more "correct" barring further analysis which unfortunately I haven't had the time to do.

    Today, when I was going through synthwaveform.cpp I noticed this:

    Code:
    // uncomment for more accurate but more computationally expensive frequency modulation
    //#define IMPROVE_EXPONENTIAL_ACCURACY
    I imagine I could simply cut and paste the multiply directly from the code into a custom multiply object.

    Thanks for the suggestion!

  6. #6
    Quote Originally Posted by wcalvert View Post
    Why not use the multiply block to modulate the wavetable waveform with some other waveform?
    Wait, doesn't the multiply block perform AM? Not FM? I'm not 100% but I think you adjust the phase and the maths are different. I was planning to extrapolate the code from the audiowaveform modulated but it takes a bit to digest. If you can just use the multiply block that would save me the time but I am unsure how to do that, being under the impression it was for AM. I'm trying to find algorithms for FM specifically but it's not as easy as I was hoping. I have my old college DSP book around somewhere...

  7. #7
    Senior Member
    Join Date
    Feb 2015
    Posts
    163
    Oh that's right, I forgot it is AM. Additive synthesis is just not my thing.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,319
    This is the one you want for FM.

    https://www.pjrc.com/teensy/gui/?inf...eformModulated

    You can modulate frequency directly (the default way), or indirectly by phase modulation.

  9. #9
    Quote Originally Posted by PaulStoffregen View Post
    This is the one you want for FM.

    https://www.pjrc.com/teensy/gui/?inf...eformModulated

    You can modulate frequency directly (the default way), or indirectly by phase modulation.
    That's the one I have been using for FM, the early experiment I made used the multiply block with envelope and the waveform mod output to compare that results of that vs just running the waveformmod block into the envelope:
    https://forum.pjrc.com/threads/58984...t=synthesis"].

    Now I am trying to use a wavetable as a carrier for the modulation source. I had already hit upon the

    Code:
    	// Pre-compute the phase angle for every output sample of this update
    	ph = phase_accumulator;
    	priorphase = phasedata[AUDIO_BLOCK_SAMPLES-1];
    	if (moddata && modulation_type == 0) {
    		// Frequency Modulation
    		bp = moddata->data;
    		for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
    			int32_t n = (*bp++) * modulation_factor; // n is # of octaves to mod
    			int32_t ipart = n >> 27; // 4 integer bits
    			n &= 0x7FFFFFF;          // 27 fractional bits
    			#ifdef IMPROVE_EXPONENTIAL_ACCURACY
    			// exp2 polynomial suggested by Stefan Stenzel on "music-dsp"
    			// mail list, Wed, 3 Sep 2014 10:08:55 +0200
    			int32_t x = n << 3;
    			n = multiply_accumulate_32x32_rshift32_rounded(536870912, x, 1494202713);
    			int32_t sq = multiply_32x32_rshift32_rounded(x, x);
    			n = multiply_accumulate_32x32_rshift32_rounded(n, sq, 1934101615);
    			n = n + (multiply_32x32_rshift32_rounded(sq,
    				multiply_32x32_rshift32_rounded(x, 1358044250)) << 1);
    			n = n << 1;
    			#else
    			// exp2 algorithm by Laurent de Soras
    			// https://www.musicdsp.org/en/latest/Other/106-fast-exp2-approximation.html
    			n = (n + 134217728) << 3;
    			n = multiply_32x32_rshift32_rounded(n, n);
    			n = multiply_32x32_rshift32_rounded(n, 715827883) << 3;
    			n = n + 715827882;
    			#endif
    			uint32_t scale = n >> (14 - ipart);
    			uint64_t phstep = (uint64_t)inc * scale;
    			uint32_t phstep_msw = phstep >> 32;
    			if (phstep_msw < 0x7FFE) {
    				ph += phstep >> 16;
    			} else {
    				ph += 0x7FFE0000;
    			}
    			phasedata[i] = ph;
    		}
    		release(moddata);
    	} else if (moddata) {
    		// Phase Modulation
    		bp = moddata->data;
    		for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
    			// more than +/- 180 deg shift by 32 bit overflow of "n"
    			uint32_t n = (uint16_t)(*bp++) * modulation_factor;
    			phasedata[i] = ph + n;
    			ph += inc;
    		}
    		release(moddata);
    as the bit I need I just don't fully understand the magic yet. Any suggestions as to routing the audio from a wavetable to be the carrier source?

  10. #10
    Quote Originally Posted by wcalvert View Post
    Oh that's right, I forgot it is AM. Additive synthesis is just not my thing.
    no worries I appreciate the help

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •