This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Last revision Both sides next revision | ||
tonegen_design [2022/03/16 04:36] dpisuperadmin [Minimal Tone Generator with Volume Control] |
tonegen_design [2022/03/20 03:45] dpisuperadmin |
||
---|---|---|---|
Line 12: | Line 12: | ||
==== Minimal Tone Generator with Volume Control ==== | ==== Minimal Tone Generator with Volume Control ==== | ||
- | A full synthesizer, as described below, | + | A full synthesizer may take more that its fair share of FPGA logic. |
- | The API for a simple tone generator might specify the musical note to play, the volume in the range of 0 to 100, and the number of milliseconds to play the note. For example: | + | The API for a simple tone generator might specify the musical note to play, the volume in the range of 0 to 100, and the number of milliseconds to play the note. We might also want to play a file of notes where each line the the file has the note, volume, and duration. For example: |
- | dpset tonegen | + | dpset tonegen |
+ | dpset tonegen melody mymelody.txt | ||
{{ wiki: | {{ wiki: | ||
Line 26: | Line 27: | ||
- | The other approach to volume control is to build a DAC out of resistors connected to the four FPGA pins dedicated to the peripheral. | + | The other approach to volume control is to build a DAC out of resistors connected to the four FPGA pins dedicated to the peripheral. |
{{wiki: | {{wiki: | ||
Line 32: | Line 33: | ||
The minimum output of the 2R-R circuit is 0.013 and the maximum value is 0.9935, a ratio of low to high of about 76. While we have lost a great deal of resolution, we have gone from 4 bits of dynamic range for the linear R-2R network to over 6 bits of dynamic range using a 2R-R network. | The minimum output of the 2R-R circuit is 0.013 and the maximum value is 0.9935, a ratio of low to high of about 76. While we have lost a great deal of resolution, we have gone from 4 bits of dynamic range for the linear R-2R network to over 6 bits of dynamic range using a 2R-R network. | ||
- | What if we combined the linear pulse density modulation with the non-linear DAC? We could PDM control each of the FPGA output pins with a separate 4 bit counter. | + | {{ : |
- | Our design now has | + | Our design |
a 24 bit phase accumulator, | a 24 bit phase accumulator, | ||
a 24 bit phase offset set by the host, | a 24 bit phase offset set by the host, | ||
Line 41: | Line 42: | ||
an 8 bit duration counter (to count milliseconds), | an 8 bit duration counter (to count milliseconds), | ||
an 8 bit duration set by the host, | an 8 bit duration set by the host, | ||
+ | |||
+ | (The diagrams in this section were generated using Octave. | ||
+ | |||
+ | |||
+ | |||
+ | /* This block comment has the Octave source code to generate the above tables. | ||
+ | % Generate a log plot that shows a typical audio taper | ||
+ | x = 1:1:100;% Generate 100 points on an log curve and map the gain | ||
+ | % to setting in pwm - nonlinear DAC scheme. | ||
+ | % the actual table to use in the API driver modules. | ||
+ | % Manually add {0,0,0,0} and {15, | ||
+ | |||
+ | % Get the target gains | ||
+ | x = 1:1:100; | ||
+ | out = exp((5 .* x) ./ 100) ./ 150; | ||
+ | target_idx = 1; | ||
+ | % loop past all possible gains recording the first to pass out(target_idx) | ||
+ | idx = 0; | ||
+ | for i3 = 0:15; | ||
+ | for i2 = 0:15; | ||
+ | for i1 = 0:15; | ||
+ | for i0 = 0:15; | ||
+ | idx = idx +1; | ||
+ | | ||
+ | if outval > out(target_idx), | ||
+ | | ||
+ | | ||
+ | | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | out = exp((5 .* x) ./ 100) ./ 150; | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | grid on; | ||
+ | print -dpng '/ | ||
+ | |||
+ | % Show a plot of linear gain | ||
+ | x=0:1:15; | ||
+ | out = x ./ 16; | ||
+ | plot(x, out); | ||
+ | title(" | ||
+ | xlabel(" | ||
+ | ylabel(" | ||
+ | set([gca; findall(gca, | ||
+ | grid on; | ||
+ | print -dpng '/ | ||
+ | |||
+ | % Show a plot of a reciprocal gain function | ||
+ | x = 0:1:15; | ||
+ | out = 1 ./ ( 16 .- x); | ||
+ | plot(x, out); | ||
+ | title(" | ||
+ | xlabel(" | ||
+ | ylabel(" | ||
+ | set([gca; findall(gca, | ||
+ | grid on; | ||
+ | print -dpng '/ | ||
+ | |||
+ | % Show the output for PDM with the rate set to one-third | ||
+ | for x=1:1:32; | ||
+ | if mod(x,3) == 0, out(x) = 1; | ||
+ | else out(x) = 0; | ||
+ | end | ||
+ | end | ||
+ | subplot(4, | ||
+ | axis off | ||
+ | |||
+ | % Generate the possible unique gain settings for four bit 2R-R network | ||
+ | % where each bit has a four bit PWM control | ||
+ | idx = 0; | ||
+ | for i3 = 0:15; | ||
+ | for i2 = 0:15; | ||
+ | for i1 = 0:15; | ||
+ | for i0 = 0:15; | ||
+ | idx = idx +1; | ||
+ | | ||
+ | | ||
+ | | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | % Generate a plot of the gain of a four bit 2R-R DAC circuit. | ||
+ | for i3 = 0:1 | ||
+ | for i2 = 0:1 | ||
+ | for i1 = 0:1 | ||
+ | for i0 = 0:1 | ||
+ | idx = (8 .* i3) + (4 .* i2) + (2 .* i1) + (1 .* i0) + 1 | ||
+ | out(idx) = (i3 .* .73203) + (i2 .* 0.19608) + (i1 .* 0.05229) + (i0 .* 0.01307) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | plot(out); | ||
+ | title(" | ||
+ | xlabel(" | ||
+ | ylabel(" | ||
+ | set([gca; findall(gca, | ||
+ | grid on; | ||
+ | print -dpng '/ | ||
+ | |||
+ | */ | ||
+ | |||