annotate yetilab/stream/framer.yeti @ 138:f68c92bd2adb

Slightly better text placement
author Chris Cannam
date Tue, 23 Apr 2013 17:01:19 +0100
parents d0abc9afe608
children cb5ab186f146
rev   line source
Chris@8 1
Chris@93 2 module yetilab.stream.framer;
Chris@8 3
Chris@25 4 /**
Chris@25 5 * Framer expresses a stream (or a file) as a lazy list of (possibly
Chris@25 6 * overlapping) frames of mono data.
Chris@25 7 */
Chris@25 8
Chris@93 9 block = load yetilab.block.block;
Chris@93 10 bf = load yetilab.block.blockfuncs;
Chris@93 11 af = load yetilab.stream.audiofile;
Chris@93 12 win = load yetilab.transform.window;
Chris@93 13 fft = load yetilab.transform.fft;
Chris@8 14
Chris@32 15 blockList framesize stream =
Chris@14 16 if stream.finished? then
Chris@14 17 (stream.close (); [] );
Chris@13 18 else
Chris@32 19 block.resizedTo framesize (stream.readMono framesize)
Chris@32 20 :. \(blockList framesize stream);
Chris@13 21 fi;
Chris@13 22
Chris@47 23 overlappingBlockList size hop stream valid buffer =
Chris@29 24 (
Chris@29 25 b = stream.readMono hop;
Chris@24 26 obtained = block.length b;
Chris@23 27
Chris@32 28 // Retain framesize - hop samples from old buffer, add hop samples
Chris@29 29 // (zero-padded if necessary) just read
Chris@47 30 buffer = block.concat
Chris@47 31 [block.rangeOf buffer hop (size-hop),
Chris@47 32 block.resizedTo hop b];
Chris@23 33
Chris@23 34 // Number of "valid" elements (not tail-end zero-padding) left in buffer
Chris@24 35 remaining = valid - (hop - obtained);
Chris@23 36
Chris@23 37 if remaining <= 0 then
Chris@23 38 stream.close ();
Chris@23 39 [];
Chris@12 40 else
Chris@47 41 buffer :. \(overlappingBlockList size hop stream remaining buffer);
Chris@23 42 fi);
Chris@14 43
Chris@32 44 frames { framesize, hop } stream =
Chris@32 45 if framesize == hop then
Chris@32 46 blockList framesize stream
Chris@30 47 else
Chris@32 48 overlappingBlockList framesize hop stream
Chris@47 49 framesize (block.zeros framesize);
Chris@30 50 fi;
Chris@14 51
Chris@49 52 windowedFrames { framesize, hop, window } stream =
Chris@49 53 (win = window framesize;
Chris@49 54 map (bf.multiply win) (frames { framesize, hop } stream));
Chris@49 55
Chris@49 56 frequencyDomainFrames { framesize, hop } stream =
Chris@49 57 (f = fft.realForward framesize;
Chris@49 58 map f (windowedFrames { framesize, hop, window = win.hann } stream));
Chris@23 59
Chris@11 60 {
Chris@30 61 frames,
Chris@49 62 windowedFrames,
Chris@49 63 frequencyDomainFrames,
Chris@49 64
Chris@49 65 framesOfFile parameters filename =
Chris@81 66 case af.open filename of
Chris@81 67 Stream s: Frames (frames parameters s);
Chris@81 68 Error e: Error e;
Chris@81 69 esac,
Chris@49 70
Chris@49 71 windowedFramesOfFile parameters filename =
Chris@81 72 case af.open filename of
Chris@81 73 Stream s: Frames (windowedFrames parameters s);
Chris@81 74 Error e: Error e;
Chris@81 75 esac,
Chris@49 76
Chris@49 77 frequencyDomainFramesOfFile parameters filename =
Chris@81 78 case af.open filename of
Chris@81 79 Stream s: Frames (frequencyDomainFrames parameters s);
Chris@81 80 Error e: Error e;
Chris@81 81 esac,
Chris@11 82 }
Chris@8 83