def is_audio(audio_pin_name): try: p = AudioOut(audio_pin_name) p.deinit() return True except ValueError: return False except RuntimeError: return False
def playFile(filename): wave_file = open(filename, "rb") with WaveFile(wave_file) as wave: with AudioOut(board.SPEAKER) as audio: audio.play(wave) while audio.playing: pass
def tone(pin, frequency, duration=1, length=100): """ Generates a square wave of the specified frequency on a pin :param ~microcontroller.Pin pin: Pin on which to output the tone :param float frequency: Frequency of tone in Hz :param int length: Variable size buffer (optional) :param int duration: Duration of tone in seconds (optional) """ if length * frequency > 350000: length = 350000 // frequency try: # pin with PWM # pylint: disable=no-member with pwmio.PWMOut(pin, frequency=int(frequency), variable_frequency=False) as pwm: pwm.duty_cycle = 0x8000 time.sleep(duration) # pylint: enable=no-member except ValueError: # pin without PWM sample_length = length square_wave = array.array("H", [0] * sample_length) for i in range(sample_length / 2): square_wave[i] = 0xFFFF square_wave_sample = audiocore.RawSample(square_wave) square_wave_sample.sample_rate = int(len(square_wave) * frequency) with AudioOut(pin) as dac: if not dac.playing: dac.play(square_wave_sample, loop=True) time.sleep(duration) dac.stop()
def play_file(filename): print("Playing file: " + filename) wave_file = open(filename, "rb") with WaveFile(wave_file) as wave: with AudioOut(board.SPEAKER) as audio: audio.play(wave) while audio.playing: pass print("Finished")
def main(): enable_speakers() speaker = AudioOut(board.SPEAKER) pixels = NeoPixel(board.NEOPIXEL, PIXEL_COUNT) pixels.brightness = 0.05 handler = Handler(speaker, pixels) events = [TouchEvent(i, handler.handle) for i in TOUCH_PADS] while True: for event in events: event.process()
def play_file(filename): print("") print("----------------------------------") print("playing file "+filename) with AudioOut(board.A0) as a: with WaveFile(open(filename, "rb")) as wf: a.play(wf) while a.playing: pass print("finished") print("----------------------------------")
def play_file(number): # The two files assigned to buttons A & B audiofiles = ["eins.wav", "zwei.wav", "drei.wav", "vier.wav", "funf.wav", "sechs.wav"] filename = audiofiles[number] print("Playing file: " + filename) wave_file = open(filename, "rb") with WaveFile(wave_file) as wave: with AudioOut(board.SPEAKER) as audio: audio.play(wave) while audio.playing: pass print("Finished")
pin.deinit() random.seed(random_value) # Without os.urandom() the random library does not set a useful seed try: os.urandom(4) except NotImplementedError: seed_with_noise() # Turn the speaker on speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_enable.value = True audio = AudioOut(board.SPEAKER) # Number of seconds SHORTEST_DELAY = 3.0 LONGEST_DELAY = 7.0 red = (40, 0, 0) black = (0, 0, 0) A4refhz = 440 midpoint = 32768 twopi = 2 * math.pi def sawtooth(angle): """A sawtooth function like math.sin(angle).
LIGHT_VALUE = 1500 # value at which we turn on / off the laughing MODE_SWITCH_TIME = 0.2 # how long to wait for a changed reading # to be consistent to change modes LAUGHING_SPEED = 0.1 # how fast the animation runs USE_AUDIO = True # if you want to disable audio USE_ANIMATION = True # if you want to disable animation # turn the board neopixel off so it does not affect our light sensor supervisor.set_rgb_status_brightness(0) # Light sensor to know when to turn on light = analogio.AnalogIn(board.A3) # Set up audio audio = AudioOut(board.A0) mp3 = open("laugh.mp3", "rb") decoder = MP3Decoder(mp3) # set up the display for the board or external displayio.release_displays() spi = board.SPI() tft_cs = board.D11 tft_dc = board.D9 display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=board.D10)
# check for and process touch events check_for_touch(_now) # if it's time to play a sample if LAST_PLAY_TIME + WAIT_TIME <= _now: # print("time to play") # if there are any samples in the loop if len(LOOP) > 0: # open the sample wav file with open(_icons[LOOP[CUR_LOOP_INDEX]][2], "rb") as wave_file: print("playing: {}".format(_icons[LOOP[CUR_LOOP_INDEX]][2])) # initialize audio output pin audio = AudioOut(board.AUDIO_OUT) # initialize WaveFile object wave = WaveFile(wave_file) # play it audio.play(wave) # while it's still playing while audio.playing: # update time variable _now = time.monotonic() # check for and process touch events check_for_touch(_now)
def __init__( self, playlist_file="playlist.json", skin_image="/base_240x320.bmp", skin_config_file="base_config.json", pyportal_titano=False, ): self.SKIN_IMAGE = skin_image self.SKIN_CONFIG_FILE = skin_config_file self.PLAYLIST_FILE = playlist_file # read the skin config data into variable f = open(self.SKIN_CONFIG_FILE, "r") self.CONFIG_DATA = json.loads(f.read()) f.close() if self.PLAYLIST_FILE: try: # read the playlist data into variable f = open(self.PLAYLIST_FILE, "r") self.PLAYLIST = json.loads(f.read()) f.close() except OSError: # file not found self.auto_find_tracks() except ValueError: # json parse error self.auto_find_tracks() else: # playlist file argument was None self.auto_find_tracks() if self.PLAYLIST: try: if len(self.PLAYLIST["playlist"]["files"]) == 0: # valid playlist json data, but no tracks self.auto_find_tracks() except KeyError: self.auto_find_tracks() # initialize clock display self.clock_display = ClockDisplay( text_color=self.CONFIG_DATA["time_color"]) if not pyportal_titano: # standard PyPortal and pynt clock display location # and playlist display parameters self.clock_display.x = 44 self.clock_display.y = 22 _max_playlist_display_chars = 30 _rows = 3 else: # PyPortal Titano clock display location # and playlist display parameters self.clock_display.x = 65 self.clock_display.y = 37 _max_playlist_display_chars = 42 _rows = 4 # initialize playlist display self.playlist_display = PlaylistDisplay( text_color=self.CONFIG_DATA["text_color"], max_chars=_max_playlist_display_chars, rows=_rows, ) if not pyportal_titano: # standard PyPortal and pynt playlist display location self.playlist_display.x = 13 self.playlist_display.y = 234 else: # PyPortal Titano playlist display location self.playlist_display.x = 20 self.playlist_display.y = 354 # set playlist into playlist display self.playlist_display.from_files_list( self.PLAYLIST["playlist"]["files"]) self.playlist_display.current_track_number = 1 # get name of current song self.current_song_file_name = self.PLAYLIST["playlist"]["files"][ self.playlist_display.current_track_number - 1] if not pyportal_titano: # standard PyPortal and pynt max characters for track title _max_chars = 22 else: # PyPortal Titano max characters for track title _max_chars = 29 # initialize ScrollingLabel for track name self.current_song_lbl = scrolling_label.ScrollingLabel( terminalio.FONT, text=self.playlist_display.current_track_title, color=self.CONFIG_DATA["text_color"], max_characters=_max_chars, ) self.current_song_lbl.anchor_point = (0, 0) if not pyportal_titano: # standard PyPortal and pynt track title location self.current_song_lbl.anchored_position = (98, 19) else: # PyPortal Titano track title location self.current_song_lbl.anchored_position = (130, 33) # Setup the skin image file as the bitmap data source self.background_bitmap = displayio.OnDiskBitmap(self.SKIN_IMAGE) # Create a TileGrid to hold the bitmap self.background_tilegrid = displayio.TileGrid( self.background_bitmap, pixel_shader=self.background_bitmap.pixel_shader) # initialize parent displayio.Group super().__init__() # Add the TileGrid to the Group self.append(self.background_tilegrid) # add other UI componenets self.append(self.current_song_lbl) self.append(self.clock_display) self.append(self.playlist_display) # Start playing first track self.current_song_file = open(self.current_song_file_name, "rb") self.decoder = MP3Decoder(self.current_song_file) self.audio = AudioOut(board.SPEAKER) self.audio.play(self.decoder) self.CURRENT_STATE = self.STATE_PLAYING # behavior variables. self._start_time = time.monotonic() self._cur_time = time.monotonic() self._pause_time = None self._pause_elapsed = 0 self._prev_time = None self._seconds_elapsed = 0 self._last_increment_time = 0
try: from audioio import AudioOut except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! FREQUENCY = 440 # 440 Hz middle 'A' SAMPLERATE = 8000 # 8000 samples/second, recommended! # Generate one period of sine wav. length = SAMPLERATE // FREQUENCY sine_wave = array.array("H", [0] * length) for i in range(length): sine_wave[i] = int(math.sin(math.pi * 2 * i / 18) * (2**15) + 2**15) # Enable the speaker speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_enable.value = True audio = AudioOut(board.SPEAKER) sine_wave_sample = RawSample(sine_wave) audio.play(sine_wave_sample, loop=True) # Keep playing the sample over and over time.sleep(1) # until... audio.stop() # We tell the board to stop
USE_AUDIO = True # if you want to disable audio USE_ANIMATION = True # if you want to disable animation # turn the board neopixel off so it does not affect our light sensor supervisor.set_rgb_status_brightness(0) # Light sensor to know when to turn on light = analogio.AnalogIn(board.LIGHT) # speaker enable if the board supports it speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_enable.value = True # Set up audio audio = AudioOut(board.SPEAKER) mp3 = open("laugh.mp3", "rb") decoder = MP3Decoder(mp3) # set up the display for the board or external display = tft_gizmo.TFT_Gizmo() display.brightness = 0.0 # start off # load the images for the skull bitmap_top, palette_top = adafruit_imageload.load("/skull_top.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) bitmap_close, palette_close = adafruit_imageload.load( "/skull_close.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette)
try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! FREQUENCY = 440 # 440 Hz middle 'A' SAMPLERATE = 8000 # 8000 samples/second, recommended! # Generate one period of sine wav. length = SAMPLERATE // FREQUENCY sine_wave = array.array("H", [0] * length) for i in range(length): sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2**15) + 2**15) # Enable the speaker speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.direction = digitalio.Direction.OUTPUT speaker_enable.value = True audio = AudioOut(board.SPEAKER) sine_wave_sample = RawSample(sine_wave) # A single sine wave sample is hundredths of a second long. If you set loop=False, it will play # a single instance of the sample (a quick burst of sound) and then silence for the rest of the # duration of the time.sleep(). If loop=True, it will play the single instance of the sample # continuously for the duration of the time.sleep(). audio.play(sine_wave_sample, loop=True) # Play the single sine_wave sample continuously... time.sleep(1) # for the duration of the sleep (in seconds) audio.stop() # and then stop.
# HARDWARE SETUP ---- mode selector, LED, speaker, keypad ---- analog_in = AnalogIn(board.A2) # Slider for "mode selector" mode = (analog_in.value * (num_modes - 1) + 32768) // 65536 # Initial mode bounds = ( # Lower, upper limit to detect change from current mode (mode * 65535 - 32768) // (num_modes - 1) - 512, (mode * 65535 + 32768) // (num_modes - 1) + 512, ) led = pwmio.PWMOut(board.A3) led.duty_cycle = 0 # Start w/LED off led_sync = 0 # LED behavior for different sounds, see comments later # AudioOut MUST be invoked AFTER PWMOut, for correct WAV playback timing. # Maybe sharing a timer or IRQ. Unsure if bug or just overlooked docs. audio = AudioOut(board.A0) # A0 is DAC pin on M0/M4 boards # To simplify the build, each key is wired to a separate input pin rather # than making an X/Y matrix. CircuitPython's keypad module is still used # (treating the buttons as a 1x10 matrix) as this gives us niceties such # as background processing, debouncing and an event queue! keys = keypad.Keys([x[0] for x in pin_to_wave], value_when_pressed=False, pull=True) event = keypad.Event() # Single key event for re-use keys.events.clear() # Load all the WAV files from the pin_to_wave list, and one more for the # mode selector, sharing a common buffer since only one is used at a time. # Also, play a startup sound. audio_buf = bytearray(1024)
break_beam.direction = Direction.INPUT break_beam.pull = Pull.UP # pwm for servo servo_pwm = pwmio.PWMOut(board.A4, duty_cycle=2 ** 15, frequency=50) # servo setup servo = servo.Servo(servo_pwm) servo.angle = 90 # import dreidel song audio file wave_file = open("dreidel_song.wav", "rb") wave = WaveFile(wave_file) # setup for audio out audio = AudioOut(board.A0) # setup for matrix display matrix = Matrix(width=32, height=32) display = matrix.display group = displayio.Group() # import dreidel bitmap dreidel_bit, dreidel_pal = adafruit_imageload.load("/dreidel.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) dreidel_grid = displayio.TileGrid(dreidel_bit, pixel_shader=dreidel_pal, width=1, height=1, tile_height=32, tile_width=32,
except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! button = digitalio.DigitalInOut(board.A1) button.switch_to_input(pull=digitalio.Pull.UP) # The listed mp3files will be played in order mp3files = ["begins.mp3", "xfiles.mp3"] # You have to specify some mp3 file when creating the decoder mp3 = open(mp3files[0], "rb") decoder = MP3Decoder(mp3) audio = AudioOut(board.A0) while True: for filename in mp3files: # Updating the .file property of the existing decoder # helps avoid running out of memory (MemoryError exception) decoder.file = open(filename, "rb") audio.play(decoder) print("playing", filename) # This allows you to do other things while the audio plays! while audio.playing: pass print("Waiting for button press to continue!") while button.value:
except ImportError: from audioio import RawSample try: from audioio import AudioOut except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! button = digitalio.DigitalInOut(board.A1) button.switch_to_input(pull=digitalio.Pull.UP) tone_volume = 0.1 # Increase this to increase the volume of the tone. frequency = 440 # Set this to the Hz of the tone you want to generate. length = 8000 // frequency sine_wave = array.array("H", [0] * length) for i in range(length): sine_wave[i] = int( (1 + math.sin(math.pi * 2 * i / length)) * tone_volume * (2**15 - 1)) audio = AudioOut(board.A0) sine_wave_sample = RawSample(sine_wave) while True: if not button.value: audio.play(sine_wave_sample, loop=True) time.sleep(1) audio.stop()
# Make the input capacitive touchpads capPins = (board.A1, board.A2, board.A3, board.A4, board.A5, board.A6, board.TX) touchPad = [] for i in range(7): touchPad.append(touchio.TouchIn(capPins[i])) # The seven files assigned to the touchpads audiofiles = [ "bd_tek.wav", "elec_hi_snare.wav", "elec_cymbal.wav", "elec_blip2.wav", "bd_zome.wav", "bass_hit_c.wav", "drum_cowbell.wav" ] audio = AudioOut(board.SPEAKER) def play_file(filename): print("playing file " + filename) file = open(filename, "rb") wave = WaveFile(file) audio.play(wave) time.sleep(bpm / 960) # Sixteenth note delay while True: for i in range(7): if touchPad[i].value: play_file(audiofiles[i])
#audio try: from audiocore import WaveFile except ImportError: from audioio import WaveFile try: from audioio import AudioOut except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! audio = AudioOut(board.A0) # Speaker wave_file = None # Set up accelerometer on I2C bus, 4G range: i2c = board.I2C() accel = adafruit_lis3dh.LIS3DH_I2C(i2c) accel.range = adafruit_lis3dh.RANGE_4_G def play_wav(name, loop=False): """ Play a WAV file in the 'sounds' directory. :param name: partial file name string, complete name will be built around this, e.g. passing 'foo' will play file 'sounds/foo.wav'. :param loop: if True, sound will repeat indefinitely (until interrupted by another sound).
# current waveform type. Will get changed from the last column current_wave_type = "sine" # load the notes dictionary for wave_type in WAVE_TYPES: for octave in range(3, 6): # [3,4,5] for note_letter in note_letters: # note with octave e.g. a4 cur_note = "{}{}".format(note_letter, octave) # add wave file to dictionary key = "{}{}".format(wave_type, cur_note) notes[key] = WaveFile( open("notes/{}/{}.wav".format(wave_type, cur_note), "rb")) # main audio object audio = AudioOut(left_channel=board.A0, right_channel=board.A1) # mixer to allow pylyphonic playback mixer = Mixer(voice_count=8, sample_rate=8000, channel_count=2, bits_per_sample=16, samples_signed=True) audio.play(mixer) # turn on the rainbow lights for i, color in enumerate(colors): trellis.pixels[i, 0] = color trellis.pixels[i, 1] = color trellis.pixels[i, 2] = color
except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! # The mp3 files on the sd card will be played in alphabetical order mp3files = sorted("/sd/" + filename for filename in os.listdir("/sd") if filename.lower().endswith("mp3")) voodoo = [1, 2, 3] # You have to specify some mp3 file when creating the decoder mp3 = open(mp3files[0], "rb") decoder = MP3Decoder(mp3) audio = AudioOut(board.A0, right_channel=board.A1) speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE) speaker_enable.switch_to_output(True) while True: for filename in mp3files: print("Playing", filename) # Updating the .file property of the existing decoder # helps avoid running out of memory (MemoryError exception) decoder.file = open(filename, "rb") audio.play(decoder) # This allows you to do other things while the audio plays! while audio.playing:
DIGITAL_RE = re.compile(r"(D\d+|BUTTON_)") # External constants DOWN = 1 UP = 2 PROPOGATE = object() # Internal constants PINS = sorted(dir(board)) DIGITALIO = [getattr(board, pin) for pin in PINS if DIGITAL_RE.match(pin)] TOUCHIO = [getattr(board, pin) for pin in PINS if ANALOG_RE.match(pin)] SAMPLERATE = 8000 # recommended AUDIO = AudioOut(board.A0) SPEAKER = DigitalInOut(board.SPEAKER_ENABLE) SPEAKER.direction = Direction.OUTPUT # Internal state RUNNING = True INTERVALS = {} # type: Dict[Callable, Tuple[float, float]] TIMERS = {} # type: Dict[Callable, float] BUTTONS = [] # type: List[Any] DIOS = [] # type: List[DigitalInOut] PRESSES = [] # type: List[Tuple[Callable, Sequence[Any], int]] def tick(fn): # type: (Callable) -> Callable
notesG = [16, 17, 18, 19, 20, 21, 22, 23, 24] states = [False, False, False, False] instrument = "violin" # one of {'violin', 'guitar'} fretChipAddresses = [0b01110000, 0b00100000, 0b01000000, 0b01100000] # E, A, D, G mixer = Mixer(voice_count=4, sample_rate=16000, channel_count=1, bits_per_sample=16, samples_signed=True, buffer_size=(6000)) a = AudioOut(A0) def playNote(scale, note): # discard not allowed note if note not in range(0, 9): print("Note must be 1-9, not playing anything") return # different scales play a different set of notes on a different voice if (scale == 0): noteIndex = notesE[note] channel = 0 elif (scale == 1): noteIndex = notesA[note] channel = 1
### displayio graphical objects from adafruit_display_text.label import Label from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle ### Assuming CLUE if it's not a Circuit Playround (Bluefruit) clue_less = "Circuit Playground" in os.uname().machine if clue_less: ### CPB with TFT Gizmo (240x240) from adafruit_circuitplayground import cp from adafruit_gizmo import tft_gizmo ### Outputs display = tft_gizmo.TFT_Gizmo() audio_out = AudioOut(board.SPEAKER) min_audio_frequency = 100 max_audio_frequency = 4000 pixels = cp.pixels board_pin_output = board.A1 ### Enable the onboard amplifier for speaker cp._speaker_enable.value = True ### pylint: disable=protected-access ### Inputs board_pin_input = board.A2 magnetometer = None ### This indicates device is not present button_left = lambda: cp.button_b button_right = lambda: cp.button_a else:
### Using mixer is a workaround for the nRF52840 PWMAudioOut ### not implementing the quiescent_value after a sample ### has completed playing mixer = Mixer(voice_count=2, sample_rate=16000, channel_count=2, bits_per_sample=16, samples_signed=True) wav_files = ("scanner-left-16k.wav", "scanner-right-16k.wav") ### Use same pins which would be used on a Feather M4 with real DACs AUDIO_PIN_L = board.A0 AUDIO_PIN_R = board.A1 audio_out = AudioOut(AUDIO_PIN_L, right_channel=AUDIO_PIN_R) wav_fh = [open(fn, "rb") for fn in wav_files] wavs = [WaveFile(fh) for fh in wav_fh] ### Voice 0 behaves strangely ### https://github.com/adafruit/circuitpython/issues/3210 mixer.voice[0].level = 0.0 mixer.voice[1].level = 1.0 audio_out.play(mixer) audio = mixer.voice[1] uart = busio.UART(board.TX, board.RX, baudrate=115200) rx_bytes = bytearray(1)
class WinampApplication(displayio.Group): """ WinampApplication Helper class that manages song playback and UI components. :param playlist_file: json file containing the playlist of songs :param skin_image: BMP image file for skin background :param skin_config_file: json file containing color values :param pyportal_titano: boolean value. True if using Titano, False otherwise. """ STATE_PLAYING = 0 STATE_PAUSED = 1 # pylint: disable=too-many-statements,too-many-branches def __init__( self, playlist_file="playlist.json", skin_image="/base_240x320.bmp", skin_config_file="base_config.json", pyportal_titano=False, ): self.SKIN_IMAGE = skin_image self.SKIN_CONFIG_FILE = skin_config_file self.PLAYLIST_FILE = playlist_file # read the skin config data into variable f = open(self.SKIN_CONFIG_FILE, "r") self.CONFIG_DATA = json.loads(f.read()) f.close() if self.PLAYLIST_FILE: try: # read the playlist data into variable f = open(self.PLAYLIST_FILE, "r") self.PLAYLIST = json.loads(f.read()) f.close() except OSError: # file not found self.auto_find_tracks() except ValueError: # json parse error self.auto_find_tracks() else: # playlist file argument was None self.auto_find_tracks() if self.PLAYLIST: try: if len(self.PLAYLIST["playlist"]["files"]) == 0: # valid playlist json data, but no tracks self.auto_find_tracks() except KeyError: self.auto_find_tracks() # initialize clock display self.clock_display = ClockDisplay( text_color=self.CONFIG_DATA["time_color"]) if not pyportal_titano: # standard PyPortal and pynt clock display location # and playlist display parameters self.clock_display.x = 44 self.clock_display.y = 22 _max_playlist_display_chars = 30 _rows = 3 else: # PyPortal Titano clock display location # and playlist display parameters self.clock_display.x = 65 self.clock_display.y = 37 _max_playlist_display_chars = 42 _rows = 4 # initialize playlist display self.playlist_display = PlaylistDisplay( text_color=self.CONFIG_DATA["text_color"], max_chars=_max_playlist_display_chars, rows=_rows, ) if not pyportal_titano: # standard PyPortal and pynt playlist display location self.playlist_display.x = 13 self.playlist_display.y = 234 else: # PyPortal Titano playlist display location self.playlist_display.x = 20 self.playlist_display.y = 354 # set playlist into playlist display self.playlist_display.from_files_list( self.PLAYLIST["playlist"]["files"]) self.playlist_display.current_track_number = 1 # get name of current song self.current_song_file_name = self.PLAYLIST["playlist"]["files"][ self.playlist_display.current_track_number - 1] if not pyportal_titano: # standard PyPortal and pynt max characters for track title _max_chars = 22 else: # PyPortal Titano max characters for track title _max_chars = 29 # initialize ScrollingLabel for track name self.current_song_lbl = scrolling_label.ScrollingLabel( terminalio.FONT, text=self.playlist_display.current_track_title, color=self.CONFIG_DATA["text_color"], max_characters=_max_chars, ) self.current_song_lbl.anchor_point = (0, 0) if not pyportal_titano: # standard PyPortal and pynt track title location self.current_song_lbl.anchored_position = (98, 19) else: # PyPortal Titano track title location self.current_song_lbl.anchored_position = (130, 33) # Setup the skin image file as the bitmap data source self.background_bitmap = displayio.OnDiskBitmap(self.SKIN_IMAGE) # Create a TileGrid to hold the bitmap self.background_tilegrid = displayio.TileGrid( self.background_bitmap, pixel_shader=self.background_bitmap.pixel_shader) # initialize parent displayio.Group super().__init__() # Add the TileGrid to the Group self.append(self.background_tilegrid) # add other UI componenets self.append(self.current_song_lbl) self.append(self.clock_display) self.append(self.playlist_display) # Start playing first track self.current_song_file = open(self.current_song_file_name, "rb") self.decoder = MP3Decoder(self.current_song_file) self.audio = AudioOut(board.SPEAKER) self.audio.play(self.decoder) self.CURRENT_STATE = self.STATE_PLAYING # behavior variables. self._start_time = time.monotonic() self._cur_time = time.monotonic() self._pause_time = None self._pause_elapsed = 0 self._prev_time = None self._seconds_elapsed = 0 self._last_increment_time = 0 def auto_find_tracks(self): """ Initialize the song_list by searching for all MP3's within two layers of directories on the SDCard. e.g. It will find all of: /sd/Amazing Song.mp3 /sd/[artist_name]/Amazing Song.mp3 /sd/[artist_name]/[album_name]/Amazing Song.mp3 but won't find: /sd/my_music/[artist_name]/[album_name]/Amazing Song.mp3 :return: None """ # list that holds all files in the root of SDCard _root_sd_all_files = os.listdir("/sd/") # list that will hold all directories in the root of the SDCard. _root_sd_dirs = [] # list that will hold all subdirectories inside of root level directories _second_level_dirs = [] # list that will hold all MP3 file songs that we find _song_list = [] # loop over all files found on SDCard for _file in _root_sd_all_files: try: # Check if the current file is a directory os.listdir("/sd/{}".format(_file)) # add it to a list to look at later _root_sd_dirs.append(_file) except OSError: # current file was not a directory, nothing to do. pass # if current file is an MP3 file if _file.endswith(".mp3"): # we found an MP3 file, add it to the list that will become our playlist _song_list.append("/sd/{}".format(_file)) # loop over root level directories for _dir in _root_sd_dirs: # loop over all files inside of root level directory for _file in os.listdir("/sd/{}".format(_dir)): # check if current file is a directory try: # if it is a directory, loop over all files inside of it for _inner_file in os.listdir("/sd/{}/{}".format( _dir, _file)): # check if inner file is an MP3 if _inner_file.endswith(".mp3"): # we found an MP3 file, add it to the list that will become our playlist _song_list.append("/sd/{}/{}/{}".format( _dir, _file, _inner_file)) except OSError: # current file is not a directory pass # if the current file is an MP3 file if _file.endswith(".mp3"): # we found an MP3 file, add it to the list that will become our playlist _song_list.append("/sd/{}/{}".format(_dir, _file)) # format the songs we found into the PLAYLIST data structure self.PLAYLIST = {"playlist": {"files": _song_list}} # print message to user letting them know we auto-generated the playlist print("Auto Generated Playlist from MP3's found on SDCard:") print(json.dumps(self.PLAYLIST)) def update(self): """ Must be called each iteration from the main loop. Responsible for updating all sub UI components and managing song playback :return: None """ self._cur_time = time.monotonic() if self.CURRENT_STATE == self.STATE_PLAYING: # if it's time to increase the time on the ClockDisplay if self._cur_time >= self._last_increment_time + 1: # increase ClockDisplay by 1 second self._seconds_elapsed += 1 self._last_increment_time = self._cur_time self.clock_display.seconds = int(self._seconds_elapsed) # update the track label (scrolling) self.current_song_lbl.update() if self.CURRENT_STATE == self.STATE_PLAYING: # if we are supposed to be playing but aren't # it means the track ended. if not self.audio.playing: # start the next track self.next_track() # store time for comparison later self._prev_time = self._cur_time def play_current_track(self): """ Update the track label and begin playing the song for current track in the playlist. :return: None """ # set the track title self.current_song_lbl.full_text = self.playlist_display.current_track_title # save start time in a variable self._start_time = self._cur_time # if previous song is still playing if self.audio.playing: # stop playing self.audio.stop() # close previous song file self.current_song_file.close() # open new song file self.current_song_file_name = self.PLAYLIST["playlist"]["files"][ self.playlist_display.current_track_number - 1] self.current_song_file = open(self.current_song_file_name, "rb") self.decoder.file = self.current_song_file # play new song file self.audio.play(self.decoder) # if user paused the playback if self.CURRENT_STATE == self.STATE_PAUSED: # pause so it's loaded, and ready to resume self.audio.pause() def next_track(self): """ Advance to the next track. :return: None """ # reset ClockDisplay to 0 self._seconds_elapsed = 0 self.clock_display.seconds = int(self._seconds_elapsed) # increment current track number self.playlist_display.current_track_number += 1 try: # start playing track self.play_current_track() except OSError as e: # file not found print("Error playing: {}".format(self.current_song_file_name)) print(e) self.next_track() return def previous_track(self): """ Go back to previous track. :return: None """ # reset ClockDisplay to 0 self._seconds_elapsed = 0 self.clock_display.seconds = int(self._seconds_elapsed) # decrement current track number self.playlist_display.current_track_number -= 1 try: # start playing track self.play_current_track() except OSError as e: # file not found print("Error playing: {}".format(self.current_song_file_name)) print(e) self.previous_track() return def pause(self): """ Stop playing song and wait until resume function. :return: None """ if self.audio.playing: self.audio.pause() self.CURRENT_STATE = self.STATE_PAUSED def resume(self): """ Resume playing song after having been paused. :return: None """ self._last_increment_time = self._cur_time if self.audio.paused: self.audio.resume() self.CURRENT_STATE = self.STATE_PLAYING
ble = adafruit_ble.BLERadio() if ble.connected: for c in ble.connections: c.disconnect() if ble_enabled.value: print("advertising") ble.start_advertising(advertisement, scan_response) k = Keyboard(hid.devices) kl = KeyboardLayoutUS(k) wave_file = open("jeopardy.wav", "rb") wave = WaveFile(wave_file) audio = AudioOut(board.SPEAKER) while True: if ble_enabled.value: while not ble.connected: pass if ble.connected: print("Connected") led.value = True time.sleep(0.1) led.value = False time.sleep(0.1) led.value = True time.sleep(0.1) led.value = False
from digitalio import DigitalInOut from audioio import WaveFile, AudioOut import board import time def play_file(speaker, path): file = open(path, "rb") audio = WaveFile(file) speaker.play(audio) def enable_speakers(): speaker_control = DigitalInOut(board.SPEAKER_ENABLE) speaker_control.switch_to_output(value=True) enable_speakers() speaker = AudioOut(board.SPEAKER) play_file(speaker, 'piano.wav') time.sleep(100)
from audioio import WaveFile try: from audioio import AudioOut except ImportError: try: from audiopwmio import PWMAudioOut as AudioOut except ImportError: pass # not always supported by every board! button = digitalio.DigitalInOut(board.A1) button.switch_to_input(pull=digitalio.Pull.UP) wave_file = open("StreetChicken.wav", "rb") wave = WaveFile(wave_file) audio = AudioOut(board.A0) while True: audio.play(wave) # This allows you to do other things while the audio plays! t = time.monotonic() while time.monotonic() - t < 6: pass audio.pause() print("Waiting for button press to continue!") while button.value: pass audio.resume() while audio.playing: