-
Notifications
You must be signed in to change notification settings - Fork 12
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
Play incremental tone for audio progress bar #143
Comments
This is a great example of the type of ideas and features that progressr was designed to support. The gist of supporting custom progress reporters is to provide the basic functions for communicating the progress (e.g. audio, visual, ...). Then it's a matter of providing a thin So, a first step would be to write functions that can generate the different sounds (e.g. synthetically directly via some third-party R package, or by playing sound files). This part does not involve the progressr package, which makes it easier to create. It might become similar to how the 'beepr' progression handler wrapper uses the beepr package to generate sounds. Is this something you could start working on? When that is in place, I can write the wrapper for progressr. |
@HenrikBengtsson -- The lightweight wav files are available at Gauge Sounds - Sound Files. could we just use these files and cite the author? |
Related (duplicate?) to #20 |
There's no explicit license, so probably better to re-generate. The first step is to identify exactly which frequencies are involved in those 101 pre-generated WAV files: > freqs <- 2^seq(from = log2(220), to = log2(880), length.out = 101) That is, they are uniformly distributed on the logaritmic scale from 220 Hz to 880 Hz. The duration of those files a 5 ms. genwavs.pl#! /usr/local/bin/perl
#
# GenWavs - Generate gauge sound files
#
# This program uses augen (from the autools port) to generate wave files.
# The wave files go with the JGauge scripts and are used as an audible gauge.
#
# Author: Doug Lee
# See the bottom of this file for licensing information.
#
# Revision History:
# 08/09/03: Initial version.
# 08/15/03: Added New/Exp/Obs/Unr wavs and improved the original sounds.
# See genTone() for wave type and start phase.
# See genFile for duration, amplitude, and which tones go in the files.
# Start and end frequencies for the whole file set, in Hz
$startFreq = 220;
$endFreq = 880;
# Number of evenly-spaced sounds to generate, from startFreq to endFreq
# This is inclusive, hence the odd number of sounds.
$nsounds=101;
# Output file name prefix (full name = ${fprefix}<n>.wav)
$fprefix="gauge";
# Number of octaves in the frequency range (possibly non-integral)
my $noctaves = ($endFreq / $startFreq) /2;
# Number of notes per octave (possibly non-integral)
my $npo = ($nsounds-1) / $noctaves;
for(my $i=0; $i<$nsounds; $i++) {
$fc = $startFreq * (2 ** ($i / $npo));
genFile( sprintf("$fprefix%-3d", $i), $fc);
}
genFile($fprefix . "New", "new");
genFile($fprefix . "Exp", "exp");
genFile($fprefix . "Obs", "obs");
genFile($fprefix . "Unr", "unr");
exit 0;
sub genFile {
# Generate one file--or rather make augen do it.
my($fname, $fc) = @_;
$fname =~ s/\s+$//;
print "Generating $fname ...\n";
open(FH, "|augen -s 11025 -ea wav -g - -o $fname")
||die "Can't generate $fname; $!\n";
select(FH);
if ($fc =~ /^\d/) {
genTone($fc, 0.05, 0.3);
genBorders();
} elsif ($fc =~ /new/i) {
my $sf = ($startFreq+$endFreq) /4;
my $ef = ($startFreq+$endFreq) *3 /4;
printf("t 0 0.05 %9.4f %9.4f 90 0.3 0.3\n",
$sf, $ef);
genBorders();
} elsif ($fc =~ /exp/i) {
my $sf = ($startFreq+$endFreq) *3 /4;
my $ef = ($startFreq+$endFreq) /4;
printf("t 0 0P.05 %9.4f %9.4f 90 0.3 0.3\n",
$sf, $ef);
genBorders();
} elsif ($fc =~ /obs/i) {
printf("n 0 0.05 0.1 0.1\n");
genBorders();
} elsif ($fc =~ /unr/i) {
printf("n 0 0.05 0.1 0.1\n");
}
close(FH); # waits for generation to complete
select(STDOUT);
die "Generation of $fname failed.\n" if !-e "$fname.wav";
}
sub genBorders {
genTone($startFreq, 0.05, 0.08);
genTone($endFreq, 0.05, 0.08);
}
sub genTone {
# Produce the directions needed for one tone.
my($fc, $nsec, $amp) = @_;
# waveType T0 T1 fc0 fc1 startPhaseDeg amp0 amp1
printf("t 0 %4.2f %9.4f %9.4f 90 %4.2f %4.2f\n",
$nsec, $fc, $fc, $amp, $amp);
}
__END__
/*
Copyright (c) 2006-2009, Doug Lee and SSB BART Group
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of the copyright holders and contributors may not be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ |
The generic progress-to-frequency mapping function for this is: progress_freq <- function(ratio, begin_freq = 220, end_freq = 880) {
stopifnot(length(ratio) == 1, is.numeric(ratio), is.finite(ratio),
ratio >= 0, ratio <= 1)
range <- (log2(end_freq) - log2(start_freq))
freq <- 2^(log2(start_freq) + ratio * range)
freq
} For example, at 0% progress, we get: > progress_freq(ratio = 0.0)
[1] 220 at 100% progress we get: > progress_freq(ratio = 1.0)
[1] 880 At 10% progress, we get: > progress_freq(ratio = 0.10)
[1] 252.7136 and at 50% progress, we get: > progress_freq(ratio = 0.5)
[1] 440 |
Oh, there's more to it; https://www.dlee.org/jgauge/ says that each of these single-tone sounds also have a start and a stop sound;
I'm not sure what they are, and how they are generated, but looking at the Also, from the Perl script, I believe that these two boundary tones have an amplitude of 8% (0.08), whereas the invidual "progress" tones have an amplitude of 30% (0.30). That is, the relative amplitude of the boundary tones is 0.08/0.30 = 0.267 = 26.7%. |
It would be even nicer if {progressr} could support incremental tones for audio progress bar. This is a technique being used by some screen readers, such as NVDA.
JGauge Progress Bar Monitoring Scripts can give you a better idea of this concept:
The text was updated successfully, but these errors were encountered: