Sampling within Tidal

The bufferEvent has an entry that specifies whether its buffer hasn't been read already and still needs loading from disk. You should set it to false:

bufferEvent[\notYetRead] = false
1 Like

Gotcha - this does the trick! Thank you very much for your help.

good! The reason was that the buffer you provide has no valid path of course …

1 Like

Yep this makes totally sense.

Yes good news, solution is simple.

Thomas, when you write "You can change the default looper mode by changing the variable pLevel", what are the different values and meaning of pLevel. And I think that rLevel is the recording level.

"You can change the default looper mode by changing the variable pLevel "

I think this is obsolete because it should not affect the Quark version of the looper. Maybe I should remove this line.

The difference between pLevel (preLevel) and rLevel (recLevel) comes from the RecordBuffer Ugen (RecordBuf | SuperCollider 3.12.2 Help)

  • recLevel: Value to multiply by input before mixing with existing data.
  • preLevel: Value to multiply to existing data in buffer before mixing with input.

So the preLevel is just useful in overdub mode because it affects the gain of the existing audio in a buffer and is useful for mixing the new audio to this existing buffer.

hey @mrreason , just recently installed the tidal-looper quark in sc and when running the basic tidal code in the readme, i don't hear any sound when playing the "loop" sample after recording with the "looper" sample.

What I've done in SC to init tidal-looper is simply the line

    // Initialize the TidalLooper
    ~looper = TidalLooper(~dirt);

I also set my input device to the default mic on my macbook ( any way to confirm that sc is actually using that as input? )

The output i see in the sc console when running the init is

---- initialize TidalLooper ----
loading synthdefs in /Users/.../tidal-looper/classes/../synths/standard.scd
function olooper was successfully loaded.
function looper was successfully loaded.
function rlooper was successfully loaded.
function freeLoops was successfully loaded.

have not seen any errors when executing the code in my ide. Wondering if I can get some help in debugging this? Thanks!!

Hey @bbquan and thanks for trying out the tidal-looper quark. It looks like that the tidal-looper is installed correctly. It would be helpful to see how your Tidal code looks like. When you have problems with the usage you should look at this thread:

But to your question how to debug the audio input:

Sure - there is a good chance that his thread will help you too:

If some of these answers helped you, I would be happy if you let me know what was missing in the README of the tidal-looper repository.

Haven't checked out the tidal looper, but is it possible to save slices from splice/slice operations? What i would like to have would be the ability to save out the slices into a directory. Then i could use these as source for patterns like n" 0 3 4 1 2" #s"folder1 folder2" etc. And further, it would be fun to be able to do this in a kind of feedback loop, so i could chop up samples, replay them back and rechop them back into the same directory.

hmmm. im not seeing the audio input in the sc server meter. i do see the input devices when i run

ServerOptions.inDevices;

seeing this in the output

Found 0 LADSPA plugins
Number of Devices: 3
   0 : "LCS USB Audio"
   1 : "MacBook Pro Microphone"
   2 : "MacBook Pro Speakers"

"LCS USB Audio" Input Device
   Streams: 1
      0  channels 1

"MacBook Pro Speakers" Output Device
   Streams: 1
      0  channels 2

[...] but is it possible to save slices from splice/slice operations?

TL;DR your use case is one of the many motivations (or reasons) why I created this looper :slight_smile:

Kinda. There is no direct connection to these TidalCycles functions. If you route your output signals to some virtual input busses, then you can loop everything which comes from TidalCycles. You can slice your audio result with the looper, record it, play it back, slice it again and so on. You can specify different input busses and you can save different results under different names. But you could replace the buffers on the same names too.

I just have an example for this on Instagram. If you are able to see it, you can find it here: MrReason on Instagram: "I am working on three #tidallooper examples and this is the first one. Here I create a loop and reloop the loop. With this you can create interesting effects. . . . #tidalcycles #hydra #livecoding #livecodingmusic #loop #sampling #livesampling #music #experiment #cycseq"

Otherwise you should be able to download it here: ownCloud

This sounds like a more general problem with your audio setup. Does your mikrophone works in other software, i.e. Discord?

yup. i think the only place i havent gotten it working is sc.

Hmm weird. I see you are using macOS. You should have at least these lines in your startup file:

s.options.numInputBusChannels = 2; // set this to your hardware output channel size, if necessary
s.options.inDevice_("LCS USB Audio");

What will be printed on your console when you evaluate this line: s.options.inDevice?

ahhh... that was exactly the problem. when i executed s.options.inDevice i got nil. putting in those two lines into sc finally did the trick. also looper works how I would expect now. thanks a bunch!

No problemo and have fun with the tidal looper! :slight_smile:

Yes but it's the way the slice function cuts up the samples make it a lot easier to generate single hits. If it's done at the looper level, the looper has to figure out where to trim the samples. Haven't looked at superdirt to see if it can do that.

Thank you for the looper! I'm finding it wonderful for building up layers of sound with olooper, but I'm having trouble figuring out how to get rlooper working with qtrigger, did the essential functionality of that change since the posts in this thread were made? You say to use it "to start the recording when the next loop starts", but when I use it, e.g.

once $ qtrigger $ s "rlooper"
d1 $ s "loop"

it starts recording immediately after I run the code, records for a full cycle, then starts playback of the recording at the beginning of the next cycle. So if I trigger the code halfway through the cycle and wait until the beginning of the next cycle to start playing a one-cycle melody, my melody ends up starting the next cycle half a cycle late, and gets cut off half a cycle short.

Obviously qtrigger has changed at some point, since I can tell it no longer accepts arguments, but I can't seem to find any documentation or discussions about the change.

(P.S. any chance you know a good way to increase input gain to supercollider? my guitar is coming into my interface pretty hot but I need to really pump the gain in Tidal to hear anything)

I'm glad to hear that you're enjoying the looper. If you ever want to share what you do with it, I would be very happy to hear/see something :slight_smile: Now let me answer your questions:

but when I use it, e.g.

This is because once will trigger your pattern immediately when you evaluate your code and doesn't care about the global cycle position. If I remember correctly, then something like this should do the trick:

d1 $ qtrigger $ seqP [(0, 1, s "rlooper")]

Also see: Composition | Tidal Cycles
In my looper documentation I also wrote this note:

Note 1: I prefer to use 'qtrigger' to ensure, that the recording starts from the beginning of the pattern. Maybe you want to use the looper with seqP, seqPLoop or wait.

There are other ways to achieve what you want to achieve, but these solutions are way more complex and I didn't documented these ideas that I currently try and use (but they are easier to use and handle in a live situation IMHO). But I am quite optimistic that it is just a matter of time when I document my complete setup and share it with everybody.

Obviously qtrigger has changed at some point, since I can tell it no longer accepts arguments, but I can't seem to find any documentation or discussions about the change.

The function qtrigger didn't knew anything about his own context. That's why it was changed. Most of the time you want to use it within i.e. d1 which has the stream id 1. And there was no way to tell a function like qtrigger that it was called inside of d1. But yeah...I must confess that I forgot to update my looper documentation.

(P.S. any chance you know a good way to increase input gain to supercollider? my guitar is coming into my interface pretty hot but I need to really pump the gain in Tidal to hear anything)

The easiest way is to increase the recording level with this command in SuperCollider (you can add this to your SuperCollider startup file):

~looper = TidalLooper(~dirt); // You should already execute this line
~looper.rLevel = 2; // Or whatever fits your needs

But I realized that the default value is way too low. But yes, you can adjust it and I must confess that I never found an optimal default value. But it's something that I have in mind.

This was hopefully helpful for you!

1 Like

Thank you very much for the detailed answer! I'm going to give these a go tomorrow when I get a chance to sit down and play again. As for sharing, I've got a guitarist and drummer friend back in my hometown that I'm starting to do remote livecode-jams with using Sonobus. The looper is a key piece of the puzzle, as they're just playing their instruments and I'm providing beats/synths plus processing their playing with Tidal from my end. Hopefully I'll get a good recording of our next jam so I can share it here!

1 Like