Ver código fonte

Add AudioSynthWaveformModulated documentation

dds
PaulStoffregen 6 anos atrás
pai
commit
c50086b93a
4 arquivos alterados com 276 adições e 1 exclusões
  1. +136
    -0
      examples/Synthesis/WaveformsModulated/WaveformsModulated.ino
  2. +47
    -0
      examples/Synthesis/WaveformsModulated/myWaveform.ino
  3. BIN
      gui/img/waveformsmod.png
  4. +93
    -1
      gui/index.html

+ 136
- 0
examples/Synthesis/WaveformsModulated/WaveformsModulated.ino Ver arquivo

@@ -0,0 +1,136 @@
// Waveform Modulation Example - Create waveforms with
// modulated frequency
//
// This example is meant to be used with 3 buttons (pin 0,
// 1, 2) and 2 knobs (pins 16/A2, 17/A3), which are present
// on the audio tutorial kit.
// https://www.pjrc.com/store/audio_tutorial_kit.html
//
// Use an oscilloscope to view the 2 waveforms.
//
// Button0 changes the waveform shape
//
// Knob A2 changes the amount of frequency modulation
//
// Knob A3 varies the shape (only for Pulse & Variable Triangle)
//
// This example code is in the public domain.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>

AudioSynthWaveformSine sine1; //xy=131,97
AudioSynthWaveformSine sine2; //xy=152,170
AudioSynthWaveformModulated waveformMod1; //xy=354,69
AudioOutputAnalogStereo dacs1; //xy=490,209
AudioOutputI2S i2s1; //xy=532,140
AudioConnection patchCord1(sine1, 0, i2s1, 1);
AudioConnection patchCord2(sine1, 0, dacs1, 1);
AudioConnection patchCord3(sine1, 0, waveformMod1, 0);
AudioConnection patchCord4(sine2, 0, waveformMod1, 1);
AudioConnection patchCord5(waveformMod1, 0, i2s1, 0);
AudioConnection patchCord6(waveformMod1, 0, dacs1, 0);
AudioControlSGTL5000 sgtl5000_1; //xy=286,240

Bounce button0 = Bounce(0, 15);
Bounce button1 = Bounce(1, 15);
Bounce button2 = Bounce(2, 15);

int current_waveform=0;

extern const int16_t myWaveform[256]; // defined in myWaveform.ino

void setup() {
Serial.begin(9600);
pinMode(0, INPUT_PULLUP);
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);

delay(300);
Serial.println("Waveform Modulation Test");
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(12);

// Comment these out if not using the audio adaptor board.
sgtl5000_1.enable();
sgtl5000_1.volume(0.8); // caution: very loud - use oscilloscope only!

// Confirgure both to use "myWaveform" for WAVEFORM_ARBITRARY
waveformMod1.arbitraryWaveform(myWaveform, 172.0);

// Configure for middle C note without modulation
waveformMod1.frequency(261.63);
waveformMod1.amplitude(1.0);
sine1.frequency(20.3); // Sine waves are low frequency oscillators (LFO)
sine2.frequency(1.2);

current_waveform = WAVEFORM_TRIANGLE_VARIABLE;
waveformMod1.begin(current_waveform);

// uncomment to try modulating phase instead of frequency
//waveformMod1.phaseModulation(720.0);
}

void loop() {
// Read the buttons and knobs, scale knobs to 0-1.0
button0.update();
button1.update();
button2.update();
float knob_A2 = (float)analogRead(A2) / 1023.0;
float knob_A3 = (float)analogRead(A3) / 1023.0;

// use Knobsto adjust the amount of modulation
sine1.amplitude(knob_A2);
sine2.amplitude(knob_A3);

// Button 0 or 2 changes the waveform type
if (button0.fallingEdge() || button2.fallingEdge()) {
switch (current_waveform) {
case WAVEFORM_SINE:
current_waveform = WAVEFORM_SAWTOOTH;
Serial.println("Sawtooth");
break;
case WAVEFORM_SAWTOOTH:
current_waveform = WAVEFORM_SAWTOOTH_REVERSE;
Serial.println("Reverse Sawtooth");
break;
case WAVEFORM_SAWTOOTH_REVERSE:
current_waveform = WAVEFORM_SQUARE;
Serial.println("Square");
break;
case WAVEFORM_SQUARE:
current_waveform = WAVEFORM_TRIANGLE;
Serial.println("Triangle");
break;
case WAVEFORM_TRIANGLE:
current_waveform = WAVEFORM_TRIANGLE_VARIABLE;
Serial.println("Variable Triangle");
break;
case WAVEFORM_TRIANGLE_VARIABLE:
current_waveform = WAVEFORM_ARBITRARY;
Serial.println("Arbitary Waveform");
break;
case WAVEFORM_ARBITRARY:
current_waveform = WAVEFORM_PULSE;
Serial.println("Pulse");
break;
case WAVEFORM_PULSE:
current_waveform = WAVEFORM_SAMPLE_HOLD;
Serial.println("Sample & Hold");
break;
case WAVEFORM_SAMPLE_HOLD:
current_waveform = WAVEFORM_SINE;
Serial.println("Sine");
break;
}
waveformMod1.begin(current_waveform);
}
}


+ 47
- 0
examples/Synthesis/WaveformsModulated/myWaveform.ino Ver arquivo

@@ -0,0 +1,47 @@

const int16_t myWaveform[256] = {
0, 1895, 3748, 5545, 7278, 8934, 10506, 11984, 13362, 14634,
15794, 16840, 17769, 18580, 19274, 19853, 20319, 20678, 20933, 21093,
21163, 21153, 21072, 20927, 20731, 20492, 20221, 19929, 19625, 19320,
19022, 18741, 18486, 18263, 18080, 17942, 17853, 17819, 17841, 17920,
18058, 18254, 18507, 18813, 19170, 19573, 20017, 20497, 21006, 21538,
22085, 22642, 23200, 23753, 24294, 24816, 25314, 25781, 26212, 26604,
26953, 27256, 27511, 27718, 27876, 27986, 28049, 28068, 28047, 27989,
27899, 27782, 27644, 27490, 27326, 27159, 26996, 26841, 26701, 26582,
26487, 26423, 26392, 26397, 26441, 26525, 26649, 26812, 27012, 27248,
27514, 27808, 28122, 28451, 28787, 29124, 29451, 29762, 30045, 30293,
30495, 30643, 30727, 30738, 30667, 30509, 30254, 29897, 29433, 28858,
28169, 27363, 26441, 25403, 24251, 22988, 21620, 20150, 18587, 16939,
15214, 13423, 11577, 9686, 7763, 5820, 3870, 1926, 0, -1895,
-3748, -5545, -7278, -8934,-10506,-11984,-13362,-14634,-15794,-16840,
-17769,-18580,-19274,-19853,-20319,-20678,-20933,-21093,-21163,-21153,
-21072,-20927,-20731,-20492,-20221,-19929,-19625,-19320,-19022,-18741,
-18486,-18263,-18080,-17942,-17853,-17819,-17841,-17920,-18058,-18254,
-18507,-18813,-19170,-19573,-20017,-20497,-21006,-21538,-22085,-22642,
-23200,-23753,-24294,-24816,-25314,-25781,-26212,-26604,-26953,-27256,
-27511,-27718,-27876,-27986,-28049,-28068,-28047,-27989,-27899,-27782,
-27644,-27490,-27326,-27159,-26996,-26841,-26701,-26582,-26487,-26423,
-26392,-26397,-26441,-26525,-26649,-26812,-27012,-27248,-27514,-27808,
-28122,-28451,-28787,-29124,-29451,-29762,-30045,-30293,-30495,-30643,
-30727,-30738,-30667,-30509,-30254,-29897,-29433,-28858,-28169,-27363,
-26441,-25403,-24251,-22988,-21620,-20150,-18587,-16939,-15214,-13423,
-11577, -9686, -7763, -5820, -3870, -1926
};

/*
#! /usr/bin/perl
$len = 256;
print "const int16_t myWaveform[256] = {\n";
for ($i=0; $i < $len; $i++) {
$x = $i / $len * 2 * 3.141592654;
$r = $x - 0.12486762;
$y = 0.95 * sin($r) + 0.25 * sin($r * 3 + 0.7) + 0.15 * sin($r * 5 - 5.4);
#print "$x $y\n";
$d = sprintf "%.0f", $y * 32767.0;
printf "%6d", $d + 0;
print "," if ($i < $len-1);
print "\n" if ($i % 10) == 9;
}
print "\n" unless ($len % 10) == 9;
print "};\n";
*/

BIN
gui/img/waveformsmod.png Ver arquivo

Antes Depois
Largura: 240  |  Altura: 408  |  Tamanho: 51KB

+ 93
- 1
gui/index.html Ver arquivo

@@ -375,7 +375,7 @@ span.mainfunction {color: #993300; font-weight: bolder}
{"type":"AudioSynthWaveformSineHires","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine_hires","inputs":0,"outputs":2,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveformSineModulated","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine_fm","inputs":1,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveform","data":{"defaults":{"name":{"value":"new"}},"shortName":"waveform","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveformModulated","data":{"defaults":{"name":{"value":"new"}},"shortName":"waveform","inputs":2,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveformModulated","data":{"defaults":{"name":{"value":"new"}},"shortName":"waveformMod","inputs":2,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveformPWM","data":{"defaults":{"name":{"value":"new"}},"shortName":"pwm","inputs":1,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthToneSweep","data":{"defaults":{"name":{"value":"new"}},"shortName":"tonesweep","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
{"type":"AudioSynthWaveformDc","data":{"defaults":{"name":{"value":"new"}},"shortName":"dc","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}},
@@ -1982,6 +1982,10 @@ The actual packets are taken
<p class=func><span class=keyword>amplitude</span>(level);</p>
<p class=desc>Change the amplitude. Set to 0 to turn the signal off.
</p>
<p class=func><span class=keyword>offset</span>(level);</p>
<p class=desc>Add a DC offset, from -1.0 to +1.0. Useful for generating
waveforms to use as control or modulation signals.
</p>
<p class=func><span class=keyword>phase</span>(angle);</p>
<p class=desc>
Cause the generated waveform to jump to a specific point within
@@ -2002,6 +2006,8 @@ The actual packets are taken
do this automatically.
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; Synthesis &gt; Waveforms
</p>
<p class=exam>File &gt; Examples &gt; Audio &gt; Synthesis &gt; PlaySynthMusic
</p>
<p class=exam>File &gt; Examples &gt; Audio &gt; Synthesis &gt; pulseWidth
@@ -2030,6 +2036,92 @@ The actual packets are taken
</div>
</script>

<script type="text/x-red" data-help-name="AudioSynthWaveformModulated">
<h3>Summary</h3>
<div class=tooltipinfo>
<p>Create a waveform <b>with modulation</b>: sine, sawtooth, square, triangle, pulse, random S&H or arbitrary.</p>
<p align=center><img src="img/waveformsmod.png"></p>
</div>
<h3>Audio Connections</h3>
<table class=doc align=center cellpadding=3>
<tr class=top><th>Port</th><th>Purpose</th></tr>
<tr class=odd><td align=center>In 0</td><td>Frequency or Phase</td></tr>
<tr class=odd><td align=center>In 1</td><td>Shape (Pulse &amp; Var Triangle)</td></tr>
<tr class=odd><td align=center>Out 0</td><td>Waveform Output</td></tr>
</table>
<h3>Functions</h3>
<p class=func><span class=keyword>begin</span>(waveform);</p>
<p class=desc>Configure the waveform type to create.
</p>
<p class=func><span class=keyword>begin</span>(level, frequency, waveform);</p>
<p class=desc>Output a waveform, and set the amplitude and base frequency.
</p>
<p class=func><span class=keyword>frequency</span>(freq);</p>
<p class=desc>Change the base (unmodulated) frequency.
</p>
<p class=func><span class=keyword>amplitude</span>(level);</p>
<p class=desc>Change the amplitude. Set to 0 to turn the signal off.
</p>
<p class=func><span class=keyword>offset</span>(level);</p>
<p class=desc>Add a DC offset, from -1.0 to +1.0. Useful for generating
waveforms to use as control or modulation signals.
</p>
<p class=func><span class=keyword>frequencyModulation</span>(octaves);</p>
<p class=desc>
Configure for frequency modulation mode (the default) where the
input signal will adjust the frequency by a specific number of
octaves (the default is 8 octaves). If the -1.0 to +1.0 signal
represents a &plusmn;10 volt range and you wish to have control
at 1 volt/octave, then configure for 10 octaves range. The
maximum modulation sensitivity is 12 octaves.
</p>
<p class=func><span class=keyword>phaseModulation</span>(degrees);</p>
<p class=desc>
Configure for phase modulation mode where the input signal will
adjust the waveform phase angle a specific number of degrees.
180.0 allows a full scale &plusmn;1.0 signal to span 1 full
cycle of the waveform. Maximum modulation sensitivity is 9000
degrees (&plusmn;25 cycles).
</p>
<p class=func><span class=keyword>arbitraryWaveform</span>(array, maxFreq);</p>
<p class=desc>
Configure the waveform to be used with WAVEFORM_ARBITRARY. Array
must be an array of 256 samples. Currently, the data is used
without any filtering, which can cause aliasing with frequencies
above 172 Hz. For higher frequency output, you must bandwidth
limit your waveform data. Someday, "maxFreq" will be used to
do this automatically.
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; Synthesis &gt; WaveformsModulated
</p>
<h3>Notes</h3>
<p>Supported Waveforms:<br>
<ul>
<li><span class=literal>WAVEFORM_SINE</span></li>
<li><span class=literal>WAVEFORM_SAWTOOTH</span></li>
<li><span class=literal>WAVEFORM_SAWTOOTH_REVERSE</span></li>
<li><span class=literal>WAVEFORM_SQUARE</span></li>
<li><span class=literal>WAVEFORM_TRIANGLE</span></li>
<li><span class=literal>WAVEFORM_TRIANGLE_VARIABLE</span></li>
<li><span class=literal>WAVEFORM_ARBITRARY</span></li>
<li><span class=literal>WAVEFORM_PULSE</span></li>
<li><span class=literal>WAVEFORM_SAMPLE_HOLD</span></li>
</ul>
</p>
<p>The Sample &amp; Hold waveform does not support phase modulation.
Attempting to modulate its phase may give random or
inconsistent results. Use only frequency modulation
to vary the Sample &amp; Hold waveform speed
</p>
</script>
<script type="text/x-red" data-template-name="AudioSynthWaveformModulated">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>

<script type="text/x-red" data-help-name="AudioSynthWaveformPWM">
<h3>Summary</h3>
<div class=tooltipinfo>

Carregando…
Cancelar
Salvar