예제 #1
0
    def one_case(self, interval_start: float, interval_end: float, buffer_length: int,
                 expected_level_in_output: Optional[float], expected_average: Optional[float]):
        host = Host()
        host.sample_rate = 100

        unit = Unit(2, 0, 2, 0, host)

        clips: List[AudioClip] = self.generate_test_clips()
        mocked_waveform_provider = MockedWaveformProvider()
        strategy = Sampler(clips, mocked_waveform_provider)
        strategy.unit = unit

        interval = TimeInterval()
        interval.start_in_seconds = interval_start
        interval.end_in_seconds = interval_end

        out1 = np.zeros(shape=(buffer_length,), dtype=np.float32)
        out2 = np.zeros(shape=(buffer_length,), dtype=np.float32)

        strategy.render(interval, [], [out1, out2], [], [])

        values_tested: bool = False

        if expected_level_in_output is not None:
            expected_buffer = np.zeros(100, ) + expected_level_in_output
            self.assertTrue((out1 == expected_buffer).all())
            values_tested = True

        if expected_average is not None:
            self.assertEqual(expected_average, np.mean(out1))
            self.assertEquals(expected_average, np.mean(out2))
            values_tested = True

        self.assertTrue(values_tested)
예제 #2
0
    def test_vst_plugin_strategy(self):
        host = Host()

        dir_path = os.path.dirname(os.path.realpath(__file__))

        path_to_so: str = dir_path + '/../../submodules/cython-vst-loader/tests/test_plugins' \
                                     '/amsynth-vst.x86_64-linux.so'
        as_bytes = path_to_so.encode('utf-8')

        unit = Unit(0, 0, 1, 0, host)
        strategy = VstPlugin(as_bytes, unit)

        unit.set_processing_strategy(strategy)
        event_factory = MidiEventFactory()
        event = event_factory.create_note_on_event(87, 10)
        event.sample_position = 10
        events: List[Event] = [event]

        def generate():
            return np.zeros((host.block_size,), np.float32)

        left_out = generate()
        right_out = generate()

        interval = TimeInterval()
        interval.start_in_bars = 0
        interval.end_in_bars = 1

        self.assertTrue(left_out[13] == 0.0)
        self.assertTrue(right_out[13] == 0.0)

        strategy.render(interval, [], [left_out, right_out], [events], [])

        self.assertTrue(left_out[13] != 0.0)
        self.assertTrue(right_out[13] != 0.0)
예제 #3
0
    def test_chaining_two_stream_units(self):
        host = Host()
        unit1 = Unit(0, 0, 1, 0, host, ConstantLevel(np.float32(0.5)))
        unit2 = Unit(1, 0, 1, 0, host, StreamGain(np.float32(0.5)))
        Connector(unit1.output_stream_nodes[0], unit2.input_stream_nodes[0])

        chain = Chain(unit1, unit2)

        self.assertEqual(len(chain.input_stream_nodes), 0)
        self.assertEqual(len(chain.input_event_nodes), 0)
        self.assertEqual(len(chain.output_stream_nodes), 1)
        self.assertEqual(len(chain.output_event_nodes), 0)

        interval = TimeInterval()
        interval.start_in_bars = 0
        interval.end_in_bars = 1

        interval.start_in_seconds = 0.0
        interval.end_in_seconds = 0.25

        interval.num_samples = 44100 * interval.get_length_in_seconds()
        out_buffer = np.ndarray(shape=(100, ), dtype=np.float32)
        chain.output_stream_nodes[0].render(interval, out_buffer)

        for x in range(0, 100):
            self.assertEqual(0.25, out_buffer[x])
    def test_render_one_buffer_with_a_note(self):
        plugin = DrumSynthPlugin()

        host = Host()
        strategy = DrumSynthStrategy(plugin)
        Unit(0, 0, 1, 0, host, strategy)

        out_stream_buffer = np.zeros(shape=(100, ), dtype=np.float32)

        interval = TimeInterval()
        interval.start_in_bars = 0
        interval.end_in_bars = 1

        factory = MidiEventFactory()

        note_event = factory.create_note_on_event(note=65,
                                                  velocity=70,
                                                  position=50)

        strategy.render(interval, [], [out_stream_buffer], [[note_event]], [])

        zero_sample_indices = [0, 20, 40]
        non_zero_sample_indices = [60, 80, 99]

        for idx in zero_sample_indices:
            self.assertEqual(0, out_stream_buffer[idx])

        for idx in non_zero_sample_indices:
            self.assertNotEqual(0, out_stream_buffer[idx])
예제 #5
0
    def test_fork_and_join(self):
        # +--------+     +--------+
        # |        |     |        |
        # | level1 +--+--> gain1  +--+
        # |        |  |  |        |  | +--------+
        # +--------+  |  +--------+  | |        |
        #             |              +-> mixer  |
        #             |              | |        |
        # +--------+  |  +--------+  | +--------+
        # |        +--+  |        |  |
        # | level2 +-----> gain2  +--+
        # |        |     |        |
        # +--------+     +--------+
        gain1_value = np.float32(0.7)
        gain2_value = np.float32(0.113)

        level1_value = np.float32(0.63)
        level2_value = np.float32(0.47)

        host = Host()

        level1 = Unit(0, 0, 1, 0, host, ConstantLevel(level1_value))
        level2 = Unit(0, 0, 1, 0, host, ConstantLevel(level2_value))

        gain1 = Unit(1, 0, 1, 0, host, StreamGain(gain1_value))
        gain2 = Unit(1, 0, 1, 0, host, StreamGain(gain2_value))

        mixer = Unit(1, 0, 1, 0, host, Transparent())

        Connector(level1.output_stream_nodes[0], gain1.input_stream_nodes[0])
        Connector(level2.output_stream_nodes[0], gain2.input_stream_nodes[0])
        Connector(level2.output_stream_nodes[0], gain1.input_stream_nodes[0])

        Connector(gain1.output_stream_nodes[0], mixer.input_stream_nodes[0])
        Connector(gain2.output_stream_nodes[0], mixer.input_stream_nodes[0])

        interval = TimeInterval()
        interval.start_in_bars = 0
        interval.end_in_bars = 1
        interval.start_in_seconds = -0.1
        interval.end_in_seconds = 0.333333333
        interval.num_samples = 44100 * interval.get_length_in_seconds()

        out_buffer = np.ndarray(shape=(100, ), dtype=np.float32)
        mixer.output_stream_nodes[0].render(interval, out_buffer)

        expected_output_level = (level1_value + level2_value
                                 ) * gain1_value + level2_value * gain2_value

        for x in range(0, 100):
            self.assertEqual(expected_output_level, out_buffer[x])
예제 #6
0
    def compile(self, project: Project) -> List[StreamNode]:
        """
        Given a project, returns a list of stream nodes (as many nodes as many channels
        there are - e.g. 2 for stereo.

        Then the user is expected to iteratively render data from those nodes into buffers.

        :param project: Project
        :return: List[StreamNode]
        """

        compiled_tracks: Dict[Track, Unit] = {}

        host = Host()

        master_unit = self._compile_internal(host, project,
                                             project.master_track,
                                             compiled_tracks)
        return master_unit.output_stream_nodes
    def test_smoke(self):
        host = Host()
        strategy = ConstantLevel(np.float32(0.50))
        unit = Unit(0, 0, 1, 0, host, strategy)

        all_output_nodes = unit.get_all_output_nodes()

        self.assertEqual(1, len(all_output_nodes))

        output_node = all_output_nodes[0]

        interval = TimeInterval()
        interval.start_in_bars = 0
        interval.end_in_bars = 1

        out_buffer = np.ndarray(shape=(100, ), dtype=np.float32)
        output_node.render(interval, out_buffer)

        for x in range(0, 100):
            self.assertEqual(0.5, out_buffer[x])