12-bit audio using video generator - first working concept
pik33
Posts: 2,393
Seems to work, so I added a topic for it.
This is version 0.02. Mono, 12bit - it don't have this "duty dac" noise so it doesn't need dithering
But - it seems to generate something at high frequencies (alias?) - I don't hear this, I see it on my equalizer display... need to test it with oscilloscope.
To do:
(1) Stereo should be possible, so do it.
(2) Test what can be possible if reducing it to 9 bit, 4x oversampling and noise shaping
This is version 0.02. Mono, 12bit - it don't have this "duty dac" noise so it doesn't need dithering
But - it seems to generate something at high frequencies (alias?) - I don't hear this, I see it on my equalizer display... need to test it with oscilloscope.
To do:
(1) Stereo should be possible, so do it.
(2) Test what can be possible if reducing it to 9 bit, 4x oversampling and noise shaping
zip
22K
Comments
It kind of feels wrong to listen to sample playback through the video generator though. It really shows how dynamic the Propeller is.
Cool uses of the video generator includes:
* Mica Dowty used the video generator for s/pdif
* I have an unreleased SPI driver (a couple of years old know) that uses the video generator to drive both clock and data at the same time at 20 Mbit/sec. A lot of parallel crunching is done while the video generator is busy feeding a byte.
* If I remember correctly someone wrote a high bandwidth prop to prop communication object that used the video generator
Video generator allows to use pll instead of main clock as a conversion base. Up to something about 220 MHz instead of 80 MHz. And this code is really small...
How's it sound?
Keep up the good work!!
I was just going by what you posted:
From videowav_demo.spin
and from videowav002.spin
So in videowav_demo.spin, why did you pass the start method for the videowav object (11,10,7) ?
You know what would be neat...
Use a specially formulated wav file fed into this driver and the appropriate post DAC circuitry to turn this into an arbitrary waveform generator :-)
...
I still don't understand why in the sample code this line was used:
sample.start(11,10,7)
In that respect duty DAC is better, but this technique will give higher resolution.
"7" is unused. The demo procedure and init procedure are copied from dithering driver I made for my Propeller media player, using Kye's dithering procedure, and it needed dither amount variable. I need to rewrite headers You can delete third variable both in call and in procedure header, it does nothing now.
Now we can try lower resoluton with oversampling and noise shaping.
* 4 pins will output the 4 MSBs through a R2R DAC.
* 1 pin will be used to PWM the 12 LSBs
* The PWM pin will have to have a signal level of half the R2R DACs LSB. Then simply add the two signals (R2R DAC + PWM) to form the 16 bit signal.
.............
Simple LC filter will do, the speaker and human ear filter out ultrasonics very effectively. The PWM waveform is ready for class D amplifier (another advantage over duty-mode counter)
Since 12 bit isn't true HiFi it needs sigma-delta conversion with noise shaping filter- this should produce very good sound. However you do, I believe, need to make the PWM phase-correct for this to work well - haven't delved into the code enough to see if this is the case. Put another way I've done 8 bit PWM with a counter and it sounds fantastic with sigma-delta added, 12 bit ought to be at least as good!
You might then want to try 11 bit at 100kHz as it should be even better as the noise-shaping will perform better with more oversampling. [ and make filtering easier ]
That has been on my todo list for a very long time. I might try this with the Propeller!
"Simple LC filter will do, the speaker and human ear filter out ultrasonics very effectively"
Of course, but the problem isn't the speaker or the human hearing. The amplifier might take a hit (yes, I know about internal low pass filter and bandwidth issues... but still... it might)
Tweeters can be burned if the amplifier has sufficient bandwidth.
Yes, that too!
If sample value is big, then last waitvid is too short to fit next sample getting procedure. It causes distortions. (listen to 200 Hz sample)
I might be able to tweek my video-generator-SPI-driver to do that!
If the amplifier is class D you don't filter until after the amp - the issue is suppressing EMI enough and preventing power wastage.
Of course, I still want to do some thinkering with class D someday.
I think it now plays better quality sound than duty dac with dither. Only problem: it is mono now.
Stereo will need more complex computation and 6 waitvids instead of 4.. there is very small margin for pll left.. now it works @206 MHz...
Though there's no particular difficulty using counters for I2S clocks, something like sysclk/8, sysclk/32 from counters and LR clock can be done is software. I use a 6.144MHz crystal to get 48kHz sample rate, slightly overclocking the prop, though that's not required. I can adjust the volume and bass and treble in the spare cycles even (using state-variable filtering and unrolled multiply loops!).
Wolfson Micro do a variety of very cheap 16/24 sigma-delta DACs and ADCs for I2S bus, WM8783, WM8524, WM8759 are the ones I've used, WM8782 is next on the list to play with. Very easy to interface to with the Prop due to the deterministic timing and multiple counters.
Of course, but a version that DOES use a i2s DAC, allows you to compare how you are going... target the best of both choices.