# Imports import redoxcodedfplayer import network import random import time import machine import os # Configuration volume = 20 intros_folder = 1 songs_folder = 2 outros_folder = 3 silences_folder = 4 reminders_folder = 5 song_selection_count = 1 verboselevel = 2 test_mode = False seedfile_basename = "seed" max_seedfile_count = 16 def main(): global intros_folder, songs_folder, outros_folder, song_selection_count, volume, seedfile_basename, max_seedfile_count, silences_folder, reminders_folder #debug(10, 'main: delaying startup ...') #for i in range(0,5): # print(i) # time.sleep(1) # Disable WLAN to save power debug(10, 'main: disabling WLAN ...') wlan = network.WLAN(network.STA_IF) wlan.active(False) ap = network.WLAN(network.AP_IF) ap.active(False) # Initialise player debug(10, 'main: initialising player ...') time.sleep(0.5) try: machine.UART(0).deinit() except: pass #time.sleep(2) player = redoxcodedfplayer.DFPlayer(uart_id=0,tx_pin_id=16,rx_pin_id=17) player.volume(volume) # Load the random number seed. debug(10, 'main: initialising RNG ...') seed, index = init_rng() # make (dirno,fileno) tuples out of the each type of files (intros, songs, outros, silences, reminders) debug(10, 'main: loading file list ...') intros = [ (intros_folder,i+1) for i in range(0,player.get_files_in_folder(intros_folder)) ] songs = [ (songs_folder,i+1) for i in range(0,player.get_files_in_folder(songs_folder)) ] outros = [ (outros_folder,i+1) for i in range(0,player.get_files_in_folder(outros_folder)) ] silences = [ (silences_folder,i+1) for i in range(0,player.get_files_in_folder(silences_folder)) ] reminders = [ (reminders_folder,i+1) for i in range(0,player.get_files_in_folder(reminders_folder)) ] debug(10, 'intros=%s' % (intros)) debug(10, 'songs=%s' % (songs)) debug(10, 'outros=%s' % (outros)) debug(10, 'silences=%s' % (silences)) debug(10, 'reminders=%s' % (reminders)) debug(10, 'main: constructing playlist ...') playlist = [] if test_mode: playlist += random_sample(intros,1) else: # Append to playlist 1 random intro, random songs, 1 random outro. # random.sample() is not available in MicroPython, so we use random_sample(), which is # defined below. playlist += random_sample(intros,1) playlist += random_sample(songs,song_selection_count) playlist += random_sample(outros,1) playlist += random_sample(silences,1) playlist += random_sample(reminders,1) debug(10, 'playlist=%s' % (playlist)) # At this point we have generated all the random numbers we need so we should save the seed. debug(10, 'main: saving RNG state ...') save_rng_state(seed, index) debug(10, 'main: entering play loop ...') for track in playlist: # Unpack the tuple into a dirno+fileno parameter list (using '*') and play it. player.play(*track) # Wait for track to finish and then loop onto next track. while player.is_playing(): debug(10, 'player is playing') time.sleep(0.1) debug(10, 'player is *NOT* playing') debug(10, 'player has played all tracks in playlist') def random_sample(things, count): random_thing_tuples_tuples = list(zip([ random.random() for _ in range(0,len(things)) ], things)) return [ num for _, num in sorted(random_thing_tuples_tuples, key=lambda x: x[0]) ][:count] def debug(level, message): global verboselevel if verboselevel >= level: print('DEBUG[%d]: %s' % (level, message)) def get_latest_seed_file(): latest = None max_index = -1 for i in range(max_seedfile_count): fname = '%s%03d.txt' % (seedfile_basename, i) if fname in os.listdir(): try: fp = open(fname, 'r') parts = fp.read().strip().split(',') fp.close() except: continue seed = int(parts[0]) index = int(parts[1]) if index > max_index: latest = (seed, index, i) max_index = index return latest if latest else (1, 0, -1) def save_seed(seed, index): next_i = (index + 1) % max_seedfile_count fname = '%s%03d.txt' % (seedfile_basename, next_i) fp = open(fname, 'w') fp.write('%d,%d' % (seed, index + 1)) fp.close() def init_rng(): debug(10, 'init_rnd: calling get_latest_seed_file() ...') seed, index, _ = get_latest_seed_file() debug(10, 'init_rnd: calling random.seed(%d) ...' % (seed)) random.seed(seed) return seed, index def save_rng_state(seed, index): """Save updated seed to file.""" save_seed(seed + 1, index) main()