view yetilab/stream/filter.yeti @ 173:2cb4c78d42db

Another test
author Chris Cannam
date Thu, 02 May 2013 17:38:23 +0100
parents f1c75782e56e
children cd5484b642aa
line wrap: on
line source

module yetilab.stream.filter;

mat = load yetilab.matrix.matrix;

load yetilab.stream.streamtype;

minDurationOf d1 d2 =
    case d1 of 
    Known a:
        case d2 of 
        Known b: Known (min a b);
        Unknown (): Unknown ();
        Infinite (): Known a;
        esac;
    Unknown ():
        case d2 of 
        Known b: Known b;
        Unknown (): Unknown ();
        Infinite (): Unknown ();
        esac;
    Infinite ():
        d2;
    esac;

truncatedTo nsamples s = //!!! should nsamples be a time in seconds?
    {
        get position () = s.position,
        get channels () = s.channels, 
        get sampleRate () = s.sampleRate,
        get available () = Known (nsamples - s.position),
        get finished? () = not (nsamples > s.position),
        read count =
            if nsamples > s.position + count then
                s.read count;
            elif nsamples > s.position then
                s.read (nsamples - s.position)
            else
                mat.zeroMatrix { columns = 0, rows = s.channels }
            fi,
        close = s.close,
    };


//!!! not really mixed -- what's the word for it? one per channel
mixed s1 s2 = //!!! could generalise to list of streams
    {
        get position () = min s1.position s2.position, // can differ after EOS
        get channels () = s1.channels + s2.channels,
        get sampleRate () = s1.sampleRate,
        get available () = minDurationOf s1.available s2.available,
        get finished? () = s1.finished? or s2.finished?,
        read count =
           (outs = map do s: s.read count done [ s1, s2 ];
            minlen = head (sort (map do m: m.size.columns done outs));
            outs = map do m:
                mat.resizedTo { rows = m.size.rows, columns = minlen } m
                done outs;
            mat.newMatrix (RowMajor ())
                (concat (map mat.asRows outs))
            ),
        close = (s1.close (); s2.close ())
    };

{
    truncatedTo, 
    mixed,
//!!!} as {
//    truncatedTo is number -> stream -> stream
}