-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blackfin audio FIFO #69
Comments
working on a branch for block processing using pingpong DMA descriptor lists, something like in this example: |
turns out that my optimism of some weeks back, was unfounded. but now a simple test case is working on the there is a module in the top-level directory called what ended up working (so far) is something like this:
this scheme is a little memory-hungry; each frame added to the blocksize adds 64 bytes. and i'm sure it could be mildly optimized in other ways. will keep cleaning up and making this more useful. |
(first a major caveat of this being entirely new territory for me, feel free to ignore) if i'm reading the code correctly the i was also wondering if it made sense to pass pointers to the it seems like you've potentially already explored some of this kind of thing and moved on. if there is anything in particular i'm happy to try some more experimentation. if not i'm temped to look into how the CV outputs and SPI bus servicing might factor into block test. |
good points! i did try a couple of other things. in the end the 1D structure was used because it turned out that my main problem wasn't the DMA structure at all, but the RX/TX timing, and this needed to be isolated. but yeah, it's not ideal. i agree that it would be better to:
for 1), the answer is (as you say) to set up 2 buffers and use 2 DMA descriptors to set them up in pingpong mode. for 2), i think this could indeed be done with the 2D DMA features. it's a little tricky. the way they implement interleaved streams is to allow the Y offset to be negative. so, i think the 2D setup would be something very approximately like this:
i think by default, when interrupt is enabled it is triggered at the end of the outer loop. in the pingpong mode, all of this stuff would go in each DMA descriptor, something like this:
and of course an equivalent setup for the TX DMA. as far as priority:
i've got some more changes to the branch - just restructuring so the block processing is in a |
ok yeah, the restructured lib/module doesn't work yet. i pushed it to the branch anyway. |
would you like me to explore getting the 2D stuff working? i was also starting to wonder if it made sense to have some overall concept of a duty cycle with servicing SPI and/or CV outs such that each could be clocked down / computed at some integer multiple of the audio processing duty cycle. if modules expressed their desired control rate it could allow one to free up cycles when high frequency control is not needed.... |
if you are interested in working out 2D DMA, and you have time right now, certainly go for it! i'm happy to try as well, but time is pretty crushed for the next few days. also good ideas about specifying different control rates. i recently opened a sparate issue about SPI servicing (#239), commenting there |
@ngwese latest commit (3b4da21) has a flag in audio.h to toggle this implementation. with or without the flag, the module API now takes two deinterleaved 2d buffer of [channels][frames] as arguments for input/output. so it's pretty much transparent whether there is a copy step in the ISR or not. the only wrinkle is that right now, the copy step also shifts the input/output frame data between the codec's native 24 bits, and the full 32 bits that is generally better for processing. maybe we should let the module do this instead so that the ISR wouldn't have to do much of anything if the pingpong DMA worked. but i think i will go ahead and start working on some block-processing modules. i want a bigger bank of simple oscillators and a proper varispeed delay... |
this isn't fully working yet but a promising step in the right direction (ngwese@7cd798a) after lots of reading, re-reading, and staring at the DMA operation flow diagram things started to click. the above changes:
it seems like there were two things in particular which where problematic in the initial attempt:
i'll keep at it. |
(sorry, posted from wrong profile just now) ach, thanks, not setting the initial flow mode/config was a pretty dumb one... maybe there is something wrong too with the way i set up the MODIFY/COUNTs causing your distortion? in the meantime i went ahead with building out a test module (bank of sinewaves to start with) and making some modification to how param changes are handled - SPI rx ISR adds them to a FIFO queue and updates the raw param states, and the block ISR processes the queue and does whatever module-specific stuff with those values. this almost works, but there is some screwy timing problem (i guess) when loading a scene from bees. and, still need to add the sport1 stuff for CV output... a good opportunity to do it more correctly. |
the MODIFY/COUNTs seemed fine when i checked - i walked the code line by line trying to wrap my head around it and verify things against the bfin reference manual. i can double check. my next step was going to sanity check the sample handling (24 vs 32 and the serial setups) as well as wrap my head around the what is going on timing wise between the dma transactions, isr, and process code. |
well there is definitely the 32b/24b problem. but shouldn't matter if you're just copying in to out... |
opened a PR (#248) with a functional setup. the final missing piece turned out to be trivial, minor typo in the tx isr. |
btw. tried to compile the |
wow, excellent, thanks! merged PR. also added missing .lds (its just the same default), moved sample shift to module, moved block size definition to module, couple other tweaks. somewhere along the way this scene-recall init problem went away...? maybe it was user error somehow. |
I'm wondering if the dma controller ( as setup above ) is mem-to-mem between L1 and SDRAM? It doesn't look that way at a first glance. I´m thinking about using one stream as a playhead and the other as a record head between these two memory spaces?! |
the audio I/O buffers aren't in SDRAM, no. they are in L1; read in one bank, write in the other. SDRAM access is about 8x slower than L1, so in general we would not want to put the I/O buffers there. i would just transfer stuff in and out of SDRAM in the block process routine of your module. but if you want to, you could use a different DMA setup pointed at SDRAM addresses. from the bf533 manual (page 9-51) it looks like using DMA to access external memory is perfectly OK. |
should implement optional audio buffering.
The text was updated successfully, but these errors were encountered: