def play_tone(waves, duration=0.1): if SPEAKER is None: speaker_init() wave_sum = waves.pop() while waves: for i, w in enumerate(waves.pop()): wave_sum[i] += w wave_sample = audioio.RawSample(wave_sum) SPEAKER.play(wave_sample, loop=True) time.sleep(duration) return SPEAKER.stop() omegas = [ 2*math.pi*x for x in freqs ] wave = array.array("H", [0] * 100) dt = 1./SAMPLE_RATE for w in omegas: for i in range( len(wave) ): wave[i] += int(math.sin(w*dt*i) * 2**15) wave_sample = audioio.RawSample(wave) SPEAKER.play(wave_sample, loop=True) time.sleep(duration) SPEAKER.stop() return
def _play_to_pin(tune, base_tone, min_freq, duration, octave, tempo): """Using the prepared input send the notes to the pin """ pwm = isinstance(base_tone, pulseio.PWMOut) for note in tune.split(","): piano_note, note_duration = _parse_note(note, duration, octave) if piano_note in PIANO: if pwm: base_tone.frequency = int(PIANO[piano_note]) base_tone.duty_cycle = 2**15 else: # AudioOut interface changed in CP 3.x if sys.implementation.version[0] >= 3: pitch = int(PIANO[piano_note]) sine_wave = sine.sine_wave(16000, pitch) sine_wave_sample = audioio.RawSample(sine_wave) base_tone.play(sine_wave_sample, loop=True) else: base_tone.frequency = int(16000 * (PIANO[piano_note] / min_freq)) base_tone.play(loop=True) time.sleep(4 / note_duration * 60 / tempo) if pwm: base_tone.duty_cycle = 0 else: base_tone.stop() time.sleep(0.02)
def waveform_sawtooth(length, waves, volumes): for vol in volumes: waveraw = array.array("H", [ midpoint + round(vol * sawtooth((idx + 0.5) / length * twopi + math.pi)) for idx in list(range(length)) ]) waves.append((audioio.RawSample(waveraw), waveraw))
def _generate_sample(self, length=100, volume=None): if self._sample is not None: return self._sine_wave = array.array("H", Express._sine_sample(length, volume)) if sys.implementation.version[0] >= 3: self._sample = audioio.AudioOut(board.SPEAKER) self._sine_wave_sample = audioio.RawSample(self._sine_wave) else: raise NotImplementedError("Please use CircuitPython 3.0 or higher.")
def alarm_audio(): tone_volume = 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)) return audioio.RawSample(sine_wave)
def _generate_sample(self, length=100): if self._sample is not None: return self._sine_wave = array.array("H", Express._sine_sample(length)) if sys.implementation.version[0] >= 3: self._sample = audioio.AudioOut(board.SPEAKER) self._sine_wave_sample = audioio.RawSample(self._sine_wave) else: self._sample = audioio.AudioOut(board.SPEAKER, self._sine_wave)
def __init__(self): self.duration = 0 self.start = 0 tone_volume = 1 # volume is from 0.0 to 1.0 frequency = 440 # Set this to the Hz of the tone you want to generate. length = 4000 // 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)) self.sine_wave_sample = audioio.RawSample(sine_wave)
def play_sin(): channels = 2 length = 8000 // 400 sine_wave = array.array("H", [0] * channels * length) for i in range(length): for j in range(channels): sine_wave[i * channels + j] = int( math.sin(math.pi * 2 * i / length) * (2**13) + 2**15) sample = audioio.RawSample(sine_wave, channel_count=2, sample_rate=8000) audio.play(sample, loop=True) time.sleep(1) audio.stop()
def start_tone(frequency): global _sample length = 100 if length * frequency > 350000: length = 350000 // frequency _sine_wave = array.array("H", _sine_sample(length)) _sample = audioio.AudioOut(board.SPEAKER) _sine_wave_sample = audioio.RawSample(_sine_wave) _sine_wave_sample.sample_rate = int(len(_sine_wave) * frequency) if not _sample.playing: _sample.play(_sine_wave_sample, loop=True)
def make_waveforms(waves, type, samplerate): cyclelength = round(samplerate // A4refhz) length = cyclelength ### a default which some waves will change #cycles = 1 #cycles = 3 ### for perfect fifth #cycles = 4 ### for major chord ### TODO consider volume modification for internal speaker ### vs non speaker use ### major chord has longer sample which initially works ### but will blow up later with four levels if type == "majorchord": volumes = [23000] else: volumes = [23000] ### 30000 clips #volumes = [10000, 18000, 23000, 30000] ### Make some waves at different volumes for vol in volumes: ### Need to create a new array here as audio.RawSample appears not if type == "square": waveraw = array.array("h", [-vol] * (length // 2) + [vol] * (length - length // 2)) else: waveraw = array.array("h", [0] * length) if type == "sawtooth": for i in range(length): waveraw[i] = round((i / (length - 1) - 0.5) * 2 * vol) elif type == "supersaw": halflength = length // 2 quarterlength = length // 4 for i in range(length): ### TODO replace this with a gen function similar to sine waveraw[i] = round(((i / (length - 1) - 0.5 + i % halflength / (halflength - 1) - 0.5 + i % quarterlength / (quarterlength - 1) - 0.5) ) * 2 / 3 * vol) elif type == "noise": waveraw = array.array("h", [0] * length) for i in range(length): waveraw[i] = random.randint(0, 65536) else: return ValueError("Unknown type") waves.append(audioio.RawSample(waveraw))
def playSound(sample_size=8000): (frequency, pulse_width) = readAnalogInputs() length = sample_size // frequency waveform = array.array("H", [0] * length) for t in range(length): v = (1.3 * math.sin(math.pi / length) * t) v = v + ((1.1 * math.sin(math.pi / length) * (t * 3))) v = v + ((1.4 * math.sin(math.pi / length) * (t * 5))) waveform[t] = int(v) # Play that wave, baby! self.speaker_enable.value = True wave_sample = audioio.RawSample(waveform) audio.play(wave_sample, loop=True) # keep playing the sample over and over time.sleep(pulse_width / 1000) # until... audio.stop() # we tell the board to stop
def update(self, shape, frequency): if shape == self.shape and frequency == self.frequency: return if frequency != self.frequency: self.reallocate(frequency) self.frequency = frequency self.shape = shape if shape == shapes.SINE: self.make_sine() elif shape == shapes.SQUARE: self.make_square() elif shape == shapes.TRIANGLE: self.make_triangle() elif shape == shapes.SAWTOOTH: self.make_sawtooth() self.dac.stop() self.dac.play(audioio.RawSample(self.sample, channel_count=1, sample_rate=64000), loop=True)
def play_tones(arr): cflag = 0 audio = audioio.AudioOut(board.A0) for note, l in XY: if cflag == 0: pixels.fill((255, 0, 0)) cflag = 1 else: pixels.fill((0, 255, 0)) cflag = 0 if note != 0: length = SAMPLERATE // (note) 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) sine_wave_sample = audioio.RawSample(sine_wave) audio.play(sine_wave_sample, loop=True) time.sleep(l * 0.4) audio.play(sine_wave_sample, loop=False)
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 pulseio.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 if sys.implementation.version[0] >= 3: square_wave_sample = audioio.RawSample(square_wave) square_wave_sample.sample_rate = int(len(square_wave) * frequency) with audioio.AudioOut(pin) as dac: if not dac.playing: dac.play(square_wave_sample, loop=True) time.sleep(duration) dac.stop() else: sample_tone = audioio.AudioOut(pin, square_wave) sample_tone.frequency = int(len(square_wave) * frequency) if not sample_tone.playing: sample_tone.play(loop=True) time.sleep(duration) sample_tone.stop()
voiceidx = ( voiceidx + 1 ) % len(oscvcas) if oscvcatouse is None: oscvcatouse = nextoscvca next = ( nextoscvca + 1 ) % len(oscvcas) ### advance next return (oscvcatouse, next) ### The next oscillator / vca to use to nextoscvca = 0 wavenames = waveform_names() wavename = wavenames[1] ### TODO - "grep" sawtooth or replace these with enum waves = [] make_waveforms(waves, wavename, basesamplerate) silenceat0 = audioio.RawSample(array.array("H",[0])) ### The voice for extrachannel - a non ADSR wave played with AudioOut ### object to A0 ### TODO - move more stuff into here extravoice = [audio_out_a0, 0] ### Set the output to 0 (0V) rather than its normal midpoint 32768 (1.65V) ### to allow for the imperfectections in the external mixer audio_out_a0.play(silenceat0) ### Initial ADSR values attack = 0.050 release = 0.500 decay = 0.1 sustain = 0.8 ### 80% level
if counter > (len(pitch_frequencies_low) - 1): counter = 0 elif counter < 0: counter = (len(pitch_frequencies_low) - 1) if note_range == 0: FREQUENCY = pitch_frequencies_low[counter] else: FREQUENCY = pitch_frequencies_high[counter] pixels[led_color_data[counter]["pixel"]] = led_color_data[counter]["color"] # Any time we get a sound with a magnitude greater than the value of blowThresshold, trigger the # current pitch (can be changed at top where it is defined) if magnitude > blowThresshold: length = SAMPLERATE // FREQUENCY #create length of sample sine_wave = array.array("H", [0] * length) # create an array for a sine wave for i in range(length): sine_wave[i] = int( math.sin(math.pi * 2 * i / 18) * (2**15) + 2**15) # fill the array with values audio = audioio.AudioOut(board.SPEAKER) sine_wave_sample = audioio.RawSample(sine_wave) audio.play(sine_wave_sample, loop=True) # Play the sample time.sleep(pitchLength) # Play for length of pitchLength audio.stop() # we tell the board to stop audio.deinit() pixels.show() #show the desired neopixel light up on board
# Lissajous version 1 import array, math import board, audioio length = 1000 samples_xy = array.array("H", [0] * length * 2) # Created interleaved x, y samples for idx in range(length): samples_xy[2 * idx] = round( math.sin(math.pi * 2 * idx / length) * 10000 + 10000) samples_xy[2 * idx + 1] = round( math.sin(math.pi * 2 * 3 * idx / length + math.pi / 2) * 10000 + 10000) output_wave = audioio.RawSample(samples_xy, channel_count=2, sample_rate=100 * 1000) dacs.play(output_wave, loop=True) while True: pass
timeout = time.monotonic() while True: print((light.value, )) # determine height of pixels pixel_height = map_range(light.value, DARK, BRIGHT, 0, num_pixels) pixels.fill((0, 0, 0)) for p in range(pixel_height): pixels[p] = wheel(int(p / num_pixels * 255)) pixels.show() # determine squeek freq = int(map_range(light.value, DARK, BRIGHT, 440, 8800)) sine_wave = audioio.RawSample(wave_array, channel_count=1, sample_rate=freq) cpx_audio.stop() cpx_audio.play(sine_wave, loop=True) # check no activity if light.value > ACTIVITY_THRESHOLD: timeout = time.monotonic() # reset our timeout # 4 seconds no activity if time.monotonic() - timeout > 4: break pixels.fill((255, 0, 0)) pixels.show() play_file("03_no_sanctuary.wav")
def makeSoundWave(frequency): 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) return audioio.RawSample(sine_wave)
for i in range(llength): low_freq_wave[i] = int( (1 + math.sin(math.pi * 2 * i / llength)) * tone_volume * (2**15 - 1)) frequency = 2100 # Set this to the Hz of the tone you want to generate. # 2670 Hz length = 8000 // frequency high_freq_wave = array.array("H", [0] * length) for i in range(length): high_freq_wave[i] = int( (1 + math.sin(math.pi * 2 * i / length)) * tone_volume * (2**15 - 1)) analog_in = AnalogIn(board.A1) a = audioio.AudioOut(board.A0) pulse_width = 0.3 sine_wave_sample_hi = audioio.RawSample(high_freq_wave) sine_wave_sample_lo = audioio.RawSample(low_freq_wave) while True: print("transmit:") transmission = input() print("transmitting '%s'" % transmission) for c in transmission: print("byte: %c" % c) frame = hamming.generate_hamming_frame(c) print(frame) for m in frame: if m == 1: a.play(sine_wave_sample_hi, loop=True) else: a.play(sine_wave_sample_lo, loop=True)
# Lissajous version 1 import array, math import board, audioio dacs = audioio.AudioOut(left_channel=board.A0, right_channel=board.A1) length = 1000 baseFreq = 100 #print("length = " + length.tostring()) #print("base frea = " + baseFreq) vP = 15000 center = 15000 samples_xy = array.array("H", [0] * length * 2) # Created interleaved x, y samples for idx in range(length): samples_xy[2 * idx] = round( math.sin(math.pi * 2 * idx / length) * vP + center) samples_xy[2 * idx + 1] = round( math.sin(math.pi * 2 * 3 * idx / length + math.pi / 2) * vP + center) output_wave = audioio.RawSample(samples_xy, channel_count=2, sample_rate=baseFreq * length) dacs.play(output_wave, loop=True) while True: pass
def makewaves(waves, type, samplerate): cyclelength = round(samplerate // A4refhz) length = cyclelength ### a default which some waves will change #cycles = 1 #cycles = 3 ### for perfect fifth #cycles = 4 ### for major chord ### TODO consider volume modification for internal speaker ### vs non speaker use ### major chord has longer sample which initially works ### but will blow up later with four levels if type == "majorchord": volumes = [23000] ### 32000 would go out of bounds else: volumes = [ 30000 ] # running too tight on memory for multiple values at 96 samples TODO review this ### Make some waves at different volumes for vol in volumes: ### Need to create a new array here as audio.RawSample appears not if type == "square": waveraw = array.array("h", [-vol] * (length // 2) + [vol] * (length - length // 2)) else: if type == "sawtooth": waveraw = array.array("h", [0] * length) for i in range(length): waveraw[i] = round((i / (length - 1) - 0.5) * 2 * vol) elif type == "supersaw": waveraw = array.array("h", [0] * length) halflength = length // 2 quarterlength = length // 4 for i in range(length): ### TODO replace this with a gen function similar to sine waveraw[i] = round( ((i / (length - 1) - 0.5 + i % halflength / (halflength - 1) - 0.5 + i % quarterlength / (quarterlength - 1) - 0.5)) * 2 / 3 * vol) elif type == "supersupersaw": cycles = 2 length = cycles * cyclelength waveraw = array.array("h", [0] * length) ### TODO add two 5ths twothirdsclen = 2 * cyclelength // 3 halfclen = cyclelength // 2 thirdclen = cyclelength // 3 quarterclen = cyclelength // 4 sixthclen = cyclelength // 6 eighthlen = cyclelength // 8 for i in range(length): ### TODO replace this with a gen function similar to sine waveraw[i] = round( (2 / 8 * (i / (cyclelength - 1) - 0.5) + 1 / 8 * (i % twothirdsclen / (twothirdsclen - 1) - 0.5) + 1 / 8 * (i % halfclen / (halfclen - 1) - 0.5) + 1 / 8 * (i % thirdclen / (thirdclen - 1) - 0.5) + 1 / 8 * (i % quarterclen / (quarterclen - 1) - 0.5) + 1 / 8 * (i % sixthclen / (sixthclen - 1) - 0.5) + 1 / 8 * (i % eighthlen / (eighthlen - 1) - 0.5)) * 2 * vol) elif type == "sine": waveraw = array.array("h", [0] * length) for i in range(length): waveraw[i] = round( math.sin(math.pi * 2 * i / length) * vol) elif type == "sineoct2": waveraw = array.array("h", [0] * length) for i in range(length): waveraw[i] = round( (math.sin(math.pi * 2 * i / length) * 2 / 3 + math.sin(math.pi * 2 * i / length * 2) * 1 / 3) * vol) elif type == "sinefifth": cycles = 2 length = cycles * cyclelength waveraw = array.array("h", [0] * length) for i in range(length): waveraw[i] = round( (math.sin(math.pi * 2 * i / cyclelength) + math.sin(math.pi * 2 * i / cyclelength * 3 / 2)) * vol / 2) # elif type == "sinemajorchord": # cycles = 4 # length = cycles * cyclelength # waveraw = array.array("h", [0] * length) # for i in range(length): # waveraw[i] = round((math.sin(math.pi * 2 * i / cyclelength) + # math.sin(math.pi * 2 * i / cyclelength * 5/4) + # math.sin(math.pi * 2 * i / cyclelength * 6/4) # ) * vol / 2.5) else: raise ValueError("Unknown type") waves.append(audioio.RawSample(waveraw))
### Keep x position within legal values (if needed) ##dac_a0_x = min(dac_a0_x, dac_x_max) ##dac_a0_x = max(dac_a0_x, 0) dac_a1_y = round((sine * pcy + cosine * pcx + halfrange_y) * mult_y) ### Keep y position within legal values (if needed) ##dac_a1_y = min(dac_a1_y, dac_y_max) ##dac_a1_y = max(dac_a1_y, 0) rawdata[idx] = dac_a0_x - dac_x_mid ### adjust for "h" array rawdata[idx + 1] = dac_a1_y - dac_y_mid ### adjust for "h" array idx += 2 if use_wav: ### 200k (maybe 166.667k) seems to be practical limit ### 1M permissible but seems same as around 200k output_wave = audioio.RawSample(rawdata, channel_count=2, sample_rate=200 * 1000) ### The image may "warp" sometimes with loop=True due to a strange bug ### https://github.com/adafruit/circuitpython/issues/1992 if poor_wav_bug_workaround: while True: dacs.play(output_wave) if time.monotonic() - prev_t >= frame_t: break else: dacs.play(output_wave, loop=True) while time.monotonic() - prev_t < frame_t: pass if not leave_wav_looping: dacs.stop()
maxsustain = 1.0 maxdecay = 2.000 ### TODO - experimental ### a short burst of fading noise designed to play at 8000 at start of play ### These eventually spits a memory error with 1000 dacmidpoint = 32768 samplerate = 8000 sampleraw = array.array("h", [0] * 600) for i in range(1,len(sampleraw) - 1): sampleraw[i] = round(random.randint(-20000,20000 + 1) * (len(sampleraw) - (abs(i - len(sampleraw) // 2) * 2)) / len(sampleraw)) sampleraw[0] = dacmidpoint sampleraw[len(sampleraw) - 1] = dacmidpoint sample = audioio.RawSample(sampleraw, sample_rate=samplerate) del sampleraw triggertransient = False print("Ready to play") while True: (msg, channel) = midi.read_in_port() if isinstance(msg, adafruit_midi.NoteOn) and msg.velocity != 0: # if debug: # print("NoteOn", msg.note, msg.velocity) lastnote = msg.note pitchbend = (pitchbendvalue - 8192) * pitchbendmultiplier basefreq = round(A4refhz * math.pow(2, (lastnote - midinoteA4 + pitchbend) / 12.0)) osc1.frequency = basefreq
def _generate_sample(self, length=100): if self._sample is not None: return self._sine_wave = array.array("H", PyBadger._sine_sample(length)) self._sample = audioio.AudioOut(board.SPEAKER) self._sine_wave_sample = audioio.RawSample(self._sine_wave)
noise_vol = 10000 half_wave_len = int(sample_len / magic_factor / 2) for idx in range(0, sample_len): # change "polarity" to create small square wave with lots of noise if idx % half_wave_len == 0: square_offset = 0 - square_offset sample = random.randint(midpoint + square_offset - noise_vol, midpoint + square_offset + noise_vol) noise_wave_raw[idx] = sample noise_wave_raw[0] = midpoint # start at midpoint #noise_wave_raw = array.array("H", # [random.randint(midpoint-5000, midpoint+5000) # for x in range(sample_len)]) #noise_wave_raw = array.array("h", [0] * sample_len) noise_wave = audioio.RawSample(noise_wave_raw) del noise_wave_raw midi_channel = 10 midi = adafruit_midi.MIDI(midi_in=usb_midi.ports[0], in_channel=midi_channel-1, in_buf_size=6) last_note = None # Read any incoming MIDI messages (events) over USB # looking for note on, note off to turn noise on and off while True: #gc.collect() #print(gc.mem_free()) #print(gc.mem_free())
def play_raw(data): duration = length / (wav.sample_rate * wav.channel_count * wav.bits_per_sample / 8) sample = audioio.RawSample(sine_wave, channel_count=2, sample_rate=8000) audio.play(sample, loop=True) time.sleep(1) audio.stop()
import time import array import math import audioio import board import audiobusio sample_rate = 8000 tone_volume = .1 # Increase or decrease this to adjust the volume of the tone. frequency = 440 # Set this to the Hz of the tone you want to generate. length = sample_rate // frequency # One freqency period sine_wave = array.array("H", [0] * length) for i in range(length): sine_wave[i] = int( (math.sin(math.pi * 2 * frequency * i / sample_rate) * tone_volume + 1) * (2**15 - 1)) # For Feather M0 Express, ItsyBitsy M0 Express, Metro M0 Express audio = audiobusio.I2SOut(board.D1, board.D0, board.D9) # For Feather M4 Express # audio = audiobusio.I2SOut(board.D1, board.D10, board.D11) # For Metro M4 Express # audio = audiobusio.I2SOut(board.D3, board.D9, board.D8) sine_wave_sample = audioio.RawSample(sine_wave, sample_rate=sample_rate) while True: audio.play(sine_wave_sample, loop=True) time.sleep(1) audio.stop() time.sleep(1)