Пример #1
0
    def _audio_playback(self, pcm_stream):
        # thread 3: audio playback
        levelmeter = LevelMeter()

        def played(sample):
            if self.client.stream_title != self.stream_title:
                self.stream_title = self.client.stream_title
                if self.song_title_callback:
                    self.song_title_callback(self.stream_title)
                else:
                    print("\n\nNew Song:", self.stream_title, "\n")
            levelmeter.update(sample)
            if self.update_ui:
                self.update_ui(levelmeter, None)
            else:
                levelmeter.print(60, True)

        with Output(mixing="sequential", frames_per_chunk=44100//4) as output:
            output.register_notify_played(played)
            while not self._stop_playback:
                try:
                    audio = pcm_stream.read(44100 * 2 * 2 // 20)
                    if not audio:
                        break
                except (IOError, ValueError):
                    break
                else:
                    if not self._stop_playback:
                        sample = Sample.from_raw_frames(audio, 2, 44100, 2)
                        output.play_sample(sample)
Пример #2
0
    def chunked_frame_data(self, chunksize: int, repeat: bool=False,
                           stopcondition: Callable[[], bool]=lambda: False) -> Generator[memoryview, None, None]:
        notes = itertools.cycle(self.title_music) if repeat else iter(self.title_music)
        attack, decay, sustain, release = self.adsr_times

        num_frames = chunksize // synth_params.norm_samplewidth // synth_params.norm_nchannels
        sample_residue = Sample(None, nchannels=2)
        for v1, v2 in notes:
            if stopcondition():
                break
            vf1 = self.music_freq_table[v1]
            vf2 = self.music_freq_table[v2]
            osc1 = FastTriangle(vf1 * _sidfreq, amplitude=0.5)
            osc2 = FastTriangle(vf2 * _sidfreq, amplitude=0.5)
            f1 = EnvelopeFilter(osc1, attack, decay, sustain, 1.0, release, stop_at_end=True)
            f2 = EnvelopeFilter(osc2, attack, decay, sustain, 1.0, release, stop_at_end=True)
            sample1 = Sample.from_oscillator(f1, 1, synth_params.norm_samplerate)       # length is max. 1 second
            sample2 = Sample.from_oscillator(f2, 1, synth_params.norm_samplerate)       # length is max. 1 second
            sample_residue.join(sample1.stereo_mix(sample2, "R"))
            while len(sample_residue) >= num_frames:
                # TODO optimize this a bit by not using Samples but instead by looping over a memoryview of the frames (just like the super class does)
                yield sample_residue.view_frame_data()[:chunksize]
                sample_residue = Sample.from_raw_frames(sample_residue.view_frame_data()[chunksize:],
                                                        sample_residue.samplewidth, sample_residue.samplerate, sample_residue.nchannels)
        if len(sample_residue):
            yield sample_residue.view_frame_data()
Пример #3
0
def play_console(filename_or_stream):
    with wave.open(filename_or_stream, 'r') as wav:
        samplewidth = wav.getsampwidth()
        samplerate = wav.getframerate()
        nchannels = wav.getnchannels()
        bar_width = 60
        levelmeter = LevelMeter(rms_mode=False, lowest=-50.0)
        with Output(samplerate, samplewidth, nchannels, mixing="sequential") as out:
            print("Audio API used:", out.audio_api)
            if not out.supports_streaming:
                raise RuntimeError("need api that supports streaming")
            out.register_notify_played(levelmeter.update)
            while True:
                frames = wav.readframes(samplerate//update_rate)
                if not frames:
                    break
                sample = Sample.from_raw_frames(frames, wav.getsampwidth(), wav.getframerate(), wav.getnchannels())
                out.play_sample(sample)
                levelmeter.print(bar_width)
            while out.still_playing():
                time.sleep(1/update_rate)
                levelmeter.print(bar_width)
            out.wait_all_played()
    print("\nDone. Enter to exit:")
    input()
Пример #4
0
 def render_samples(self, osc: Oscillator, sample_residue: Sample,
                    sample_chunksize: int, stopcondition: Callable[[], bool] = lambda: False,
                    return_residue: bool = False) -> Generator[memoryview, None, Sample]:
     num_frames = sample_chunksize // synth_params.norm_samplewidth // synth_params.norm_nchannels
     blocks = osc.blocks()
     while not stopcondition():
         try:
             block = next(blocks)
         except StopIteration:
             break
         sample = Sample.from_osc_block(block, osc.samplerate, 2 ** (8 * synth_params.norm_samplewidth - 1)).stereo()
         sample_residue.join(sample)
         while len(sample_residue) >= num_frames:
             yield sample_residue.view_frame_data()[:sample_chunksize]
             sample_residue = Sample.from_raw_frames(sample_residue.view_frame_data()[sample_chunksize:],
                                                     sample_residue.samplewidth, sample_residue.samplerate, sample_residue.nchannels)
     if return_residue:
         return sample_residue
     yield sample_residue.view_frame_data()
     return sample_residue
Пример #5
0
def silence_audio(sid_or_name=None):
    sound_engine.silence(sid_or_name)


def shutdown_audio():
    sound_engine.close()


def check_api():
    a = best_api()
    a.close()


if __name__ == "__main__":
    smp = Sample.from_raw_frames([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 44100, 1)
    chunks = smp.chunked_frame_data(chunksize=51, repeat=True)
    for _ in range(60):
        print(next(chunks).tobytes())
    if os.name == "nt":
        prepare_oggdec_exe()
    sound_engine = init_audio({
        "explosion": ("explosion.ogg", 99),
        "amoeba": ("amoeba.ogg", 99),
        "game_over": ("game_over.ogg", 99)
    })
    print("PLAY SAMPLED SOUNDS...")
    amoeba_sid = sound_engine.play_sample("amoeba", repeat=True)
    time.sleep(3)
    print("PLAY ANOTHER SOUND!")
    sid = sound_engine.play_sample("game_over", repeat=False)