def __init__(self): # Initialization is handled in the windows, otherwise we'd need this sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO) # Open audio device spec_want = sdl2.SDL_AudioSpec(32768, sdl2.AUDIO_S8, 2, 64) spec_have = sdl2.SDL_AudioSpec(0, 0, 0, 0) self.device = sdl2.SDL_OpenAudioDevice(None, 0, spec_want, spec_have, 0) self.sample_rate = spec_have.freq self.sampleclocks = CPU_FREQ / self.sample_rate self.audiobuffer = array("b", [0] * 4096) # Over 2 frames self.audiobuffer_p = c_void_p(self.audiobuffer.buffer_info()[0]) self.clock = 0 self.poweron = True self.sweepchannel = SweepChannel() self.tonechannel = ToneChannel() self.wavechannel = WaveChannel() self.noisechannel = NoiseChannel() self.leftnoise = False self.leftwave = False self.lefttone = False self.leftsweep = False self.rightnoise = False self.rightwave = False self.righttone = False self.rightsweep = False # Start playback (move out of __init__ if needed, maybe for headless) sdl2.SDL_PauseAudioDevice(self.device, 0)
def _init_audio(self): if sdl2.SDL_InitSubSystem(sdl2.SDL_INIT_AUDIO) != 0: raise RuntimeError("Failed to init audio") nsamples = self.chunksize * self.nchannels # For some reason, on OS X, this is 2x bigger than expected. # HACK! import sys if sys.platform == "darwin": nsamples = int(nsamples / 2) self._audio_spec = sdl2.SDL_AudioSpec( self.R, # sdl2.AUDIO_S16MSB, sdl2.AUDIO_S16LSB, # endianness eek! self.nchannels, nsamples, sdl2.SDL_AudioCallback(self._handle_audio_cb), ) self._devid = sdl2.SDL_OpenAudioDevice(None, 0, self._audio_spec, None, 0) # start playing (well-named function!) sdl2.SDL_PauseAudioDevice(self._devid, 0)
def _init_sound(self): """ Perform any necessary initialisations. """ # init sdl audio in this thread separately sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO) self.dev = sdl2.SDL_OpenAudioDevice(None, 0, self.audiospec, None, 0) if self.dev == 0: logging.warning('Could not open audio device: %s', sdl2.SDL_GetError()) # unpause the audio device sdl2.SDL_PauseAudioDevice(self.dev, 0)
def setup(self, fmt): if fmt.codec == AudioCodec.AAC: sdl_audio_fmt = sdl2.AUDIO_F32LSB self._resampler = AACResampler('flt', fmt.sample_rate, fmt.channels) elif fmt.codec == AudioCodec.PCM: raise TypeError("PCM format not implemented") elif fmt.codec == AudioCodec.Opus: raise TypeError("Opus format not implemented") else: raise TypeError("Unknown audio codec: %d" % fmt.codec) self._channels = fmt.channels self._sample_rate = fmt.sample_rate self._decoder = FrameDecoder.audio(fmt.codec) dummy_callback = sdl2.SDL_AudioCallback() target_spec = sdl2.SDL_AudioSpec(self._sample_rate, sdl_audio_fmt, self._channels, self._sample_size, dummy_callback) self._audio_spec = sdl2.SDL_AudioSpec(self._sample_rate, sdl_audio_fmt, self._channels, self._sample_size, dummy_callback) self._dev = sdl2.SDL_OpenAudioDevice( None, 0, target_spec, self._audio_spec, sdl2.SDL_AUDIO_ALLOW_FORMAT_CHANGE) if not self._dev: raise AudioRenderError( "SDL: Could not open audio device: %s - exiting", sdl2.SDL_GetError()) # TODO: Is this even possible? if target_spec.format != self._audio_spec.format: log.error("SDL: We didn't get requested audio format") # Start playback sdl2.SDL_PauseAudioDevice(self._dev, 0)
def main(): if len(sys.argv) != 2: print("usage: 3dwf.py REMOTE_ADDRESS", file=sys.stderr) sys.exit(1) nbins = 256 overlap = 192 rem_address = (sys.argv[1], 3731) conn = socket.create_connection(rem_address) sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO | sdl2.SDL_INIT_AUDIO) window = sdl2.SDL_CreateWindow(b"3D Waterfall", sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED, 800, 600, sdl2.SDL_WINDOW_RESIZABLE | sdl2.SDL_WINDOW_OPENGL) context = sdl2.SDL_GL_CreateContext(window) wf = WFViewer(nbins) wf.init(800, 600) wf.shift = 0 filt = interp_fir_filter(lowpass(np.pi / 4, 512) * np.hamming(512), 4) freqx = freq_translator((0.8/8.0) * np.pi) headlen = max(filt.nhistory, overlap) ringbuf = RingBuf(headlen, np.zeros(headlen + (nbins - overlap) * 512, dtype=np.complex64)) # FIXME global audio_edge audio_edge = 0 def callback(unused, buf, buflen): global audio_edge bufbuf = pybuf_from_memory(buf, buflen, 0x200) # PyBUF_WRITE array = np.frombuffer(bufbuf, np.float32) assert len(array) % filt.interp == 0 # TODO nreqframes = len(array) // filt.interp loc_ringbuf_edge = ringbuf.fill_edge if loc_ringbuf_edge < 0 or (loc_ringbuf_edge - audio_edge) % len(ringbuf) < nreqframes: print("audio underrun", file=sys.stderr) array.fill(0) return # TODO if audio_edge + nreqframes > len(ringbuf): audio_edge = 0 slic = ringbuf.slice(audio_edge - filt.nhistory, audio_edge + nreqframes) array[:] = np.real(freqx(filt(slic))) * wf.volume audio_edge += nreqframes sdl2.SDL_PushEvent(UPDATE_EVENT) audio_spec = sdl2.SDL_AudioSpec(8000, sdl2.AUDIO_F32, 1, 512, sdl2.SDL_AudioCallback(callback)) audio_dev = sdl2.SDL_OpenAudioDevice(None, 0, audio_spec, None, 0) if audio_dev == 0: raise Error('could not open audio device') err_queue = queue.Queue() def readfunc(nbytes): bytes = b'' while len(bytes) < nbytes: ret = conn.recv(nbytes - len(bytes)) if not ret: raise Exception('end of stream') bytes += ret return bytes def thread_target(): try: input_thread(readfunc, ringbuf, nbins, overlap, wf) except Exception as e: err_queue.put(e) event = sdl2.SDL_Event() event.type = sdl2.SDL_QUIT sdl2.SDL_PushEvent(event) other_thread = threading.Thread(target=thread_target) other_thread.setDaemon(True) other_thread.start() sdl2.SDL_PauseAudioDevice(audio_dev, 0) running = True event = sdl2.SDL_Event() while running: sdl2.SDL_WaitEvent(ctypes.byref(event)) while True: if event.type == sdl2.SDL_QUIT: running = False break wf.event(event) if sdl2.SDL_PollEvent(ctypes.byref(event)) == 0: break # FIXME wf.shift = ((ringbuf.fill_edge - audio_edge) % len(ringbuf)) / (nbins - overlap) wf.draw() sdl2.SDL_GL_SwapWindow(window) try: for exc in iter(err_queue.get_nowait, None): sdl2.SDL_ShowSimpleMessageBox(sdl2.SDL_MESSAGEBOX_ERROR, b"Exception", str(exc).encode("ascii"), None) except queue.Empty: pass sdl2.SDL_CloseAudioDevice(audio_dev) sdl2.SDL_GL_DeleteContext(context) sdl2.SDL_DestroyWindow(window) sdl2.SDL_Quit()
def __init__(self, perhiperal_type=Input.Type.JOYSTICK, verbosity=0, silent=False): self.atari = jigo2600.Atari2600() self.speed = 1 self.max_fps = 60. self.aspect = 1.8 self.paused = False self.done = False self.verbosity = verbosity self.cart_db = None self.cart_sha1 = None self.cart_meta = None self.peripheral_type = Input.Type.JOYSTICK self.switches_interface = SwitchesInterface() self.joysticks_interface = JoystickInterface() self.paddles_interface = PaddleInterface() self.input_stream = InputStream() self.has_sdl_audio = False self.has_sdl_gamecontroller = False self.has_sdl_joystick = False # Load the cartridge database. try: data = pkgutil.get_data('jigo2600', 'cartridges.json').decode("utf8") self.cart_db = json.loads(data) del data except FileNotFoundError: if self.verbosity > 0: print(f'Warning: could not open the cartridge metadata file') # Setup the graphics. frame = self.atari.get_current_frame() if sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) != 0: print(sdl2.SDL_GetError()) sys.exit(-1) self.screen = sdl2.SDL_CreateWindow( b"Atari2600", sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, int(frame.width * self.aspect * 2), int(frame.height * 2), sdl2.SDL_WINDOW_SHOWN | sdl2.SDL_WINDOW_RESIZABLE) if not self.screen: print(sdl2.SDL_GetError()) sys.exit(-1) self.renderer = sdl2.SDL_CreateRenderer(self.screen, -1, sdl2.SDL_RENDERER_PRESENTVSYNC) self.texture = sdl2.SDL_CreateTexture(self.renderer, sdl2.SDL_PIXELFORMAT_BGRA32, sdl2.SDL_TEXTUREACCESS_STREAMING, frame.width, frame.height) # Setup the audio. self.has_sdl_audio = not silent and (sdl2.SDL_InitSubSystem( sdl2.SDL_INIT_AUDIO) == 0) if self.has_sdl_audio: self.audio_spec = sdl2.SDL_AudioSpec( 44100, sdl2.AUDIO_U8, 1, 1024, sdl2.SDL_AudioCallback(self.play_audio)) self.audio_dev = sdl2.SDL_OpenAudioDevice(None, 0, self.audio_spec, self.audio_spec, 0) self.audio_buffer_rate = self.audio_spec.freq / self.audio_spec.samples assert self.audio_spec.channels == 1 # Setup the joysticks. self.has_sdl_joystick = (sdl2.SDL_InitSubSystem( sdl2.SDL_INIT_JOYSTICK) == 0) if self.has_sdl_joystick: sdl2.SDL_SetHint(sdl2.SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, b"1") sdl2.SDL_JoystickEventState(sdl2.SDL_ENABLE) # Setup the game controllers. self.has_sdl_gamecontroller = (sdl2.SDL_InitSubSystem( sdl2.SDL_INIT_GAMECONTROLLER) == 0) if self.has_sdl_gamecontroller: sdl2.SDL_GameControllerEventState(sdl2.SDL_ENABLE) data = pkgutil.get_data("jigo2600", "gamecontrollerdb.txt") rw = sdl2.SDL_RWFromConstMem(data, len(data)) n = sdl2.SDL_GameControllerAddMappingsFromRW(rw, False) if self.verbosity > 0: if n == -1: print( f"Warning: could not load the controller database file" ) else: print(f"Loaded {n} game controller mappings")