예제 #1
0
class ContinuousModulator(object):
    """
    This class is used in continuous sending mode.
    You pass a list of messages and modulators to it, and it takes care of modulating the messages sequentially.
    This avoids running out of RAM for large amounts of messages.
    """

    BUFFER_SIZE_MB = 100
    WAIT_TIMEOUT = 0.1

    def __init__(self, messages, modulators):
        """
        
        :type messages: list of Message 
        :type modulators: list of Modulator 
        """
        self.messages = messages
        self.modulators = modulators

        self.ring_buffer = RingBuffer(int(self.BUFFER_SIZE_MB * 10**6) // 8)

        self.current_message_index = Value("L", 0)

        self.abort = Value("i", 0)
        self.process = Process(target=self.modulate_continuously)
        self.process.daemon = True

    @property
    def is_running(self):
        return self.process.is_alive()

    def start(self):
        self.abort.value = 0
        try:
            self.process = Process(target=self.modulate_continuously)
            self.process.daemon = True
            self.process.start()
        except RuntimeError as e:
            logger.debug(str(e))

    def stop(self, clear_buffer=True):
        self.abort.value = 1
        if clear_buffer:
            self.ring_buffer.clear()
        if not self.process.is_alive():
            return

        try:
            self.process.join(0.1)
        except RuntimeError as e:
            logger.debug(str(e))

        if self.process.is_alive():
            self.process.terminate()
            self.process.join()

        logger.debug("Stopped continuous modulation")

    def modulate_continuously(self):
        pos = 0
        while True:
            start = self.current_message_index.value
            for i in range(start, len(self.messages)):
                if self.abort.value:
                    return

                message = self.messages[i]
                self.current_message_index.value = i
                modulator = self.modulators[
                    message.modulator_indx]  # type: Modulator
                modulator.modulate(start=pos,
                                   data=message.encoded_bits,
                                   pause=message.pause)
                while not self.ring_buffer.will_fit(
                        len(modulator.modulated_samples)):
                    if self.abort.value:
                        return

                    # Wait till there is space in buffer
                    time.sleep(self.WAIT_TIMEOUT)
                self.ring_buffer.push(modulator.modulated_samples)
                pos += len(modulator.modulated_samples)
예제 #2
0
class ContinuousModulator(object):
    """
    This class is used in continuous sending mode.
    You pass a list of messages and modulators to it, and it takes care of modulating the messages sequentially.
    This avoids running out of RAM for large amounts of messages.
    """

    BUFFER_SIZE_MB = 100
    WAIT_TIMEOUT = 0.1

    def __init__(self, messages, modulators):
        """
        
        :type messages: list of Message 
        :type modulators: list of Modulator 
        """
        self.messages = messages
        self.modulators = modulators

        self.ring_buffer = RingBuffer(int(self.BUFFER_SIZE_MB*10**6)//8)

        self.current_message_index = Value("L", 0)

        self.abort = Value("i", 0)
        self.process = Process(target=self.modulate_continuously)
        self.process.daemon = True

    @property
    def is_running(self):
        return self.process.is_alive()

    def start(self):
        self.abort.value = 0
        try:
            self.process = Process(target=self.modulate_continuously)
            self.process.daemon = True
            self.process.start()
        except RuntimeError as e:
            logger.debug(str(e))

    def stop(self, clear_buffer=True):
        self.abort.value = 1
        if clear_buffer:
            self.ring_buffer.clear()
        if not self.process.is_alive():
            return

        try:
            self.process.join(0.1)
        except RuntimeError as e:
            logger.debug(str(e))

        if self.process.is_alive():
            self.process.terminate()
            self.process.join()

        logger.debug("Stopped continuous modulation")

    def modulate_continuously(self):
        pos = 0
        while True:
            start = self.current_message_index.value
            for i in range(start, len(self.messages)):
                if self.abort.value:
                    return

                message = self.messages[i]
                self.current_message_index.value = i
                modulator = self.modulators[message.modulator_indx]  # type: Modulator
                modulator.modulate(start=pos, data=message.encoded_bits, pause=message.pause)
                while not self.ring_buffer.will_fit(len(modulator.modulated_samples)):
                    if self.abort.value:
                        return

                    # Wait till there is space in buffer
                    time.sleep(self.WAIT_TIMEOUT)
                self.ring_buffer.push(modulator.modulated_samples)
                pos += len(modulator.modulated_samples)
예제 #3
0
class ContinuousModulator(object):
    """
    This class is used in continuous sending mode.
    You pass a list of messages and modulators to it, and it takes care of modulating the messages sequentially.
    This avoids running out of RAM for large amounts of messages.
    """
    WAIT_TIMEOUT = 0.1

    def __init__(self, messages, modulators, num_repeats=-1):
        """
        
        :type messages: list of Message 
        :type modulators: list of Modulator 
        """
        self.messages = messages
        self.modulators = modulators
        self.num_repeats = num_repeats  # -1 or 0 = infinite

        self.ring_buffer = RingBuffer(
            int(settings.CONTINUOUS_BUFFER_SIZE_MB * 1e6) // 8,
            dtype=Modulator.get_dtype())

        self.current_message_index = Value("L", 0)

        self.abort = Value("i", 0)
        self.process = Process(target=self.modulate_continuously,
                               args=(self.num_repeats, ),
                               daemon=True)

    @property
    def is_running(self):
        return self.process.is_alive()

    def start(self):
        self.abort.value = 0
        try:
            self.process = Process(target=self.modulate_continuously,
                                   args=(self.num_repeats, ),
                                   daemon=True)
            self.process.start()
        except RuntimeError as e:
            logger.exception(e)

    def stop(self, clear_buffer=True):
        self.abort.value = 1

        if self.process.is_alive():
            try:
                self.process.join(1.5)
            except RuntimeError as e:
                logger.exception(e)
                self.process.terminate()

        if clear_buffer:
            self.ring_buffer.clear()

        logger.debug("Stopped continuous modulation")

    def modulate_continuously(self, num_repeats):
        rng = iter(int, 1) if num_repeats <= 0 else range(
            0, num_repeats)  # <= 0 = forever
        for _ in rng:
            if self.abort.value:
                return

            start = self.current_message_index.value

            for i in range(start, len(self.messages)):
                if self.abort.value:
                    return

                message = self.messages[i]
                self.current_message_index.value = i
                modulator = self.modulators[
                    message.modulator_index]  # type: Modulator
                modulated = modulator.modulate(start=0,
                                               data=message.encoded_bits,
                                               pause=message.pause)
                while not self.ring_buffer.will_fit(len(modulated)):
                    if self.abort.value:
                        return

                    # Wait till there is space in buffer
                    time.sleep(self.WAIT_TIMEOUT)

                self.ring_buffer.push(modulated)

            self.current_message_index.value = 0