Something went wrong. Try again.
A proof-of-concept proposal for turning standard Rubik's Cubes into smartcubes by embedding speakers into the cube's centercaps.
Something went wrong. Try again.
3.0 kB · 89 lines
Python
at commit 59fa6d42
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889# This Source Code Form is subject to the terms of the Mozilla Public# License, v. 2.0. If a copy of the MPL was not distributed with this# file, You can obtain one at https://mozilla.org/MPL/2.0/.
"""Create a recording with arbitrary duration.
The soundfile module (https://PySoundFile.readthedocs.io/) has to be installed!
"""import argparseimport tempfileimport queueimport sys
import sounddevice as sdimport soundfile as sfimport numpy # Make sure NumPy is loaded before it is used in the callbackassert numpy # avoid "imported but unused" message (W0611)
def int_or_str(text): """Helper function for argument parsing.""" try: return int(text) except ValueError: return text
parser = argparse.ArgumentParser(add_help=False)parser.add_argument( '-l', '--list-devices', action='store_true', help='show list of audio devices and exit')args, remaining = parser.parse_known_args()if args.list_devices: print(sd.query_devices()) parser.exit(0)parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser])parser.add_argument( 'filename', nargs='?', metavar='FILENAME', help='audio file to store recording to')parser.add_argument( '-d', '--device', type=int_or_str, help='input device (numeric ID or substring)')parser.add_argument( '-r', '--samplerate', type=int, help='sampling rate')parser.add_argument( '-c', '--channels', type=int, default=1, help='number of input channels')parser.add_argument( '-t', '--subtype', type=str, help='sound file subtype (e.g. "PCM_24")')args = parser.parse_args(remaining)
q = queue.Queue()
def callback(indata, frames, time, status): """This is called (from a separate thread) for each audio block.""" if status: print(status, file=sys.stderr) q.put(indata.copy())
try: if args.samplerate is None: device_info = sd.query_devices(args.device, 'input') # soundfile expects an int, sounddevice provides a float: args.samplerate = int(device_info['default_samplerate']) if args.filename is None: args.filename = "outputs.wav" # tempfile.mktemp(prefix='delme_rec_unlimited_', # suffix='.wav', dir='')
# Make sure the file is opened before recording anything: with sf.SoundFile(args.filename, mode='x', samplerate=args.samplerate, channels=args.channels, subtype=args.subtype) as file: with sd.InputStream(samplerate=args.samplerate, device=args.device, channels=args.channels, callback=callback): print('#' * 80) print('press Ctrl+C to stop the recording') print('#' * 80) while True: file.write(q.get())except KeyboardInterrupt: print('\nRecording finished: ' + repr(args.filename)) parser.exit(0)except Exception as e: parser.exit(type(e).__name__ + ': ' + str(e))