SoundFileView: How to View Only One Channel on Multi-Channel Sample?

Hello,

I am using the SoundFileView object to display samples in a GUI window. The samples have two channels, but I would to only display one channel.

Here is my code:

I am storing the sample in a buffer and set channels=0.

~k3 = Buffer.readChannel(s, "/Users/spyridonpallis/Documents/SuperCollider/Samples/The Lunch77 Kanye West Drumkit/Kicks/(Kick) FSMH1.wav", channels: [0]);

I am accessing the buffer here to display the file.

(
w = Window.new("soundfile test", Rect(200, 300, 740, 100));
a = SoundFileView.new(w, Rect(20,20, 700, 60));

a.soundfile = ~k3;
a.read(0, ~k3.numFrames);
a.timeCursorOn = true;
a.timeCursorColor = Color.white;
a.timeCursorPosition = 0;
a.drawsWaveForm = true;
a.gridOn = false;

w.front;
)

Here is the result:

How can I get this view to only display one channel?

Thanks!

The “fine print” here is that SoundFileView:read does not access the buffer’s contents. It asks the object stored under soundfile what is its path, and then reads from disk. If you’ve read the buffer from disk, then the Buffer object has a path – so Buffers can sort of substitute for SoundFiles here, but it isn’t using any of the other Buffer variables such as numChannels – readChannel will have zero effect on SoundFileView’s behavior.

I don’t see any built-in SoundFileView method to de-interleave channels, but you can load and manipulate the contents yourself.

(
var file, contents;

file = SoundFile.openRead(~k3.path);
if(file.notNil) {
	protect {
		contents = Signal.newClear(file.numChannels * file.numFrames);
		file.readData(contents);
	} {
		file.close;
	};
} {
	Error("Couldn't open file").throw;
};

// get samples 0, 2, 4, 6 ...
// channel 1 would be [1, 1 + file.numChannels ..]
contents = contents[0, file.numChannels ..];

w = Window.new("soundfile test", Rect(200, 300, 740, 100));
a = SoundFileView.new(w, Rect(20,20, 700, 60));

a.setData(contents);
a.timeCursorOn = true;
a.timeCursorColor = Color.white;
a.timeCursorPosition = 0;
a.drawsWaveForm = true;
a.gridOn = false;

w.front;
)

hjh

1 Like

This works great! Thank you so much.

I :hearts: this forum. I did not know of protect {} before. Time to learn how to better deal with exceptions.

In this context, it’s a “just in case” policy – you want the file handle to be closed whether there’s an exception or not. It “shouldn’t” come to that but if it does, it’s covered. For that reason, I’ve been wrapping file access in protect for some time.

There’s also try which can decide whether to swallow the exception or re-throw it. (The return value from the try method is not always reliable – there’s a bug filed somewhere about that – workaround is to structure the usage so that you don’t need the return value.)

hjh