1. IMPORTANT:
    We launched a new online community and this space is now closed. This community will be available as a read-only resources until further notice.
    JOIN US HERE

Recording audio in core

Discussion in 'Building With Reaktor' started by Tun, Mar 7, 2014.

  1. Tun

    Tun NI Product Owner

    Messages:
    224
    Hi
    I am going to be attempting to build something along the lines of the tape deck in core, but im not really sure how i would go about recording audio in to core and storing it there.
    i have had a look at the delay module, which has a basic record section (but no way of deciding a start point e.t.c.). is this the sort of thing i should be studying to get an idea of where to start?

    any suggestions on concepts that i can explore would be great.

    thank you
     
  2. colB

    colB NI Product Owner

    Messages:
    3,969
    I don't have much experience in this area, but I'll have a go :)

    Core can't save any data in snapshots, so if you want to be able to save and reload the recorded audio using, you will need to set up a couple of Audio table (or maybe event tables?) and a snap value array in Primary layer, then just an array in the core cell.

    If you set up one of the Audio tables to the size you need (depending on maximum recording length required), then use it to create a file (use the little disk symbol and "save table data"), making sure "Backup Data with Module" is ticked, when you copy an paste it, the copy will point to the same data!

    You put one of these at the start of your chain and one at the end: so something like:

    Audio table 1 -> Snap value array -> core processing cell -> Audio table 2.

    You need some kind of input management logic so that each input sample first goes to the core cell, then from there it is written to Audio table 2. Then after that process has been completed, your input manager triggers a read from Audio table 1 (same data in the background which you have just written to table 2) into the snap value array. The snap value array is connected to the core cell input so that when you recall a snap, the data is automatically (self iteration) loaded into the core cell - in this case, you probably don't want it to pass through to the Audio table...

    You top level logic will need to handle processing updates etc. so if you apply some sort of processing to the data that you would like to be stored if a snapshot is saved, there will need to be some logic that first tells the core cell to process the data and pass it to Audio table 2, then tells Audio table 1 to read that data and send it to the snap value array...

    It sound complicated - because it is. It takes some fiddling to get this sort of thing working without event loops and array offset problems, but it is possible.

    The main thing is understanding how multiple tables can be set up to access the same data - that's how you can avoid the event loops.
    Watch out for array indexing offsets... it's something like - tables indices start at 0, snap value arrays start at 1, iterators do one more iteration than you think they will because they do the first one, then another N iterations on top of that.

    And if that's not enough trouble, another problem you will have is the maximum table size. Maximum X is 999999 which is only enough for about 20 seconds of audio at 44.1Khz. I guess you could use a multi dimentional array, like X=999999, Y=15, that would give about 15 minutes of recording and you would have to manage the seamless switching between table rows. But I'm not sure what the actual limits are on file size for Audio table... Like I said, I'm a noob in this area. I have dabbled, but not with more than 20 seconds of audio...

    Hope that helps to get started.

    Col
     
  3. salamanderanagram

    salamanderanagram NI Product Owner

    Messages:
    3,454
    oh i really don't suggest storing audio files by snapshot in any event.

    one of the transformers ensembles (starscream) has this capacity, i ripped for use in the convolution stuff later on. for convolution, with short files it works fine, holding sample maps or loops is pretty much out of the question if you want more than a few snapshots.

    and you definitely don't want to go outside the 20 second limit if you're saving it as snap data!
     
  4. colB

    colB NI Product Owner

    Messages:
    3,969
    Lol. My suggestion above ain't gonna work for decent length recording because of the system resources reactor need for setting up a big enough snap value array. So stick to recording one thing and saving it with the ensemble using just the audio tables.

    You could still use snapshots for shorter recordings though.
     
  5. salamanderanagram

    salamanderanagram NI Product Owner

    Messages:
    3,454
    reaktor really needs a way to store file locations, as opposed to actual files, in snapshot data.
    i mean, come on.
     
  6. colB

    colB NI Product Owner

    Messages:
    3,969
    Here's a very simple module that records to and plays from an array in a core macro. It has a pair of audio tables at Primary level that save and load the audio. The table is set up with a two dimensional array to demonstrate how that works.

    Hit record to reset the record position and start recording.
    Hit play to reset the play position and play.

    In this version, you get just over 20 seconds - scratch that, I changed it to under 2 secs because the 20 sec on was to big to upload to the forum :) - before it loops around and starts recording over the start again.
    Change the array and the tables to higher values to have longer record times, and update the div and mod constants at the outputs of the core cell.

    The downside of using Audio tables is that they output at audio rate, so you need to limit the read iterator to audio rate or it doesn't load properly at startup. But that must be done in the preperties dialog, so if the user uses a different sample rate, they need to edit it manually. The alternative would be using Event tables... Not sure about that. might be ok ?

    Col
     

    Attached Files:

  7. Tun

    Tun NI Product Owner

    Messages:
    224
    i probably should have mentioned that i dont need to be able to save audio with this, not even in a snapshot. i only need to be able to store the audio temporarily so it can be looped.

    it is for a looper pedal type build, so no loops will need to be saved, just played back multiple times. i also want to be able to play back the loop from certain points, for example, start playing at the halfway point when it loops instead of the beginning.
    the tape deck does work great for this, but i want to build one in core, mostly for the fun, but also for flexibility.

    thanks for the upload ColB, i will check that out later when i can download it.

    and thank you both for the replies
     
  8. colB

    colB NI Product Owner

    Messages:
    3,969
    Heh, that simplifies things a LOT!

    You can take that example and shov... kidding... just remove all the primary stuff and the bit in the core cell that loads from the table, and sends to the table...

    In fact, it's so quick to do, here ya go...

    The only downside is the limit to array size in core. You get about 23 seconds at 44.1kHz. If you want more, you need to have multiple arrays and manage the transitions. Not particularly difficult to do in core.

    Col
     

    Attached Files:

    • Like Like x 1
  9. Tun

    Tun NI Product Owner

    Messages:
    224
    great! thanks

    i will come back once i have had a look
     
  10. Tun

    Tun NI Product Owner

    Messages:
    224
    well i have tried for many hours today to get this working :(
    i still use win XP and so i havent updated my reaktor. i did hear about some work arounds, but i have tried most of them today with no luck. i will keep trying though to see what i can do. anything is better than letting ms get the better of me :)

    this is not the first time this has restricted me either. looks like im going to need to bite the bullet and update my os sooner than i was hoping.
    funny thing is, i dont care about loosing support on XP, im happy with XP anyway, but loosing reaktor has hurt me twice now, and hurt me hard.

    i will return to this thread when i figure out a work around.

    thanks
     
  11. colB

    colB NI Product Owner

    Messages:
    3,969
    here's a screen grab:

    basic core record.png
     
    • Like Like x 1
  12. Tun

    Tun NI Product Owner

    Messages:
    224
    excellent! thank you very much!
    i will try this out later and get back.

    thanks
     
  13. Tun

    Tun NI Product Owner

    Messages:
    224
    one quick question though.
    what is the purpose of the write modules at the end of the record chain that are not connected to anything?
    i noticed something like this in the built in delay macro, but assumed it was so they could use that part on different macros.
     
  14. colB

    colB NI Product Owner

    Messages:
    3,969
    There are no write modules that are not connected to anything!

    The record chain has two different memory processes.

    The upper one is the index counter. It has two writes and a read. The first write (leftmost end of the chain) is there to reset the index to zero when there is an event from the record button. Then, if rec is on (>0), the read is triggered each tick and the value read is incremented, and wrapped back to zero once it reaches the size of the buffer (N). The final write module stores the new index value back in the memory ready for the next tick.
    It's important to remember that those three memory modules are all connected to the same memory slot, so anything written by the write at the right most end, will be read by the read module in the next tick (unless it is overwritten by a reset event).

    The lower process is the actual record process, this uses the index value from the counter to write the incoming samples to the array... I just notices a slight error. It is always writing to the buffer, even when record is off (but in that case always to the same index), it should only write when record is on... see if you can spot the error and fix it (just one connection needs to be changed).

    cheers

    Col
     
    • Like Like x 1
  15. Tun

    Tun NI Product Owner

    Messages:
    224
    i would assume the error is one of the routers, probably the left one? would need to take its boolean from the records compare module, rather than the play one?

    to be honest though its a bit of a stab in the dark because i still dont understand what is going on in this structure :)

    i have only dabbled in core slightly, it is still quite confusing to me, and there are a few modules here that i dont really understand, such as the arrays, index e.t.c. i havent looked into them yet.
    but i will be learning them all soon enough, this structure will teach me a lot on its own. i learn better from analysing structures along side reading about individual components of the structure.

    i think the most confusing thing to me about this structure is that the top half appears to lead to a "dead end". i am used to seeing structures that run from left to right (like in primary), and if there is no wire coming from the right side of a module then the signal ends there (apart from sends e.t.c. of course). but it doesnt seem to quite work like that in core, not strictly anyway. it seems that modules further down the chain have an effect on previous modules.

    i will analyse this carefully though and figure it out eventually. i am a quick learner, ive just rarely got the time to dive in to reaktor :(

    thank you again for all your help
     
  16. colB

    colB NI Product Owner

    Messages:
    3,969
    Actually, looking again, I must have been tired. The actual functionality is correct. Just that the second router is somewhat redundant, because it routes the same input based on the same condition as the first...
    You really have to understand how core lets you directly access and manipulate memory. You can't really do that in Primary (apart from using tables and snapshot modules).
    Those funny looking square sockets without a dot (or =) in them are 'OBC' connections (Object Bus Connections). They have no counterpart in primary level. OBC connections do not handle events at all, so the idea of a stream of events moving from left to right doesn't make sense. The order the OBC modules are connected just defines (in most situations) what order operations on them are processed.
    They are connectors that allow different modules to share a resource - a memory location or an array. There are two very important modules in core that you absolutely must understand that both use OBCs internally in a minimal way. Latches and z-1 modules. If you study and understand how they work and why they are useful, then you're most of the way towards 'getting' core.

    There's lots more info in the core reference: chapter 4 page 85 "Structures with internal state"
     
    • Like Like x 1
  17. Tun

    Tun NI Product Owner

    Messages:
    224
    AH! i did notice that when i first looked at it. yay me :)

    yea i havent looked at OBC connections yet. i have seen them mentioned and that is about it. i have used them in read and write functions, but not really knowing what they are doing, only knowing that they need to be connected for the process to work.
    OBC connections will be my next lesson then.

    its annoying that i have to go through so much to build another tape deck when there is already one in primary, mostly because i want it to function in samples instead of ms (although further editing will be useful), but at the same time its about time i started using core properly rather than just using the very basic things in there.

    thank you very much for the help. i will likely be replying to this thread again soon with more questions if you dont mind.

    thanks
     
  18. colB

    colB NI Product Owner

    Messages:
    3,969
    No problem, I don't mind at all!