# Path: gum/lib/event.py
# class Signal(object):
# 
#     def __init__(self):
#         self.__slots = WeakValueDictionary()
# 
#         # For keeping references to _FuncHost objects.
#         self.__funchosts = {}
# 
#     def __call__(self, *args, **kargs):
#         for key in self.__slots:
#             func, _ = key
#             func(self.__slots[key], *args, **kargs)
# 
#     def connect(self, slot):
#         if inspect.ismethod(slot):
#             key = (slot.im_func, id(slot.im_self))
#             self.__slots[key] = slot.im_self
#         else:
#             host = _FuncHost(slot)
#             self.connect(host.meth)
#             # We stick a copy in here just to keep the instance alive.
#             self.__funchosts[slot] = host
# 
#     def disconnect(self, slot):
#         if inspect.ismethod(slot):
#             key = (slot.im_func, id(slot.im_self))
#             if key in self.__slots:
#                 self.__slots.pop(key)
#         else:
#             if slot in self.__funchosts:
#                 self.disconnect(self.__funchosts[slot].meth)
#                 self.__funchosts.pop(slot)
# 
#     def clear(self):
#         self.__slots.clear()
#         self.__funchosts.clear()
# 
# Path: gum/lib/history.py
# class Action(object):
# class History(object):
#     def __init__(self, do, undo):
#     def do(self):
#     def undo(self):
#     def __init__(self):
#     def _push(self, action):
#     def undo(self):
#     def redo(self):
#     def add(self, do, undo):
#     def revision(self):
#     def is_empty(self):
#     def testAction():
#     def testHistory():    
# 
# Path: gum/lib/edit.py
# def resample(frames, ratio):
# def mix_channels(frames, gain_lists):
# def mix_channels_auto(frames, n):


from gum.lib.event import Signal
from gum.lib import history, edit
from copy import copy
    from copy import copy
    from math import sin
    from gum.lib import mock
import pysndfile
import os.path
import numpy
    import gum
    import os

    def paste(self, start, end, clip):
        saved = copy(self.frames[start:end])
        do = (self._do_paste, (start, end, clip))
        undo = (self._do_paste, (start, start + len(clip), saved))
        self.history.add(do, undo)
        self.changed()

    def _do_paste(self, start, end, clip):
        if self.is_empty():
            self.frames = clip
        else:
            # FIXME: should resample
            clip = edit.mix_channels_auto(clip, self.numchan())
            x = self.frames
            y = numpy.concatenate((x[:start], clip, x[end:]))
            self.frames = y

    def mix(self, start, end, clip):
        saved = copy(self.frames[start:start + len(clip)])
        do = (self._do_mix, (start, end, clip))
        undo = (self._do_paste, (start, start + len(clip), saved))
        self.history.add(do, undo)
        self.changed()

    def _do_mix(self, start, end, clip):
        if self.is_empty():
            self.frames = clip
        else:
            # FIXME: should resample

# Path: gum/lib/event.py
# class Signal(object):
# 
#     def __init__(self):
#         self.__slots = WeakValueDictionary()
# 
#         # For keeping references to _FuncHost objects.
#         self.__funchosts = {}
# 
#     def __call__(self, *args, **kargs):
#         for key in self.__slots:
#             func, _ = key
#             func(self.__slots[key], *args, **kargs)
# 
#     def connect(self, slot):
#         if inspect.ismethod(slot):
#             key = (slot.im_func, id(slot.im_self))
#             self.__slots[key] = slot.im_self
#         else:
#             host = _FuncHost(slot)
#             self.connect(host.meth)
#             # We stick a copy in here just to keep the instance alive.
#             self.__funchosts[slot] = host
# 
#     def disconnect(self, slot):
#         if inspect.ismethod(slot):
#             key = (slot.im_func, id(slot.im_self))
#             if key in self.__slots:
#                 self.__slots.pop(key)
#         else:
#             if slot in self.__funchosts:
#                 self.disconnect(self.__funchosts[slot].meth)
#                 self.__funchosts.pop(slot)
# 
#     def clear(self):
#         self.__slots.clear()
#         self.__funchosts.clear()
# 
# Path: gum/lib/history.py
# class Action(object):
# class History(object):
#     def __init__(self, do, undo):
#     def do(self):
#     def undo(self):
#     def __init__(self):
#     def _push(self, action):
#     def undo(self):
#     def redo(self):
#     def add(self, do, undo):
#     def revision(self):
#     def is_empty(self):
#     def testAction():
#     def testHistory():    
# 
# Path: gum/lib/edit.py
# def resample(frames, ratio):
# def mix_channels(frames, gain_lists):
# def mix_channels_auto(frames, n):


# Path: gum/models/sound.py
from gum.lib.event import Signal
from gum.lib import history, edit
from copy import copy
    from copy import copy
    from math import sin
    from gum.lib import mock
import pysndfile
import os.path
import numpy
    import gum
    import os


    def paste(self, start, end, clip):
        saved = copy(self.frames[start:end])
        do = (self._do_paste, (start, end, clip))
        undo = (self._do_paste, (start, start + len(clip), saved))
        self.history.add(do, undo)
        self.changed()

    def _do_paste(self, start, end, clip):
        if self.is_empty():
            self.frames = clip
        else:
            # FIXME: should resample
            clip = edit.mix_channels_auto(clip, self.numchan())
            x = self.frames
            y = numpy.concatenate((x[:start], clip, x[end:]))
            self.frames = y

    def mix(self, start, end, clip):
        saved = copy(self.frames[start:start + len(clip)])
        do = (self._do_mix, (start, end, clip))
        undo = (self._do_paste, (start, start + len(clip), saved))
        self.history.add(do, undo)
        self.changed()

    def _do_mix(self, start, end, clip):
        if self.is_empty():
            self.frames = clip
        else:
            # FIXME: should resample

            clip = edit.mix_channels_auto(clip, self.numchan())