Sample player?

Yes, this may be useful: GitHub - musikinformatik/AudacityLabels: Import labels from the audacity sound editor, marking soundfile regions.

1 Like

I don’t know of any quarks doing all you are asking but it’s easy to build a synthdef doing that - especially if you are talking about ‘normal’ sampler operation in which playback rate and pitch are linked, ie. no time-stretching. The hardest part by far (in my experience) is a good crossfading mechanism for looped played back. For single shot samples everything is easy. For looped playback I have used this design which I modified to suit my needs. The crossfading works really well: Looping sampler with crossfading

1 Like

Thanks, yeah I guess with a MacBook and lots of memory I don’t really need looping, never thought of that. I could just play one long file. I think there is a sampler in the quarks that streams off the hard drive, without eating up ram. I’ll have to look for that.

Yes, you can stream from disk. If you got a newer macbook with ARM processor I think you can fill the RAM with a lot of audio before getting in trouble. I haven’t tried but I would think that a couple of GBs of audio in buffers would be no problem. There are some issues with precise indexing into to large buffers, there are plenty of post regarding, should be easy to search. If you just want to play an audio file from start to finish and eg. treat it with FXs it is a very easy setup.

I often load many gb of sound buffers into ram, works fine! (Solution to disk read glitches when streaming large amounts of audio and video – load audio into ram and only stream video from disk)

1 Like

@Thor_Madsen : could you elaborate how you are using your \simpler SynthDef?

I have recently opened this topic about a similar subject. I wasn’t able to find a SynthDef that makes it easy to mix/match different looping samples with patterns. I am thinking about something rather straightforward that plays for instance a sampled drum loop with a sampled bass loop together (matching tempo if necessary). The goal would be to live-code long samples/slices in a smooth and pleasant way.

@sslew: I am very happy using SAMP made by @scztt. I am loading a crazy amount of samples without any issues (3GB+). My library is automatically loaded when the server boots. It’s super convenient. For simple sample playback, there are a ton of resources available. Maybe start by taking a look at this resource. It comes bundled with a few sampler SynthDefs that you can start to modify to your liking :slight_smile:

2 Likes

Makes sense, would I just build a synthdef with a PlayBuf , an Envelope and whatever else for flavor in there and it should play polyphonic? maybe there is a sample player on the net somewhere. Must be different ways to approach this, the looping sounds the most difficult part, and I’ve decided I don’t need that.

Thank you, veeeery much, I wish there was a little help file for every class. Just a simple example helps a ton.

Great link thank u

Spacechild1 turned me on to this solution: Plogue’s sforzando player’s VST2 version (sadly not VST3) accepts the detuning byte that is part of the VST2 standard (and also VST3, but it seems nobody implements it). VSTPlugin sends the detuning byte – so you can get microtuning in cents with VSTPlugin + this specific sampler.

Even in Linux – I’m running it in wine with yabridge, works a treat.

hjh

1 Like

I think that is how the * TBX2b* by hpi.zentral works. There is also the Tal sampler, which touts its microtinal ability.

I’m not a math guy but I’m assuming to play a sample to a microtinal scale you have to start with the sample at the right pitch or it will throw it all off, if you wanted to be exact.

The recorded pitch can be whatever. The important thing is to know the exact Hz value for it. Then the playback speed adjustment is desiredHz / recordedHz.

hjh

1 Like

You can examine the precise looping and crossfading mechanism here Looping sampler with crossfading . I adjusted the code so that the loop length, loop position, fade time, attack and release times are relative to the length of the sample played. In my case the sample is a chunk of a larger buffer, so all those values are relative to the start- and end indices used to play the chunk. This makes it easier to do pattern style slight randomization of args.

If the total sample dur is 1. If loopPos = 0.2, then there is 0.8 left to loop. A loopLen = 1 loops between 0.2 and 1. LoopLen = 0.6 loops between 0.2 and 0.68 (0.8 * 0.6 + 0.2). Similarly fadetime, relative to the loopLen. So all these values are normalized in the synthdef.

2 Likes

I thought SuperSampler quark might be what I want. But I don’t really understand it.

I just want to play a sample within a scale with an envelope. At its most basic. I guess I have to roll my own. I don’t need looping, which should make things easier.

(Sorry if you have already explained this… I have not read all the posts in this thread).

Could you explain more about what you need?

  • Are the samples mono, stereo or mixed?

  • What is a scale with an envelope? Should the samples always be played from start to end, or could the user control the length (make the sound shorter than the sample)?

  • If you need a microtonal sample player, you can change the playback rate slightly.

Step 1: Determine the original pitch of the sample file in Hz (call it originalFreq).

Step 2: In your synthdef, have a freq input.

Step 3: Playback rate for the buffer then is freq / originalFreq * BufRateScale.kr(bufnum).

The envelope should work just the same as any other synth.

hjh

1 Like

Thank you, hjh

@prko
Yeah, I just want to play a sample like this,

Polyphonically, with control over the envelope of the sound. Just like any normal synth.but yes, with different scales you can’t normally get with regular synths.

Sorry, I cannot follow your intention. Is the sample the result of a simple long pitch without any vibrato or pitch modulation, or is the sample the sample you want to use as a buffer?

I want to make a sample player. Thats all. The sample I provided is an example of what I would load.
No different than an akai s1000 or any other sampler.

Is this what you want?
PlayBuf

If you want to play various pitches with one sample, you should do what @jamshark70 explained.

Do you know about the built in SC help / documentation?

Anyway, what I think you’re asking for (polyphonic MIDI sample player with microtonal pitch adjustments / tunings) wouldn’t necessarily be intuitive to build so here’s a template of one way to do it:

First load the soundfile into a buffer:

// save the .scd file in the same directory as your sample for this to work:
~buf = Buffer.read(s, "VoxHumana_A3.wav".resolveRelative);

Make your synthdef to play it, e.g.:

(
SynthDef(\sample_mono, { |out, buf, startSec, rate = 1, gate = 1, amp = 0.1, pan|
  // adjust envelope here
  var env = Env.adsr(0.1, 1, 0.2, 1.0).ar(Done.freeSelf, gate); 
  
  var startPos = startSec * BufSampleRate.kr(buf);
  var sig = PlayBuf.ar(1, buf, BufRateScale.kr(buf) * rate, startPos: startPos);
  Out.ar(out, Pan2.ar(sig * env * amp, pan));
}).add;
)

You can test it out:

x = Synth(\sample_mono, [buf: ~buf])
x.release

Now the MIDI bit. The basic template I use for handling incoming MIDI notes polyphonically is:

(
MIDIClient.init;
MIDIIn.connectAll;

~notes = ();

MIDIdef.noteOn(\sampleOn, { |vel, num|
  ~notes[num].free; // just in case
  ~notes[num] = Synth( ...whatever... );
});

MIDIdef.noteOff(\sampleOff, { |vel, num|
  ~notes[num].release;
  ~notes[num] = nil;
});
)

For your case, maybe:

(
MIDIClient.init;
MIDIIn.connectAll;

~notes = ();
~tuning = Tuning.just;

MIDIdef.noteOn(\sampleOn, { |vel, num|
  var adjustedNum = num - 57; // root note A3 = midi note 57
  var octave = (adjustedNum / 12).floor;
  var semitone = adjustedNum % 12;
  var tuned = ~tuning[semitone] + (octave * 12);
  
  ~notes[num].free; // just in case
  ~notes[num] = Synth(\sample_mono, [
    buf: ~buf, 
    rate: tuned.midiratio.postln,
    amp: vel.linlin(0, 127, -30, -10).dbamp,
  ]);
});

MIDIdef.noteOff(\sampleOff, { |vel, num|
  ~notes[num].release;
  ~notes[num] = nil;
});
)

You can change tunings while playing:

~tuning = Tuning.et12;
~tuning = Tuning.pythagorean;

~tuning = [0, 0.9, 1.6, 3.1, 4.0, 4.9, 5.6, 7.1, 8.0, 8.9, 9.6, 11.1];

hope this gets you closer…

1 Like