Mercurial > hg > may
changeset 20:0b04bc5d2e53
Update to use Block tagged types throughout
author | Chris Cannam |
---|---|
date | Thu, 20 Dec 2012 11:58:48 +0000 |
parents | 327dac3a8e1f |
children | 6c5d2fe1b260 |
files | audiofile.yeti block.yeti blockmatrix.yeti channels.yeti fmatrix.yeti framer.yeti fvector.yeti playback.yeti stream.yeti syntheticstream.yeti |
diffstat | 10 files changed, 111 insertions(+), 146 deletions(-) [+] |
line wrap: on
line diff
--- a/audiofile.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/audiofile.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -9,8 +9,9 @@ import java.nio: ByteBuffer, ByteOrder; -mat = load fmatrix; +str = load stream; ch = load channels; +block = load block; decode8u bytes doubles n is ~byte[] -> ~double[] -> number -> () = (for [0..n-1] do i: @@ -59,25 +60,25 @@ bytesPerSample = format#getSampleSizeInBits() / 8; bytes = new byte[nframes * channels * bytesPerSample]; bytesRead = stream#read(bytes); - if bytesRead <= 0 then new double[0]; + if bytesRead <= 0 then block.zeros 0; else n = int(bytesRead / bytesPerSample); doubles = new double[n]; decode { format } bytes doubles n; - doubles; + block.block doubles; fi; ); read' { format is ~AudioFormat, stream is ~AudioInputStream } n = - (doubles = readInterleaved' { format, stream } n; + (b = readInterleaved' { format, stream } n; channels = format#getChannels(); - ch.deinterleaved channels doubles; + ch.deinterleaved channels b; ); readMono' { format is ~AudioFormat, stream is ~AudioInputStream } n = - (doubles = readInterleaved' { format, stream } n; + (b = readInterleaved' { format, stream } n; channels = format#getChannels(); - ch.mixedDownFromInterleaved channels doubles; + ch.mixedDownFromInterleaved channels b; ); // Note, all this assumes the stream is non-blocking (i.e. available() @@ -105,19 +106,18 @@ (f = new File(name); stream = AudioSystem#getAudioInputStream(f); format = stream#getFormat(); - { + len = available' { format, stream }; // at start of stream + str.stream { stream, format, - get channels () = format#getChannels(), - get sampleRate () = format#getSampleRate(), + len, + rate = format#getSampleRate(), + channels = format#getChannels(), + get position () = len - available' { stream, format }, 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 }, } );
--- a/block.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/block.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -1,42 +1,27 @@ module block; -import java.util: Arrays; +vec = load fvector; -zeros n = - Block new double[n]; +zeros = Block . vec.zeros; +ones = Block . vec.ones; + +block v is ~double[] -> (Block ~double[]) = + Block v; unblock b is (Block ~double[]) -> ~double[] = case b of Block a: a esac; -ones n = - (v = unblock (zeros n); - for [0..n-1] do i: v[i] := 1.0 done; - Block v); +list' b = vec.list (unblock b); +length' b = vec.length (unblock b); -block l is list?<number> -> (Block ~double[]) = - (arr = array(l); - len = length arr; - v = unblock (zeros len); - for [0..len-1] do i: v[i] := arr[i] done; - Block v); - -norec list b is (Block ~double[]) -> list<number> = - list (unblock b); - -norec length b = - length (list b); - -copyOf b is (Block ~double[]) -> (Block ~double[]) = - (v = unblock b; - Block Arrays#copyOf(v, length b)); - -subset b start len is (Block ~double[]) -> number -> number -> (Block ~double[]) = - Block Arrays#copyOfRange(unblock b, start, start + len); +copyOf b = Block (vec.copyOf (unblock b)); +subset b start len = Block (vec.subset (unblock b) start len); { zeros, ones, block, unblock, -length, +length = length', +list = list', copyOf, subset, }
--- a/blockmatrix.yeti Mon Dec 17 16:00:12 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -module blockmatrix; - -// Basic matrices using a Block for each row. I don't like this one, -// it's clumsy - -block = load block; - -zeroMatrix rows cols = array (map \(block.zeros cols) [1..rows]); - -generateMatrix f rows cols = - (m = zeroMatrix rows cols; - for [0..rows-1] do row: - (rb = block.unblock m[row]; - for [0..cols-1] do col: - rb[col] := f row col; - done); - done; - m); - -constMatrix n = generateMatrix do row col: n done; -randomMatrix = generateMatrix do row col: Math#random() done; -identityMatrix = constMatrix 1; - -width m = if length m > 0 then block.length m[0] else 0 fi; -cols = width; - -height m = length m; -rows = height; - -dimensions m = { cols = width m, rows = height m }; - -copyOfMatrix m = array (map block.copyOf m); - -cell m row col = - (rb = block.unblock m[col]; - rb[row]); - -transposed m is array<Block ~double[]> -> array<Block ~double[]> = - generateMatrix do row col: cell m row col done (cols m) (rows m); - -{ -generateMatrix, constMatrix, randomMatrix, zeroMatrix, identityMatrix, -width, cols, height, rows, dimensions, -copyOfMatrix, -transposed, -} -
--- a/channels.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/channels.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -2,6 +2,7 @@ module channels; vec = load fvector; +block = load block; mat = load fmatrix; interleaved m = @@ -12,42 +13,45 @@ v[col * rows + row] := m[row][col]; done; done; - v); + block.block v); -deinterleaved rows v is number -> ~double[] -> array<~double[]> = - mat.generateMatrix do row col: +deinterleaved rows b = + (v = block.unblock b; + mat.generate do row col: v[rows * col + row] - done rows ((vec.vectorLength v) / rows); + done rows ((vec.length v) / rows)); mixedDown m = - (if empty? m then vec.zeros 0 else + (if empty? m then block.zeros 0 else { cols, rows } = mat.dimensions m; - v = vec.copyOfVector m[0]; + v = vec.copyOf m[0]; for [1..rows-1] do row: for [0..cols-1] do col: v[col] := v[col] + m[row][col]; done; done; - v; + block.block v; fi); -mixedDownFromInterleaved rows v is number -> ~double[] -> ~double[] = - (cols = ((vec.vectorLength v) / rows); +mixedDownFromInterleaved rows b = + (v = block.unblock b; + cols = ((vec.length v) / rows); v' = vec.zeros cols; for [0..rows-1] do row: for [0..cols-1] do col: v'[col] := v'[col] + v[col * rows + row]; done; done; - v'); + block.block v'); -mixedFromInterleavedTo targetRows rows v is number -> number -> ~double[] -> ~double[] = +mixedFromInterleavedTo targetRows rows b = if targetRows == rows then - v; + b; elif targetRows == 1 then - mixedDownFromInterleaved rows v; + mixedDownFromInterleaved rows b; else - cols = ((vec.vectorLength v) / rows); + v = block.unblock b; + cols = ((vec.length v) / rows); v' = vec.zeros (cols * targetRows); for [0..targetRows-1] do target: for [0..cols-1] do col: @@ -58,7 +62,7 @@ fi done done; - v'; + block.block v'; fi; {
--- a/fmatrix.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/fmatrix.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -6,7 +6,7 @@ zeroMatrix rows cols = array (map \(vec.zeros cols) [1..rows]); -generateMatrix f rows cols = +generate f rows cols = (m = zeroMatrix rows cols; for [0..rows-1] do row: for [0..cols-1] do col: @@ -15,11 +15,11 @@ done; m); -constMatrix n = generateMatrix do row col: n done; -randomMatrix = generateMatrix do row col: Math#random() done; +constMatrix n = generate do row col: n done; +randomMatrix = generate do row col: Math#random() done; identityMatrix = constMatrix 1; -width m = if length m > 0 then vec.vectorLength m[0] else 0 fi; +width m = if length m > 0 then vec.length m[0] else 0 fi; cols = width; height m = length m; @@ -27,15 +27,15 @@ dimensions m = { cols = width m, rows = height m }; -copyOfMatrix m = array (map vec.copyOfVector m); +copyOf m = array (map vec.copyOf m); transposed m is array<~double[]> -> array<~double[]> = - generateMatrix do row col: m[col][row] done (cols m) (rows m); + generate do row col: m[col][row] done (cols m) (rows m); { -generateMatrix, constMatrix, randomMatrix, zeroMatrix, identityMatrix, +generate, constMatrix, randomMatrix, zeroMatrix, identityMatrix, width, cols, height, rows, dimensions, -copyOfMatrix, +copyOf, transposed, }
--- a/framer.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/framer.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -2,6 +2,7 @@ module framer; vec = load fvector; +block = load block; af = load audiofile; blockList blocksize stream = @@ -16,24 +17,25 @@ 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 = stream.readMono hopsize; - blen = vec.vectorLength block; - for [0..blen-1] do i: buffer[blocksize - hopsize + i] := block[i] done; + b = stream.readMono hopsize; + samples = block.unblock b; + blen = block.length b; + for [0..blen-1] do i: buffer[blocksize - hopsize + i] := samples[i] done; for [blen..hopsize-1] do i: buffer[blocksize - hopsize + i] := 0.0 done; - v = vec.subVector buffer 0 blocksize; + v = Block (vec.subset buffer 0 blocksize); for [hopsize..blocksize-1] do i: buffer[i - hopsize] := buffer[i] done; v :. \(overlappingBlockList blocksize hopsize stream buffer); fi; overlappingFrames blocksize hopsize stream = - overlappingBlockList blocksize hopsize stream (new double[blocksize]); + overlappingBlockList blocksize hopsize stream (vec.zeros blocksize); frames blocksize stream = blockList blocksize stream; overlappingFramesOfFile blocksize hopsize filename = overlappingBlockList blocksize hopsize (af.open filename) - (new double[blocksize]); + (vec.zeros blocksize); framesOfFile blocksize filename = blockList blocksize (af.open filename);
--- a/fvector.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/fvector.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -2,27 +2,42 @@ import java.util: Arrays; -zeros n = new double[n]; -ones n = (a = zeros n; for [0..n-1] do i: a[i] := 1.0 done; a); +zeros n = + new double[n]; + +ones n = + (a = zeros n; + for [0..n-1] do i: + a[i] := 1.0; + done; + a); vector l is list?<number> -> ~double[] = (arr = array(l); len = length arr; v = zeros len; - for [0..len-1] do i: v[i] := arr[i] done; + for [0..len-1] do i: + v[i] := arr[i]; + done; v); -listWrap a is ~double[] -> list<number> = list a; +list' a is ~double[] -> list<number> = + list a; -vectorLength v = length (listWrap v); +length' = + length . list'; -copyOfVector v is ~double[] -> ~double[] = Arrays#copyOf(v, length(listWrap v)); +copyOf v is ~double[] -> ~double[] = + Arrays#copyOf(v, list' v |> length); -subVector v start len is ~double[] -> number -> number -> ~double[] = Arrays#copyOfRange(v, start, start + len); +subset v start len is ~double[] -> number -> number -> ~double[] = + Arrays#copyOfRange(v, start, start + len); { -zeros, ones, vector, -vectorLength, -copyOfVector, subVector, +zeros, ones, +vector, +length = length', +list = list', +copyOf, subset, }
--- a/playback.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/playback.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -1,7 +1,7 @@ module playback; -vec = load fvector; +block = load block; fr = load framer; af = load audiofile; ch = load channels; @@ -11,7 +11,7 @@ import java.nio: ByteBuffer, ByteOrder; -open rate channels = +open { rate, channels } = (format = new AudioFormat(AudioFormat$Encoding#PCM_SIGNED, rate, 16, channels, channels * 2, rate, false); line = AudioSystem#getSourceDataLine(format); @@ -23,8 +23,9 @@ close () = line#close(), }); -play { line is ~SourceDataLine } samples = - (len = vec.vectorLength samples; +playBlock { line is ~SourceDataLine } b = + (len = block.length b; + samples = block.unblock b; nb = len * 2; bytes = new byte[nb]; bb = ByteBuffer#wrap(bytes, 0, nb); @@ -34,14 +35,14 @@ println "writing \(nb) bytes"; actual = line#write(bytes, 0, nb); ()); + +play line blocks = for blocks (playBlock line); playStream stream = - (line = open stream.sampleRate stream.channels; + (line = open { rate = stream.sampleRate, channels = stream.channels }; blocksize = 10240; - frames = fr.frames blocksize stream; - for frames do frame: - play line (ch.mixedFromInterleavedTo line.channels stream.channels frame) - done; + play line (map (ch.mixedFromInterleavedTo line.channels stream.channels) + (fr.frames blocksize stream)); line.close()); playFile filename = playStream (af.open filename);
--- a/stream.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/stream.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -1,8 +1,6 @@ module stream; -vec = load fvector; - monoStream box = (readAll box = box.read (box.len - box.position); { @@ -10,12 +8,14 @@ get channels () = 1, get sampleRate () = box.rate, get available () = box.len - box.position, + get finished? () = not (box.len > box.position), read = box.read, readInterleaved = box.read, readMono = box.read, readAll = readAll box, readAllInterleaved = readAll box, readAllMono = readAll box, + close = box.close, }); stream box = @@ -25,12 +25,14 @@ get channels () = box.channels, get sampleRate () = box.rate, get available () = box.len - box.position, + get finished? () = not (box.len > box.position), read = box.read, readInterleaved = box.readInterleaved, readMono = box.readMono, readAll = box.read (box.len - box.position), readAllInterleaved = box.readInterleaved (box.len - box.position), readAllMono = box.readMono (box.len - box.position), + close = box.close, }); { monoStream, stream }
--- a/syntheticstream.yeti Mon Dec 17 16:00:12 2012 +0000 +++ b/syntheticstream.yeti Thu Dec 20 11:58:48 2012 +0000 @@ -3,6 +3,7 @@ str = load stream; vec = load fvector; +block = load block; generated rate generator seconds = str.monoStream { @@ -16,26 +17,28 @@ result[i] := generator ((position + i) / rate) done; position := position + rc; - result), + block.block result), + close = \(), }; -sinusoid rate freq = - generated rate (sin . (* (freq / (2*pi * rate)))); +sinusoid rate freq seconds = + generated rate (sin . (* (freq / (2*pi * rate)))) seconds; -whiteNoise rate = - generated rate \((Math#random() * 2.0) - 1.0); +whiteNoise rate seconds = + generated rate \((Math#random() * 2.0) - 1.0) seconds; precalculated rate data is number -> ~double[] -> 'a = - (n = vec.vectorLength data; + (n = vec.length data; str.monoStream { var position = 0, len = n, rate, read count = (rc = min count (len - position); - result = vec.subVector data position rc; + result = vec.subset data position rc; position := position + rc; - result), + block.block result), + close = \(), }); {