Discussion:
Convert Pairs of Mono Soundfiles to Two-Channel Buffer
Mike Winters
2014-10-16 18:32:21 UTC
Permalink
Dear SC-Users,

I'm having an interesting problem in SC working with large mono WAV files
(>100MB). I'm searching for a method that would allow me to quickly
normalize pairs of these soundfiles with respect to each other and not
independently (e.g. not buf1.normalize; buf2.normalize;)

My first thought was that if I could find the max value of each buffer, I
could use the ratio of the two to set the peak value of the buffer with
smaller magnitude. To determine the max value of all samples in a buffer, I
believe the most efficient way would be to convert it to a soundfile first:

SoundFile.use(buf1.path,{|f| f.channelPeaks})

The technique avoids first loading the buffer to a collection and then
calling .maxItem. However, it still takes four seconds for one mono 112MB
file, and would take at least eight seconds for a pair.

I think it would be faster to load pairs of mono soundfiles into a two
channel buffer and then call .normalize. Am I right in thinking this would
work? Would it indeed be faster? Most importantly, how would I use SC to do
this?

Thanks very much,
Mike



--
View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Convert-Pairs-of-Mono-Soundfiles-to-Two-Channel-Buffer-tp7614037.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
christopher jette
2014-10-17 03:14:18 UTC
Permalink
Check out SFBatch. Should do what you need.

Cheers
Christopher
Post by Mike Winters
Dear SC-Users,
I'm having an interesting problem in SC working with large mono WAV files
(>100MB). I'm searching for a method that would allow me to quickly
normalize pairs of these soundfiles with respect to each other and not
independently (e.g. not buf1.normalize; buf2.normalize;)
My first thought was that if I could find the max value of each buffer, I
could use the ratio of the two to set the peak value of the buffer with
smaller magnitude. To determine the max value of all samples in a buffer, I
SoundFile.use(buf1.path,{|f| f.channelPeaks})
The technique avoids first loading the buffer to a collection and then
calling .maxItem. However, it still takes four seconds for one mono 112MB
file, and would take at least eight seconds for a pair.
I think it would be faster to load pairs of mono soundfiles into a two
channel buffer and then call .normalize. Am I right in thinking this would
work? Would it indeed be faster? Most importantly, how would I use SC to do
this?
Thanks very much,
Mike
--
http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Convert-Pairs-of-Mono-Soundfiles-to-Two-Channel-Buffer-tp7614037.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.
_______________________________________________
sc-users mailing list
http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
James Harkins
2014-10-17 10:33:13 UTC
Permalink
At Thu, 16 Oct 2014 22:14:18 -0500,
Post by christopher jette
Check out SFBatch. Should do what you need.
If you can't find SFBatch (as I could not), here's an extension file I have locally that uses a NRT server for normalizing. The normalizeNRT method won't let you treat a pair of files as a unit, but the extension implements channelPeaksNRT and scaleAndWriteNRT, which you can use in place of the corresponding methods without NRT.

channelPeaksNRT should be at least two orders of magnitude faster than channelPeaks. It's fast... blink-and-you'll-miss-it fast.

I'd like to replace the old normalize methods with these, but I discovered recently that the -NRT versions don't support the startFrame and numFrames arguments. I'll work on that, eventually.

hjh
Mike Winters
2014-10-17 14:35:31 UTC
Permalink
Thanks James,

I put 'test-NRT-normalize.sc' in the extensions folder
(~/Library/Application Support/SuperCollider/Extensions/) and tried to run
it:

SoundFile.use(Platform.resourceDir +/+ "sounds/a11wlk01.wav", { |f|
f.normalizeNRT });

but get an error " 'quote' not understood" (see below).

I thought it was a problem in line 31, where you write "Server.program + "
-N" + oscpath.quote", but I don't think I'm right. String.quote works fine,
and oscpath.asString still pulls up a 'quote' not understood error.

Any thoughts?

@Christopher, would you kindly indicate where one can find SFBatch?

a SoundFile
ERROR: Message 'quote' not understood.
RECEIVER:
nil
ARGS:
CALL STACK:
DoesNotUnderstandError:reportError 0x114d25348
arg this = <instance of DoesNotUnderstandError>
Nil:handleError 0x115ac2208
arg this = nil
arg error = <instance of DoesNotUnderstandError>
Thread:handleError 0x114d12ba8
arg this = <instance of Thread>
arg error = <instance of DoesNotUnderstandError>
Thread:handleError 0x114d11e18
arg this = <instance of Routine>
arg error = <instance of DoesNotUnderstandError>
Object:throw 0x114d178a8
arg this = <instance of DoesNotUnderstandError>
Object:doesNotUnderstand 0x114d0d958
arg this = nil
arg selector = 'quote'
arg args = [*0]
Score:recordNRT 0x1193c9658
arg this = <instance of Score>
arg oscFilePath = "/tmp/osc815227566"
arg outputFilePath = nil
arg inputFilePath = "/Applications/SuperCollider/..."
arg sampleRate = 44100
arg headerFormat = "WAV"
arg sampleFormat = "int16"
arg options = <instance of ServerOptions>
arg completionString = ""
arg duration = 4.2832879818594
arg action = <instance of Function>
< FunctionDef in Method SoundFile:scaleAndWriteNRT > (no arguments or
variables)
Routine:prStart 0x115aff048
arg this = <instance of Routine>
arg inval = 486.70629714
^^ The preceding error dump is for ERROR: Message 'quote' not understood.
RECEIVER: nil



--
View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Convert-Pairs-of-Mono-Soundfiles-to-Two-Channel-Buffer-tp7614037p7614043.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
James Harkins
2014-10-17 14:44:11 UTC
Permalink
Post by Mike Winters
Thanks James,
I put 'test-NRT-normalize.sc' in the extensions folder
(~/Library/Application Support/SuperCollider/Extensions/) and tried to run
SoundFile.use(Platform.resourceDir +/+ "sounds/a11wlk01.wav", { |f|
f.normalizeNRT });
but get an error " 'quote' not understood" (see below).
Oh, I see... I think I have a fix locally for the silly oversight in
recordNRT that (in master) it doesn't automatically supply a path for the
osc file. My code depends on that fix.

I'm not at the computer now, but I'll send an update when I can.

It's worth the wait -- I think the NRT server is actually faster at
normalizing than Audacity.

hjh

Sent with AquaMail for Android
http://www.aqua-mail.com



_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
christopher jette
2014-10-17 16:43:34 UTC
Permalink
I only have phone, so I can't dig it out at the moment, but SFBatch is part
of SFUtils that I think was made by Tom Hall in 2008. Pretty sure I found
it knocking around an old forum discussion.
Cheers
Christopher
Post by Mike Winters
Thanks James,
Post by Mike Winters
I put 'test-NRT-normalize.sc' in the extensions folder
(~/Library/Application Support/SuperCollider/Extensions/) and tried to run
SoundFile.use(Platform.resourceDir +/+ "sounds/a11wlk01.wav", { |f|
f.normalizeNRT });
but get an error " 'quote' not understood" (see below).
Oh, I see... I think I have a fix locally for the silly oversight in
recordNRT that (in master) it doesn't automatically supply a path for the
osc file. My code depends on that fix.
I'm not at the computer now, but I'll send an update when I can.
It's worth the wait -- I think the NRT server is actually faster at
normalizing than Audacity.
hjh
Sent with AquaMail for Android
http://www.aqua-mail.com
_______________________________________________
sc-users mailing list
info (subscription, etc.): http://www.beast.bham.ac.uk/
research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Mike Winters
2014-10-17 21:37:52 UTC
Permalink
That sounds great. I'll look forward to the update when you have it. Which
branch would have the fix?



--
View this message in context: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/Convert-Pairs-of-Mono-Soundfiles-to-Two-Channel-Buffer-tp7614037p7614059.html
Sent from the SuperCollider Users New (Use this!!!!) mailing list archive at Nabble.com.

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
James Harkins
2014-10-18 02:52:56 UTC
Permalink
At Fri, 17 Oct 2014 14:37:52 -0700 (PDT),
Post by Mike Winters
That sounds great. I'll look forward to the update when you have it.
Actually, I checked the code, and the methods do create a temporary OSC file path. So that's not the issue.

So I looked more carefully at the stack trace:

Score:recordNRT 0x1193c9658
arg this = <instance of Score>
arg oscFilePath = "/tmp/osc815227566"
arg outputFilePath = nil

recordNRT expects you to pass a string for the path where the output audio file will be written. In this case, recordNRT is being called from scaleAndWriteNRT, which passes an argument called outPath to recordNRT.

The only way this would be nil is if you didn't provide a path for the resulting audio file.

For both normalize and normalizeNRT, you have to give two paths: one for the input file, and the other for the new file. If you leave out the second, you'll get this error.

No update needed.
Post by Mike Winters
Which branch would have the fix?
normalizeNRT isn't in any branch yet. It will go into master when it's ready (but it's not ready yet). As it's a new feature, it won't be backported into older versions.

hjh



_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Mike Winters
2014-10-20 20:04:21 UTC
Permalink
Thank you very much James. Indeed I was not supplying the output path.
After putting test-NRT-normalize.sc, in your Extensions folder, here is a
MWE:

SoundFile.use(Platform.resourceDir +/+ "sounds/a11wlk01.wav", { |f|
f.normalizeNRT("~/Desktop/me.wav"); });

FYI, I just tested it with a 560MB WAV file. .normalizeNRT works its magic
in ~6 seconds, compared to ~36 seconds with .normalize.

Speed test code:
d
="/Users/macpro41no2/Desktop/Research/Reductions/Full/Div_PTh_4.wav".standardizePath;
(
t = Task.new({
Date.getDate.hourStamp.postln;
SoundFile.use(d, { |f| f.normalize("~/Desktop/me.wav".standardizePath); });
Date.getDate.hourStamp.postln;
});
)
t.play
Post by James Harkins
At Fri, 17 Oct 2014 14:37:52 -0700 (PDT),
Post by Mike Winters
That sounds great. I'll look forward to the update when you have it.
Actually, I checked the code, and the methods do create a temporary OSC
file path. So that's not the issue.
Score:recordNRT 0x1193c9658
arg this = <instance of Score>
arg oscFilePath = "/tmp/osc815227566"
arg outputFilePath = nil
recordNRT expects you to pass a string for the path where the output audio
file will be written. In this case, recordNRT is being called from
scaleAndWriteNRT, which passes an argument called outPath to recordNRT.
The only way this would be nil is if you didn't provide a path for the
resulting audio file.
For both normalize and normalizeNRT, you have to give two paths: one for
the input file, and the other for the new file. If you leave out the
second, you'll get this error.
No update needed.
Post by Mike Winters
Which branch would have the fix?
normalizeNRT isn't in any branch yet. It will go into master when it's
ready (but it's not ready yet). As it's a new feature, it won't be
backported into older versions.
hjh
_______________________________________________
sc-users mailing list
http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Loading...