Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help: SoundFileView: Clarify zooming/scrolling, add RangeSlider example. #3587

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 74 additions & 3 deletions HelpSource/Classes/SoundFileView.schelp
Expand Up @@ -213,16 +213,26 @@ METHOD:: zoomSelection
argument::
The index of the selection; an Integer between 0 an 63.

METHOD:: xZoom
The number of seconds of audio to display in the view. E.g., to zoom out by a factor of 2, code::view.xZoom = dataDuration / 2::. (You are responsible for keeping track of the data duration.)

returns:: A Float, in seconds of audio displayed.

METHOD:: yZoom
Vertical scaling. code::yZoom = 1:: sets 0 dBFS to the top and bottom of the view. 0.5 is half as tall.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.5 is half as tall.

This could be improved. What dBFS do yo get when setting yZoom to 0.5?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If dBFS are too confusing, it's probably better to remove the reference and say +/-1 instead.

If the audio file is properly engineered, you won't have positive dBFS at all (and, it's literally impossible to have positive dBFS in an integer-format audio file, because the maximum possible integer value for the bit depth maps onto 0 dBFS -- you might have values outside +/-1.0 in a floating-point file but it's not recommended to rely on that). So the question here doesn't entirely make sense.

Or should I use yZoom = 2 instead? Avoid the whole topic of out-of-range values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should stick with +/-1 instead of dBFS, and say that yZoom=2 will give you +/-0.5.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works for me.

As an editorial aside, I find this last sort of comment -- a concrete suggestion for improvement -- to be very helpful. Otherwise, the PR author is left to guess what the desired improvement is, which only wastes everybody's time. (TBH I didn't know exactly what to do with the question about dBFS.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I'll try to offer more concrete suggestions in the future.


returns:: A Float scaling factor.

METHOD:: scrollPos

The scrolling position of the view, as a fraction of the total scrolling range.
The scrolling position of the view, as a fraction of the total scrolling range. The total scrolling range is code::totalDuration - xZoom::.

returns::
A Float in the range of 0.0 to 1.0.

METHOD:: scrollTo

Scrolls to a fraction of the total scrolling range.
Scrolls to a fraction of the total scrolling range. The total scrolling range is code::totalDuration - xZoom::.

argument::
A Float in the range of 0.0 to 1.0.
Expand All @@ -242,7 +252,6 @@ METHOD:: scrollToEnd

Scrolls to the end.


SUBSECTION:: Selection

METHOD:: selections
Expand Down Expand Up @@ -641,3 +650,65 @@ a.zoom(4);
w.close;

::

SUBSECTION:: Adding a scroll bar

Zooming and scrolling by mouse, directly in a SoundFileView, may not be immediately intuitive. (Most users wouldn't guess to shift-right-click!) You can add a link::Classes/RangeSlider:: to act as a scrollbar.

Notes:

list::
## If the user shift-right-clicks, the only way to track the SoundFileView's display changes is by using mouse actions: link::Classes/View#-mouseDownAction:: and link::Classes/View#-mouseUpAction:: to know which button is pressed, and link::Classes/View#-mouseMoveAction:: to read the new scrolling and zooming values.
## link::Classes/SoundFileView#-xZoom:: is in seconds, while the range slider is normalized to a 0-1 range. So code::xZoom == slider.range * duration::, and code::slider.range == xZoom / duration::.
## link::Classes/SoundFileView#-scrollPos:: is normalized to the "total scrolling range," where 1.0 is scrolled fully to the right. We have to subtract the displayed area: code::slider.lo = sfv.scrollPos / (1 - slider.size)::, with some refinements to avoid division by 0.
::

code::

f = SoundFile.openRead(Platform.resourceDir +/+ "sounds/a11wlk01.wav");
f.readData(d = Signal.newClear(f.numFrames * f.numChannels));
f.close;

(
var w = Window("test", Rect(700, 200, 600, 300)),
file, sfv, sfZoom, mouseButton,
dur = d.size / f.sampleRate / f.numChannels;

w.layout = VLayout(
sfv = SoundFileView(),
sfZoom = RangeSlider().orientation_(\horizontal)
);

sfZoom.lo_(0).range_(1)
.action_({ |view|
var divisor, rangeStart;
rangeStart = view.lo;
divisor = 1 - sfZoom.range;
if(divisor < 0.0001) {
rangeStart = 0;
divisor = 1;
};
sfv.xZoom_(sfZoom.range * dur)
.scrollTo(rangeStart / divisor)
});

sfv.setData(d, startFrame: 0, channels: f.numChannels, samplerate: f.sampleRate);

sfv.mouseDownAction_({ |view, x, y, mod, buttonNumber|
mouseButton = buttonNumber;
})
.mouseUpAction_({ |view, x, y, mod|
mouseButton = nil;
})
.mouseMoveAction_({ |view, x, y, mod|
var rangeSize, rangeStart;
if(mouseButton == 1) {
rangeSize = view.xZoom / dur;
rangeStart = view.scrollPos * (1 - rangeSize);
sfZoom.lo_(rangeStart).range_(rangeSize);
};
});

w.front;
)
::