view framer.yeti @ 46:00b604d7faf9

Use complex class for output of FFT
author Chris Cannam
date Sat, 29 Dec 2012 14:36:13 +0000
parents 1f80673af4c7
children f24e0bf01dda
line wrap: on
line source

module framer;

/**
 * Framer expresses a stream (or a file) as a lazy list of (possibly
 * overlapping) frames of mono data.
 */

vec = load fvector;
block = load block;
af = load audiofile;

blockList framesize stream =
    if stream.finished? then
       (stream.close (); [] );
    else
        block.resizedTo framesize (stream.readMono framesize)
            :. \(blockList framesize stream);
    fi;

overlappingBlockList size hop stream valid buffer
    is number -> number -> 'a -> number -> ~double[] -> 'b =
   (
    b = stream.readMono hop;
    obtained = block.length b;
    samples = block.unblock b;

    // Retain framesize - hop samples from old buffer, add hop samples
    // (zero-padded if necessary) just read
    buffer = vec.concat
       [vec.rangeOf buffer hop (size-hop),
        vec.resizedTo hop samples];

    // Number of "valid" elements (not tail-end zero-padding) left in buffer
    remaining = valid - (hop - obtained);

    if remaining <= 0 then
        stream.close ();
        [];
    else
        v = block.block buffer;
        v :. \(overlappingBlockList size hop stream remaining buffer);
    fi);

frames { framesize, hop } stream =
    if framesize == hop then
        blockList framesize stream
    else
        overlappingBlockList framesize hop stream 
            framesize (vec.zeros framesize);
    fi;

framesOfFile { framesize, hop } filename =
    if framesize == hop then
        blockList framesize (af.open filename)
    else
        overlappingBlockList framesize hop (af.open filename)
            framesize (vec.zeros framesize);
    fi;

{ 
    frames,
    framesOfFile,
}