def sleep(self, seconds): if hasattr(self, 'wav'): samples = fs.raw_audio_string(self.fs.get_samples( int(seconds * 44100))) self.wav.writeframes(''.join(samples)) else: time.sleep(seconds)
def play( self, music_container: Union[str, int, Note, NoteContainer, Bar, Track, PianoKey], recording_file: Union[str, None] = None, record_seconds: int = 4, ) -> None: """Function to play a provided music container and control recording settings Central user facing method of Piano class to play or record a given music container. Handles setting up audio output or recording to audio file and handles switching between playing audio and recording to wav file. Args music_container: A music container such as Notes, NoteContainers, etc. describing a piece of music recording_file: Path to a wav file where audio should be saved to. If passed music_container will be recorded record_seconds: The duration of recording in seconds """ # Check a given music container for invalid notes. See docstring of self._lint_music_container for more details self._lint_music_container(music_container) if recording_file is None: logger.info( "Playing music container: {music_container} via audio".format( music_container=music_container)) self._start_audio_output() self._play_music_container(music_container) else: logger.info( "Recording music container: {music_container} to file {recording_file}" .format(music_container=music_container, recording_file=recording_file)) self._stop_audio_output() self.__fluid_synth_sequencer.start_recording(recording_file) self._play_music_container(music_container) WAV_SAMPLE_FREQUENCY = 44100 samples = globalfs.raw_audio_string( self.__fluid_synth_sequencer.fs.get_samples( int(record_seconds * WAV_SAMPLE_FREQUENCY))) self.__fluid_synth_sequencer.wav.writeframes(bytes(samples)) self.__fluid_synth_sequencer.wav.close() # It seems we have to delete the wav attribute after recording in order to enable switching between # audio output and recording for all music containers. The # mingus.midi.fluidsynth.FluidSynthSequencer.play_Bar and # mingus.midi.fluidsynth.FluidSynthSequencer.play_Track use the # mingus.midi.fluidsynth.FluidSynthSequencer.sleep methods internally which is for some reason also used # to record in mingus. # See also my issue in the mingus repository: https://github.com/bspaans/python-mingus/issues/77 # When wav attribute is present sleep tries to write to the wave file and if not the method just sleeps. # If we do not delete the wav attribute it is still there as None and play_Bar tries to write to the file # resulting in AttributeError: 'NoneType' object has no attribute 'write' delattr(self.__fluid_synth_sequencer, "wav") logger.info("Finished recording to {recording_file}".format( recording_file=recording_file))
samples = [] if sf2 != "": from mingus.midi import pyfluidsynth fs = pyfluidsynth.Synth(samplerate=sr) fsf2 = fs.sfload(sf2) fs.program_select(0, fsf2, 0, 0) for index, lrep_code in enumerate(notes): for index1, lrep_code1 in enumerate(lrep_code): for index2, lrep_code2 in enumerate(lrep_code1): for index3, lrep_code3 in enumerate(lrep_code2): if lrep_code3[0] != -1: fs.noteon(0, lrep_code3[0], volume * 100) samples.append( pyfluidsynth.raw_audio_string( np.array( fs.get_samples( int((sr * lrep_code3[1] * (60 / bpm)) / speed_multiplier))))) if lrep_code3[0] != -1: fs.noteoff(0, lrep_code3[0]) fs.delete() if sf2 == "": for index, lrep_code in enumerate(notes): for index1, lrep_code1 in enumerate(lrep_code): for index2, lrep_code2 in enumerate(lrep_code1): for index3, lrep_code3 in enumerate(lrep_code2): if lrep_code3[0] == -1: freq = 0 else: freq = 27.5 * (2**(lrep_code3[0] / 12))
fl = pyfluidsynth.Synth() # Initial silence is 1 second s = numpy.append(s, fl.get_samples(44100 * 1)) sfid = fl.sfload(os.path.join(this_dir, "example.sf2")) fl.program_select(0, sfid, 0, 0) fl.noteon(0, 60, 30) fl.noteon(0, 67, 30) fl.noteon(0, 76, 30) # Chord is held for 2 seconds s = numpy.append(s, fl.get_samples(44100 * 2)) fl.noteoff(0, 60) fl.noteoff(0, 67) fl.noteoff(0, 76) # Decay of chord is held for 1 second s = numpy.append(s, fl.get_samples(44100 * 1)) fl.delete() samps = pyfluidsynth.raw_audio_string(s) print(len(samps)) print('Starting playback') strm.write(samps)