def downmix_to_mono(process_func):
    '''
    Pre-processing decorator that downmixes frames from multi-channel to mono

    Downmix is achieved by averaging all channels

    >>> from timeside.core.preprocessors import downmix_to_mono
    >>> @downmix_to_mono
    ... def process(analyzer,frames,eod):
    ...     print 'Frames, eod inside process :'
    ...     print frames, eod
    ...     return frames, eod
    ...
    >>> import numpy as np
    >>> frames = np.asarray([[1,2],[3,4],[5,6],[7,8],[9,10]])
    >>> eod = False
    >>> frames_, eod_ = process(object(),frames,eod)
    Frames, eod inside process :
    [1.5 3.5 5.5 7.5 9.5] False

    Outside Process frames and eod are preserved :

    >>> frames_
    array([[ 1,  2],
           [ 3,  4],
           [ 5,  6],
           [ 7,  8],
           [ 9, 10]])
    >>> eod_
    False
    '''

    import functools

    @functools.wraps(process_func)
    def wrapper(analyzer, frames, eod):
        # Pre-processing
        if frames.ndim > 1:
            downmix_frames = frames.mean(axis=-1)
        else:
            downmix_frames = frames
        # Processing
        process_func(analyzer, downmix_frames, eod)

        return frames, eod
    return wrapper
Pre-processing decorator that downmixes frames from multi-channel to mono

    Downmix is achieved by averaging all channels

    >>> from timeside.core.preprocessors import downmix_to_mono
    >>> @downmix_to_mono
    ... def process(analyzer,frames,eod):
    ...     print 'Frames, eod inside process :'
    ...     print frames, eod
    ...     return frames, eod
    ...
    >>> import numpy as np
    >>> frames = np.asarray([[1,2],[3,4],[5,6],[7,8],[9,10]])
    >>> eod = False
    >>> frames_, eod_ = process(object(),frames,eod)
    Frames, eod inside process :
    [1.5 3.5 5.5 7.5 9.5] False

    Outside Process frames and eod are preserved :

    >>> frames_
    array([[ 1,  2],
           [ 3,  4],
           [ 5,  6],
           [ 7,  8],
           [ 9, 10]])
    >>> eod_
    False