How to change a buffer's sampleRate everywhere

This feels like a newbie question, but I’m too old to be one, so please accept my apologies for my simple misunderstanding.

I am loading a 44100 sample:

b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav")
b.play

so far so good. if queried, b.query gives us what I expect.

now I update the sampling rate

b.sampleRate = 48000.0
b.updateInfo

Now if I query once I get 2 different values: one in the query function (printed) and one in the parsed function (printed)

If I query again, the server is now back at 44100…

is that a bug? if not, can anyone explain what is happening?

thanks

It’s not possible to update the buffer’s sample rate in the server. There’s no server command for that.

What’s the purpose of forcing it to change in the server? I’m having trouble imagining a use case.

hjh

this is strange then that we can change it’s object representation on the language side, as per my example, no? What is the use of b.sampleRate if it doesn’t change the server side info of the buffer?

one could composite (with copyData) a sample made from 2 sources of various SR and decide on a destination valid SR programmatically. In Max we can and in Pd arrays have no sr at all. It is in effect just a tag, so I don’t know why we couldn’t update it on the server - it could be fun in many ways, for dirty samplers and such fun endeavours…

1 Like

If I’m the only one who finds this strange, I’ll just add it to my Offline Buffer Processes or in FluCoMa’s BufCompose (where it is most needed)

Are there mistakes in SC’s object interfaces? Yes. This does appear to be inconsistent and misleading.

I see what you mean, although the pd reference suggests that it isn’t strictly necessary to control the server side buffer sample rate for this, since you can calculate any playback rate you need. That’s probably why there’s no command to set it – since the use case is to play at an arbitrary speed, this can be arranged at playback time. (Yes, it would be simpler in some cases if BufRateScale returned what you choose – not saying that it isn’t useful – I’m just speculating as to JMc’s reasoning. Since he was single-handedly responsible for designing and implementing the server command interface, I can understand why he might have been selective about those commands that are definitely necessary vs those that may be “nice to have.”)

The thing I wish we could do with buffers is to override the buffer’s sample rate when writing it to disk with b_write. AFAIK there’s no way to alloc a buffer in a 48kHz server and write its contents to disk with a 44.1kHz sample rate in the header (except to pull data into the language and use SoundFile :grimacing: ). So perhaps a /b_setSampleRate command would be worthwhile.

hjh

I agree :slight_smile: I will try to get a PR done asap.

I’ve also run into this in various situations like reading a file and then manually resizing the buffer… would be great to have a server command

here I’m not talking about resizing or resampling, just changing the flag of sampling rate. It has no memory implication while resizing has so that makes it tricky. For what you want, have you tried FluidBufCompose?

I mean that when resizing (i.e. trimming) a buffer it has lost its sample rate tag and so e.g. BufRateScale doesn’t work anymore. What you are proposing would help this situation

Maybe write a temp file using SoundFile?

(
    f = SoundFile.new;
    f.openRead(Platform.resourceDir +/+ "sounds/a11wlk01.wav");
    g = SoundFile.new.headerFormat_("wav").sampleFormat_("float").numChannels_(1).sampleRate_(96000);
    g.openWrite(Platform.defaultTempDir +/+ "a11wlk96.wav");
    a = FloatArray.newClear(f.numFrames);
    f.readData(a);
    g.writeData(a);
    g.close;
    f.close;
)

Sam

FluidBufCompose is being clarified now, as it would currently take the dest SR or the server SR when it is empty. Which is what we want to change (taking the input SR makes more sense except in some cases, hence needed this ability to change the sr)

@Sam_Pluta yes, but staying on server and in ram is the point here.

1 Like

If it is focused on NRT, all can be set in the OSC score. Maybe we must look deeper into your program to find the best solution. It will be peculiar to implement this in scsynth if there is any other suitable solution.

I’m kind of saying, “If there is a good reason to break a design, let’s do it.” But until now, it has never occurred to change this one.

The server side buffer does know the sample rate. If it didn’t, how could BufSampleRate.kr(bufnum) or BufRateScale produce a valid result?

Initially I was skeptical of the request, but at least two valid use cases have been mentioned in this thread, so I’m convinced.

hjh

1 Like

But, in theory, the Server’s Buffer is just a multidimensional array of 32-bit floating-point numbers. It does not even need to be audio.

There is a 64-bit number that may stand for the sample rate, and that’s it.

The idea is to modify this number. Why?

The client has many more elements to manage.

Maybe I failed to get it. There must be use cases I’m not aware. Why would that be necessary? Is it a setup with two clients who do not share their states?

  1. Currently it’s impossible to b_alloc a buffer and b_write it at the sample rate you choose. It would be possible to bring the buffer data into the language and use SoundFile to write it at the sample rate of your choice, but that seems unnecessarily complicated. The data exist on the server. The server has a buffer-write command. The ability to set the server-side buffer sample rate would make the server’s buffer-write command more flexible, and basically not have any downside.

  2. b_gen copy: maybe the source data are not all at the same sample rate, and the user wants to decide what they will get from BufRateScale. It could be argued that it’s abuse of the sample rate property, but electronic music is all about abuse of technology, so I don’t find that a compelling reason to reject the use case.

(Both of these were mentioned earlier in the thread, btw.)

It’s a low-complexity enhancement that has zero chance of accidentally breaking current code. These use cases might be a little bit exotic, but they’re harmless.

PS Max has a “sr” message that you can send to a buffer~.

hjh

But the duration and the number of samples were there; the SR number is not a mystery. But I understand, and to be fair, there is no reason not to do it either. So why not?