changeset 14:ff66f7df30bf

Convert audiofile to returning objects
author Chris Cannam
date Fri, 14 Dec 2012 10:20:00 +0000
parents 5da01c5a5e1f
children 0ddc2aa8885d
files audiofile.yeti framer.yeti
diffstat 2 files changed, 62 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/audiofile.yeti	Fri Dec 14 09:29:29 2012 +0000
+++ b/audiofile.yeti	Fri Dec 14 10:20:00 2012 +0000
@@ -11,18 +11,6 @@
 
 mat = load fmatrix;
 
-open name is string -> 'a = 
-   (f = new File(name);
-    stream = AudioSystem#getAudioInputStream(f);
-    format = stream#getFormat();
-    { stream, format } );
-
-finished? { stream is ~AudioInputStream } =
-    not (stream#available() > 0);
-
-close { stream is ~AudioInputStream } =
-    stream#close();
-
 decode8u bytes doubles n is ~byte[] -> ~double[] -> number -> () =
    (for [0..n-1] do i:
        doubles[i] := (bytes[i] / 128.0) - 1.0;
@@ -65,7 +53,7 @@
         fi
     fi);
 
-readInterleaved { format is ~AudioFormat, stream is ~AudioInputStream } nframes =
+readInterleaved' { format is ~AudioFormat, stream is ~AudioInputStream } nframes =
    (channels = format#getChannels();
     bytesPerSample = format#getSampleSizeInBits() / 8;
     bytes = new byte[nframes * channels * bytesPerSample];
@@ -79,38 +67,60 @@
     fi;
    );
 
-read { format is ~AudioFormat, stream is ~AudioInputStream } n =
-   (doubles = readInterleaved { format, stream } n;
+read' { format is ~AudioFormat, stream is ~AudioInputStream } n =
+   (doubles = readInterleaved' { format, stream } n;
     channels = format#getChannels();
     mat.deinterleaved channels doubles;
    );
 
-readMono { format is ~AudioFormat, stream is ~AudioInputStream } n =
-   (doubles = readInterleaved { format, stream } n;
+readMono' { format is ~AudioFormat, stream is ~AudioInputStream } n =
+   (doubles = readInterleaved' { format, stream } n;
     channels = format#getChannels();
     mat.mixedDownFromInterleaved channels doubles;
    );
 
-//!!! need to read only remaining, not whole stream length
+// Note, all this assumes the stream is non-blocking (i.e. available()
+// is to the end of file)
 
-readAllInterleaved { format is ~AudioFormat, stream is ~AudioInputStream } =
-   readInterleaved { format, stream } stream#getFrameLength();
+available' { format is ~AudioFormat, stream is ~AudioInputStream } =
+    stream#available() / ((format#getSampleSizeInBits() / 8) * format#getChannels());
 
-readAll { format is ~AudioFormat, stream is ~AudioInputStream } =
-   read { format, stream } stream#getFrameLength();
+readAllInterleaved' { format is ~AudioFormat, stream is ~AudioInputStream } =
+    readInterleaved' { format, stream } (available' { format, stream });
 
-readAllMono { format is ~AudioFormat, stream is ~AudioInputStream } =
-   readMono { format, stream } stream#getFrameLength();
+readAll' { format is ~AudioFormat, stream is ~AudioInputStream } =
+    read' { format, stream } (available' { format, stream });
+
+readAllMono' { format is ~AudioFormat, stream is ~AudioInputStream } =
+    readMono' { format, stream } (available' { format, stream });
+
+finished?' { stream is ~AudioInputStream } =
+    not (stream#available() > 0);
+
+close' { stream is ~AudioInputStream } =
+    stream#close();
+
+open name is string -> 'a = 
+   (f = new File(name);
+    stream = AudioSystem#getAudioInputStream(f);
+    format = stream#getFormat();
+    {
+        stream,
+        format,
+        get channels () = format#getChannels(),
+        get sampleRate () = format#getSampleRate(),
+        get available () = available' { stream, format },
+        get finished? () = finished?' { stream },
+        read = read' { stream, format },
+        readAll () = readAll' { stream, format },
+        readInterleaved = readInterleaved' { stream, format },
+        readAllInterleaved () = readAllInterleaved' { stream, format },
+        readMono = readMono' { stream, format },
+        readAllMono () = readAllMono' { stream, format },
+        close () = close' { stream },
+    } );
 
 {
-    open,
-    read,
-    readAll,
-    readInterleaved,
-    readAllInterleaved,
-    readMono,
-    readAllMono,
-    finished?,
-    close
+    open
 }
 
--- a/framer.yeti	Fri Dec 14 09:29:29 2012 +0000
+++ b/framer.yeti	Fri Dec 14 10:20:00 2012 +0000
@@ -4,35 +4,42 @@
 vec = load fvector;
 af = load audiofile;
 
-blockList blocksize file =
-    if af.finished? file then
-       (af.close file; [] );
+blockList blocksize stream =
+    if stream.finished? then
+       (stream.close (); [] );
     else
-        af.readMono file blocksize :. \(blockList blocksize file);
+        stream.readMono blocksize :. \(blockList blocksize stream);
     fi;
 
-overlappingBlockList blocksize hopsize file buffer
+overlappingBlockList blocksize hopsize stream buffer
     is number -> number -> 'a -> ~double[] -> 'b =
-    if af.finished? file then
-       (af.close file; [] ); //!!! wrong! need unit tests! need to read from any stream, not only a file, to facilitate that
+    if stream.finished? then
+       (stream.close (); [] ); //!!! wrong! need unit tests! need to read from any stream, not only a file, to facilitate that
     else
-        block = af.readMono file hopsize;
+        block = stream.readMono hopsize;
         blen = vec.vectorLength block;
         for [0..blen-1] do i: buffer[blocksize - hopsize + i] := block[i] done;
         for [blen..hopsize-1] do i: buffer[blocksize - hopsize + i] := 0.0 done;
         v = vec.subVector buffer 0 blocksize;
         for [hopsize..blocksize-1] do i: buffer[i - hopsize] := buffer[i] done;
-        v :. \(overlappingBlockList blocksize hopsize file buffer);
+        v :. \(overlappingBlockList blocksize hopsize stream buffer);
     fi;
 
-overlappingFrames blocksize hopsize filename =
+overlappingFrames blocksize hopsize stream =
+    overlappingBlockList blocksize hopsize stream (new double[blocksize]);
+
+frames blocksize stream =
+    blockList blocksize stream;
+
+overlappingFramesOfFile blocksize hopsize filename =
     overlappingBlockList blocksize hopsize (af.open filename)
         (new double[blocksize]);
 
-frames blocksize filename =
+framesOfFile blocksize filename =
     blockList blocksize (af.open filename);
 
 { 
-    frames, overlappingFrames
+    frames, overlappingFrames,
+    framesOfFile, overlappingFramesOfFile,
 }