I may have asked the wrong question. What I want to do is write some audio code and output through a DAC using the A/V accessory board. What mode should I use for that?
There's Rayman's wave player code you could look at and I also have TAQOZ code for a wave player although I will probably check to see if I need to bring that up to date for revB silicon since there wasn't any info around at the time I did this. I am just using my DAC function to setup the pin and writing samples to WYPIN.
WRFNC just left shifts the function code and combines it with any other drive modes (normally 0) before it does a WRPIN.
|< converts the bits parameter to a mask before writing to WXPIN.
Then the audio samples are written to WYPIN.
While I get mine to work, and it works well, I'm sure it could make better use of the DAC modes when I get around to looking at it again.
The last two instructions convert it from a signed 16-bit value (-$8000 to $7FFF) to an offset unsigned 16-bit value ($0000-$FFFF). It should be possible to replace the last two instructions with "bitnot right, #15". This optimization won't ever cause overflow, since rdword only gets you a 16 bit value.
The last two instructions convert it from a signed 16-bit value (-$8000 to $7FFF) to an offset unsigned 16-bit value ($0000-$FFFF). It should be possible to replace the last two instructions with "bitnot right, #15". This optimization won't ever cause overflow, since rdword only gets you a 16 bit value.
I may have asked the wrong question. What I want to do is write some audio code and output through a DAC using the A/V accessory board. What mode should I use for that?
There's a few ways: You can set the DAC level as a low-level pin setting with a WRPIN. Or use one of a couple of smartpin modes which both perform a dither to extend beyond 8-bit effective. Or SETDACS can be used. Or a streamer for up to four 8-bit DACs on a single hubRAM DMA channel.
In all cases the low-level DAC has to be setup in the P field of a WRPIN.
What exactly do you want to do? You can have a look at reSound if you want something quite usable! If you want to do it yourself, there are numerous threads discussion audio stuff. I can go through my discussion history and post some links if you want to.
What exactly do you want to do? You can have a look at reSound if you want something quite usable! If you want to do it yourself, there are numerous threads discussion audio stuff. I can go through my discussion history and post some links if you want to.
/Johannes
I want to port a program called Auduino to the P2 (and maybe to the P1 as well). It's a simple granular synthesizer.
I see...
A grain is basically a soundbuffer of a very small size that you apply realtime frequency control, volume control and the ability to change the data ptr on the fly. Having a lot of grains mixed in realtime into two stereo channels is the basis of granular synthesis. Sounds almost like a perfect match for reSound. Up to 64 grains could be mixed in realtime with independant frequency, volume, panning and grain size. The driver supports everything, the API just needs a method to set the grain parameters. It was actually on my todo list + a very basic granular synth examples. It wouldn't take much effort to implement it since it basically is just setting some parameters in hub that reSound already reads in at the mixing rate.
The P2 has real 8-bit R2R DACs; it's not just PWM. Smartpins can be used to do dithering to achieve 16 effective bits, which is effectively using PWM to append 8 more bits to an 8 bit value. Using the DACs should sound a lot better, i.e. have a lot less noise, than just using plain PWM.
EDIT: It's apparently a resistor-string DAC, not an R2R DAC. See Ariba's post below if you're reading this in the future.
I use this method for putting a frequency on a pin. Using P_NCO_MODE, the output duty cycle will always be 50%.
pub nco_freq(pin, fr01)
'' Output frequency on pin
'' -- fr01 is in 0.1Hz units
'' * set to 0 to stop output
if (fr01 > 0)
pinstart(pin, P_NCO_FREQ | P_OE, 10, fr01 frac CLK_FREQ)
else
pinclear(pin)
pinf(pin)
The P2 has real 8-bit R2R DACs; it's not just PWM. Smartpins can be used to do dithering to achieve 16 effective bits, which is effectively using PWM to append 8 more bits to an 8 bit value. Using the DACs should sound a lot better, i.e. have a lot less noise, than just using plain PWM.
Depends... R2R DACs have some non-linearity, i.e. it could happen that each of the 256 steps are not exactly the same size if the Rs are not perfectly matched. So DAC mode has less noise (if you only use simple RC filtering) but more inter-modulation and distortion.
For speech distortion doesn't matter much. There are even cases where you want distortion. E-guitars and old synthesizers (C64...) sound better if you have a little bit inter-modulation. But if you want to play high quality music I'd go for PWM with good filtering. A 3rd order sallen-key filter can be built with only one OP amp.
But if you want to play high quality music I'd go for PWM with good filtering.
The only problem is that you would need 2^16 * 44100 = 2.8 GHz system clock to even achive CD quality output, it's not feasible. We can achive a little bit better than 12 bits of resolution for 44100 samples/sec using an overclocked P2. There are noise shaping techniques that could be applied to get better result, but I doubt the end result will be better than what we already have with chips 8bit-PWM. The perceived inter-modulation and distortion is quite low on the P2 from what I've heard (using two sine functions at different frequencies), but I will make some real measurements to confirm this. It should differ a little between pins and chips, but doing the measurement on more than one pin/chip will give us a clue.
One more thing regarding my example above...
You can't update the sample more often than what the sample period dictates because the smart pin will only update the value on each NCO rollover. Therefore it's necessary to have that "waitse1" to sync everything.
The P2 has real 8-bit R2R DACs; it's not just PWM. Smartpins can be used to do dithering to achieve 16 effective bits, which is effectively using PWM to append 8 more bits to an 8 bit value. Using the DACs should sound a lot better, i.e. have a lot less noise, than just using plain PWM.
Depends... R2R DACs have some non-linearity, i.e. it could happen that each of the 256 steps are not exactly the same size if the Rs are not perfectly matched. So DAC mode has less noise (if you only use simple RC filtering) but more inter-modulation and distortion.
For speech distortion doesn't matter much. There are even cases where you want distortion. E-guitars and old synthesizers (C64...) sound better if you have a little bit inter-modulation. But if you want to play high quality music I'd go for PWM with good filtering. A 3rd order sallen-key filter can be built with only one OP amp.
Chip said, it's a resistor string DAC, so there are 255 equal resistors in series and a 256 to 1 multiplexer that selects the output voltage.
This should work much better than a R2R DAC for 16 bit dithering.
I did run a test on the dacs to check their linearity. Its graphed vs output code, the linearity deviated around 0.2 lsb from ideal. There would be ways to straighten that out if needed.
And I forgot one more thing regarding my example above...
If you choose to use the PWM mode, it's important to have a sample period that is a multiple of 256 to get the best results; In other words the 8 LSB's needs to be zero. The reason is that the PWM has 8bit = 256 CPU cycles of resolution. Not having a multiple of 256 will possible give you audible jitter/distortion. If it actually is audible depends on the ratio of the period to 256 and the sample rate. A sample period with bit 7 set will not be audible if the sample rate is 88200 Hz, because the jitter will be above the upper limit of the human hearing. (Dogs may complain though! )
Chip said, it's a resistor string DAC, so there are 255 equal resistors in series and a 256 to 1 multiplexer that selects the output voltage.
This should work much better than a R2R DAC for 16 bit dithering.
Ok, it really looks like it's a 256:1 mux instead of a R-2R ladder. If it was R-2R there should be larger steps at transitions where many bits change, especially from $7F to $80. So please forget my 1st post, DAC mode seems to be the better way compared to PWM.
Where can I find Spin2 documentation? I need an explanation of what the FRAC operator does. I looked at the fastspin docs but they only described the differences between Fastspin's P2 support and PNut. Is there a Spin2 language description somewhere?
It's the QX half of result of QFRAC or QDIV cordic instructions. Both do a 64-bit / 32-bit -> 32-bit(QX) r 32-bit(QY).
QFRAC x,y effectively has an implicit 32-bit left shift of x. So that'll be the one used there. The actual difference is QDIV gets the dividend high 32 bits from the preceeding SETQ, or zero, and the low 32 bits from D, whereas QFRAC gets the dividend low 32 bits from the preceeding SETQ, or zero, and the high 32 bits from D.
Comments
|< converts the bits parameter to a mask before writing to WXPIN.
Then the audio samples are written to WYPIN.
While I get mine to work, and it works well, I'm sure it could make better use of the DAC modes when I get around to looking at it again.
In all cases the low-level DAC has to be setup in the P field of a WRPIN.
/Johannes
http://forums.parallax.com/discussion/comment/1496551/#Comment_1496551
https://code.google.com/archive/p/tinkerit/wikis/Auduino.wiki
A grain is basically a soundbuffer of a very small size that you apply realtime frequency control, volume control and the ability to change the data ptr on the fly. Having a lot of grains mixed in realtime into two stereo channels is the basis of granular synthesis. Sounds almost like a perfect match for reSound. Up to 64 grains could be mixed in realtime with independant frequency, volume, panning and grain size. The driver supports everything, the API just needs a method to set the grain parameters. It was actually on my todo list + a very basic granular synth examples. It wouldn't take much effort to implement it since it basically is just setting some parameters in hub that reSound already reads in at the mixing rate.
You may find these very simple -- they're intended to be beginner-friendly.
Edit: Whoops, I posted very late and in response to your first quote -- these may not be helpful.
The P2 has real 8-bit R2R DACs; it's not just PWM. Smartpins can be used to do dithering to achieve 16 effective bits, which is effectively using PWM to append 8 more bits to an 8 bit value. Using the DACs should sound a lot better, i.e. have a lot less noise, than just using plain PWM.
EDIT: It's apparently a resistor-string DAC, not an R2R DAC. See Ariba's post below if you're reading this in the future.
Depends... R2R DACs have some non-linearity, i.e. it could happen that each of the 256 steps are not exactly the same size if the Rs are not perfectly matched. So DAC mode has less noise (if you only use simple RC filtering) but more inter-modulation and distortion.
For speech distortion doesn't matter much. There are even cases where you want distortion. E-guitars and old synthesizers (C64...) sound better if you have a little bit inter-modulation. But if you want to play high quality music I'd go for PWM with good filtering. A 3rd order sallen-key filter can be built with only one OP amp.
Here's a very basic stereo audio example code in pasm...
You can't update the sample more often than what the sample period dictates because the smart pin will only update the value on each NCO rollover. Therefore it's necessary to have that "waitse1" to sync everything.
Chip said, it's a resistor string DAC, so there are 255 equal resistors in series and a 256 to 1 multiplexer that selects the output voltage.
This should work much better than a R2R DAC for 16 bit dithering.
Andy
https://forums.parallax.com/discussion/comment/1452997/#Comment_1452997
If you choose to use the PWM mode, it's important to have a sample period that is a multiple of 256 to get the best results; In other words the 8 LSB's needs to be zero. The reason is that the PWM has 8bit = 256 CPU cycles of resolution. Not having a multiple of 256 will possible give you audible jitter/distortion. If it actually is audible depends on the ratio of the period to 256 and the sample rate. A sample period with bit 7 set will not be audible if the sample rate is 88200 Hz, because the jitter will be above the upper limit of the human hearing. (Dogs may complain though!
Ok, it really looks like it's a 256:1 mux instead of a R-2R ladder. If it was R-2R there should be larger steps at transitions where many bits change, especially from $7F to $80. So please forget my 1st post, DAC mode seems to be the better way compared to PWM.
forums.parallax.com/discussion/171196/pnut-spin2-latest-version-v34s
QFRAC x,y effectively has an implicit 32-bit left shift of x. So that'll be the one used there. The actual difference is QDIV gets the dividend high 32 bits from the preceeding SETQ, or zero, and the low 32 bits from D, whereas QFRAC gets the dividend low 32 bits from the preceeding SETQ, or zero, and the high 32 bits from D.