reSound (OBEX)
Mickster
Posts: 2,897
reSound
By: Johannes
Language: Spin2 & PASM2
Created: 19-June-2020
Category: speech and sound
Description:
The reSound object can mix up to 32 audiostreams at once and apply volume, panning, frequency control and different audio formats for each channel independently. All this in CD quality stereo mode (or even better) using a single cog.
I love the power of the P2, this performance was never possible on the P1. The limiting factor REALLY is the SD card interface, so in reality we are talking 2 to 4 streams per physical SD interface. You can also mix in samples over the audiostreams for sound effects as long as they fit in the remaining hub ram. All this can be mixed in mono, stereo or up to 8 physical audio pins for surround sound.
The demos illustrate what the reSound driver can do.
License: MIT (see source code)
@Johannes mentions "The limiting factor REALLY is the SD card interface, so in reality we are talking 2 to 4 streams per physical SD interface."
Is this still the case? I seem to remember seeing mention of SD card data transfer rate improvements(?)
My application is for multi-track backing tracks for live performance. I'd like to have independent control over each instrument which can be either MP3 or WAV. Mono would be fine.
Craig

Comments
I think that @evanh works with a 4bit interface instead of 1bit.
To be fair to Johannes's 2020 post, I only finished the 4-bit driver this year. Stable edition, v1.2, in Obex - https://obex.parallax.com/obex/sdsd-cc/
Latest testing edition, v1.13, in the discussion topic - https://forums.parallax.com/discussion/comment/1570392/#Comment_1570392
Whoa!

Craig,
Check out the new readme in v1.13 zip file and let me know if you need more help. I'm going to bed right now though, so won't be reading any replies for some hours.
As for getting top performance, data reads can be dynamically set to ignore the CRC and also use a clock divider of sysclock/2. I've had over 50 MB/s.
It can be flipped back and forth at will if you want to use CRC for some loads.
PS: To adjust these setting from within Spin2 requires Flexspin V7.5.1 or later.
ioctl()wasn't exposed inlibc.spin2before that.Think this is the code that needs to be added to my 90's 3D game to give it music and effects...
Wonder what code he was using for uSD access. Thought he was just using embedded .mod files.
Was hoping it could do .wav from uSD and guess the above suggests that it can...
PPS: Best all round performance is got by leaving CRC enabled and just setting the clock divider to 3. Default is 4.
CRC processing rate exactly matches sysclock/3 data rate. All other overheads then expose as slowdown compared to sysclock/4, which can hide some overheads.
This is exciting stuff
Do we have an established audio driver schematic or do I cook one up?
Craig
Add a capacitor level shifter to the regular 3.3 Volt 123 Ohm DAC output and you get a suitable line-out to plug into a line-in receiver.
Still have to solve for de-popping though. I had a shot at it and got some way towards a solution by initialising with the natural ADC bias before switching the pin over to DAC mode. Still some clicking though. Would probably do better by measuring undriven volts with comparator then slowly ramping from there to 50% with the DAC.
I'm still wondering about that de-pop thing, too.
There was an idea at some point about pulsing the DAC drive to slowly ramp it up. Not sure what happened to that. Minor problem is that the "idle" level for smart DAC $7F80, so halfway between $7F and $80 raw DAC levels. Other problem is how to do it without being invasive to / slowing down the surrounding code.
Though IME many machines do have a pop on power-up, so it's not terrible to have it.
Incidentally, I found that the reSound code still has this bad assumption
' Use the better quality option, PWM dither, if sysClock is a 256x multiple of the mixing frequency if (word[configurationPointer][0] & $FF) == 0 byte[configurationPointer][2] := DAC_MODE_PWM else byte[configurationPointer][2] := DAC_MODE_DEFAULTCan remove the bottom branch completely.
The PWM dither is better, completely regardless of sample period. Whatever issues you might invite by using uneven divisions of the PWM dither are dwarfed by the design flaw made manifest known as the noise dither. I have this in some of my old objects, too, so @Ahle2 couldn't have known then, either.