### Creating and Starting a Synth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Demonstrates how to create a Synth instance, start audio output, load a SoundFont, select an instrument, play notes, and clean up resources. ```APIDOC ## Creating and Starting a Synth ### Description The `Synth` class is the main interface for sound generation. Create a synthesizer instance with optional gain, sample rate, and channel configuration, then call `start()` to begin audio output in a background thread. ### Method `fluidsynth.Synth()` ### Endpoint N/A (Class instantiation) ### Parameters #### Constructor Parameters - **gain** (float) - Optional - The gain for the synthesizer. - **samplerate** (int) - Optional - The sample rate for the audio output. - **channels** (int) - Optional - The number of audio channels. #### Methods - **start(driver=None, midi_driver=None)**: Starts audio output in a background thread. Accepts optional driver and MIDI driver names. - **sfload(filename)**: Loads a SoundFont file and returns its ID. - **program_select(channel, sfid, bank, preset)**: Selects an instrument for a given MIDI channel. - **noteon(channel, note, velocity)**: Starts playing a note. - **noteoff(channel, note)**: Stops playing a note. - **delete()**: Cleans up synthesizer resources. ### Request Example ```python import time import fluidsynth # Create synth with custom settings fs = fluidsynth.Synth(gain=0.2, samplerate=44100, channels=256) # Start audio output (uses system default driver) fs.start() # Or specify a driver explicitly # fs.start(driver="pulseaudio") # fs.start(driver="alsa", midi_driver="alsa_seq") # fs.start(driver="coreaudio") # macOS # Load a SoundFont file and get its ID sfid = fs.sfload("GeneralUser_GS.sf2") # Select instrument: channel 0, soundfont sfid, bank 0, preset 0 (piano) fs.program_select(0, sfid, 0, 0) # Play a C major chord fs.noteon(0, 60, 100) # Middle C, velocity 100 fs.noteon(0, 64, 100) # E fs.noteon(0, 67, 100) # G time.sleep(2.0) # Stop notes fs.noteoff(0, 60) fs.noteoff(0, 64) fs.noteoff(0, 67) time.sleep(0.5) # Clean up resources fs.delete() ``` ### Response #### Success Response (N/A for instantiation and method calls, results are returned or side effects occur) #### Response Example N/A ``` -------------------------------- ### Initialize and Start Synth with pyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Demonstrates how to instantiate the Synth class, configure audio settings, start the synthesizer, and play a basic chord. It covers loading a SoundFont and cleaning up resources after playback. ```python import time import fluidsynth fs = fluidsynth.Synth(gain=0.2, samplerate=44100, channels=256) fs.start() sfid = fs.sfload("GeneralUser_GS.sf2") fs.program_select(0, sfid, 0, 0) fs.noteon(0, 60, 100) fs.noteon(0, 64, 100) fs.noteon(0, 67, 100) time.sleep(2.0) fs.noteoff(0, 60) fs.noteoff(0, 64) fs.noteoff(0, 67) time.sleep(0.5) fs.delete() ``` -------------------------------- ### Audio Generation and Playback with pyFluidSynth and PyAudio Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md This example shows how to manage audio I/O manually using FluidSynth to generate audio samples. It initializes FluidSynth without starting its internal audio thread, generates audio chunks using `get_samples()`, converts them to bytes using `fluidsynth.raw_audio_string()`, and plays them using PyAudio. NumPy is used for array manipulation. ```python import time import numpy import pyaudio import fluidsynth pa = pyaudio.PyAudio() strm = pa.open( format = pyaudio.paInt16, channels = 2, rate = 44100, output = True) s = [] fl = fluidsynth.Synth() # Initial silence is 1 second s = numpy.append(s, fl.get_samples(44100 * 1)) sfid = fl.sfload("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 = fluidsynth.raw_audio_string(s) print(len(samps)) print('Starting playback') strm.write(samps) ``` -------------------------------- ### Generate Audio Samples with get_samples Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This example demonstrates how to generate raw audio samples using `get_samples()` for custom audio pipelines or offline rendering. It shows how to create silence, play notes, capture audio, and convert it to bytes for playback using PyAudio. ```python import numpy import pyaudio import fluidsynth # Create synth without starting audio driver fs = fluidsynth.Synth() # Load SoundFont and select instrument sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Collect audio samples samples = numpy.array([], dtype=numpy.int16) # Generate 1 second of silence (44100 samples at 44100 Hz) samples = numpy.append(samples, fs.get_samples(44100)) # Play notes and capture audio fs.noteon(0, 60, 100) fs.noteon(0, 64, 100) fs.noteon(0, 67, 100) # Generate 2 seconds of chord audio samples = numpy.append(samples, fs.get_samples(44100 * 2)) # Release notes fs.noteoff(0, 60) fs.noteoff(0, 64) fs.noteoff(0, 67) # Generate 1 second of decay/release samples = numpy.append(samples, fs.get_samples(44100)) fs.delete() # Convert to raw bytes for playback audio_bytes = fluidsynth.raw_audio_string(samples) # Play through PyAudio pa = pyaudio.PyAudio() stream = pa.open(format=pyaudio.paInt16, channels=2, rate=44100, output=True) stream.write(audio_bytes) stream.close() pa.terminate() # Or save to file using scipy/wave # import scipy.io.wavfile # scipy.io.wavfile.write("output.wav", 44100, samples.reshape(-1, 2)) ``` -------------------------------- ### Sequencer Callbacks for Dynamic Scheduling Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This example shows how to register callback functions with the sequencer to be executed at specific times. It demonstrates dynamic music generation by scheduling repeating musical patterns and callbacks. ```python import time import fluidsynth # Global references seq = None synth_id = None pattern_start = 0 pattern_length = 2000 # 2 seconds per pattern def schedule_pattern(): """Schedule a repeating musical pattern.""" global pattern_start # Beat pattern (quarter notes) for beat in range(4): tick = pattern_start + beat * 500 seq.note(tick, 0, 60, 100, 200, dest=synth_id) # Melody over the beat melody = [(0, 72), (250, 74), (500, 76), (1000, 79), (1500, 77)] for offset, note in melody: seq.note(pattern_start + offset, 1, note, 90, 200, dest=synth_id) # Schedule callback for next pattern callback_time = pattern_start + pattern_length - 100 seq.timer(callback_time, dest=callback_id) pattern_start += pattern_length def seq_callback(time, event, sequencer, data): """Called by sequencer to trigger next pattern.""" schedule_pattern() # Setup fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) fs.program_select(1, sfid, 0, 0) seq = fluidsynth.Sequencer(time_scale=1000) synth_id = seq.register_fluidsynth(fs) callback_id = seq.register_client("pattern_callback", seq_callback) # Start the pattern pattern_start = seq.get_tick() schedule_pattern() # Let it play for 10 seconds time.sleep(10) seq.delete() fs.delete() ``` -------------------------------- ### Offline Audio Rendering with pyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This example demonstrates how to generate raw audio samples offline using pyFluidSynth without starting the real-time synthesizer. The `get_samples()` method is used to retrieve audio data, which can then be processed, mixed, or outputted through a custom audio system. ```python # Assuming fs is an initialized FluidSynth instance and a SoundFont is loaded # fs.program_select(0, soundfont_id, 0, 0) # Select instrument for channel 0 # Generate audio samples for a specific duration (e.g., 2 seconds) # The number of samples depends on the sample rate (default is 44100 Hz) # audio_data = fs.get_samples(duration_in_seconds=2.0) # Process or save audio_data here # print(f"Generated {len(audio_data)} audio samples.") ``` -------------------------------- ### Use Sequencer for Timed MIDI Events Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This example demonstrates using the `Sequencer` class to schedule MIDI events at precise times. It covers scheduling notes with absolute and relative timing, and registering the synth with the sequencer. ```python import time import fluidsynth # Create and start synth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Channel 0: melody fs.program_select(1, sfid, 0, 0) # Channel 1: bass # Create sequencer (default: 1000 ticks per second) seq = fluidsynth.Sequencer(time_scale=1000) # Register synth with sequencer synth_id = seq.register_fluidsynth(fs) # Get current time now = seq.get_tick() # Schedule notes using absolute timing # note(time, channel, key, velocity, duration, dest=synth_id) seq.note(now + 0, 0, 72, 100, 400, dest=synth_id) # C5 seq.note(now + 500, 0, 74, 100, 400, dest=synth_id) # D5 seq.note(now + 1000, 0, 76, 100, 400, dest=synth_id) # E5 seq.note(now + 1500, 0, 77, 100, 800, dest=synth_id) # F5 (longer) # Schedule bass notes seq.note(now + 0, 1, 48, 80, 1500, dest=synth_id) # C3 seq.note(now + 2000, 1, 53, 80, 1500, dest=synth_id) # F3 # Or use relative timing (absolute=False) seq.note_on(500, 0, 79, velocity=100, dest=synth_id, absolute=False) seq.note_off(900, 0, 79, dest=synth_id, absolute=False) # Wait for playback time.sleep(5.0) seq.delete() fs.delete() ``` -------------------------------- ### Implement Custom Tuning Systems in PyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Details how to define and activate custom tuning systems for microtonal music or historical temperaments using `activate_key_tuning()`. The example shows how to create a tuning array using `ctypes.c_double` and set it for a specific key. This allows for precise control over pitch relationships beyond equal temperament. ```python import time import fluidsynth from ctypes import c_double fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Create a custom tuning (values in cents, 100 cents = 1 semitone) # This example creates a just intonation major scale starting at C tuning = (c_double * 128)() # Standard equal temperament as base (all zeros) for i in range(128): tuning[i] = 0.0 # Example: Just intonation major scale tuning (cents deviation from equal temperament) # Root (C), Major Third (E), Perfect Fifth (G) tuning[0] = 0.0 # C tuning[4] = -14.0 # E (Just Major Third is 386 cents, Equal is 400) tuning[7] = 2.0 # G (Just Perfect Fifth is 702 cents, Equal is 700) # Activate the custom tuning for key C (MIDI note 0) fs.activate_key_tuning(0, tuning) # Play notes to hear the custom tuning fs.noteon(0, 60, 100) # C4 fs.noteon(0, 64, 100) # E4 fs.noteon(0, 67, 100) # G4 time.sleep(3.0) fs.noteoff(0, 60) fs.noteoff(0, 64) fs.noteoff(0, 67) fs.delete() ``` -------------------------------- ### Apply MIDI Effects and Control Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This snippet shows how to apply vibrato and pitch bend to notes, and how to get the current control value for volume. It uses the fluidsynth library to interact with MIDI events. ```python import time import fluidsynth # Initialize fluidsynth fs = fluidsynth.Synth() fs.start() # Start the audio driver sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Apply vibrato for i in range(20): fs.cc(0, 1, i * 6) # Gradually increase modulation time.sleep(0.05) # Gradually decrease modulation # Apply pitch bend (-8192 to +8191, 0 = no bend) # 2048 = one semitone up, -2048 = one semitone down fs.noteon(0, 60, 80) for i in range(10): fs.pitch_bend(0, i * 512) # Bend up gradually time.sleep(0.1) fs.noteoff(0, 60) # Get current control value volume = fs.get_cc(0, 7) print(f"Current volume: {volume}") fs.delete() ``` -------------------------------- ### Manage SoundFonts and Program Selection Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Shows how to load SoundFont files, assign specific instruments to MIDI channels using presets, and retrieve channel information. It also demonstrates how to unload SoundFonts to free memory. ```python import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("FluidR3_GM.sf2") fs.program_select(0, sfid, 0, 0) fs.program_select(1, sfid, 0, 40) fs.program_select(2, sfid, 0, 73) fs.program_select(9, sfid, 128, 0) sfont_id, bank, program, name = fs.channel_info(0) print(f"Channel 0: {name.decode()} (bank {bank}, preset {program})") preset_name = fs.sfpreset_name(sfid, 0, 40) print(f"Bank 0, Preset 40: {preset_name}") fs.sfunload(sfid) fs.delete() ``` -------------------------------- ### Play MIDI Files with PyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Demonstrates how to play standard MIDI files using the `play_midi_file()` function. It covers loading SoundFonts, selecting instruments, controlling playback status, and adjusting tempo. Ensure a SoundFont file (e.g., 'GeneralUser_GS.sf2') is available in the same directory or provide a full path. ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() # Load a General MIDI SoundFont for best compatibility sfid = fs.sfload("GeneralUser_GS.sf2") # Select instruments for all 16 MIDI channels for channel in range(16): fs.program_select(channel, sfid, 0, 0) # Play MIDI file fs.play_midi_file("song.mid") # Check player status # FLUID_PLAYER_READY = 0 # FLUID_PLAYER_PLAYING = 1 # FLUID_PLAYER_STOPPING = 2 # FLUID_PLAYER_DONE = 3 while fluidsynth.fluid_player_get_status(fs.player) == fluidsynth.FLUID_PLAYER_PLAYING: time.sleep(0.1) # Optionally adjust tempo during playback # FLUID_PLAYER_TEMPO_EXTERNAL_BPM = 1 # fs.player_set_tempo(fluidsynth.FLUID_PLAYER_TEMPO_EXTERNAL_BPM, 120.0) # Stop playback early if needed # fs.play_midi_stop() print("Playback finished") fs.delete() ``` -------------------------------- ### Loading SoundFonts and Selecting Programs Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Details on how to load SoundFont files and select specific instruments (programs) for different MIDI channels. ```APIDOC ## Loading SoundFonts and Selecting Programs ### Description SoundFonts contain instrument definitions organized by bank and preset numbers. Use `sfload()` to load a SoundFont file and `program_select()` to choose an instrument for a MIDI channel. ### Method `sfload(filename)` `program_select(channel, soundfont_id, bank, preset)` `channel_info(channel)` `sfpreset_name(soundfont_id, bank, preset)` `sfunload(soundfont_id)` ### Endpoint N/A (Class methods) ### Parameters #### `sfload(filename)` - **filename** (str) - Required - Path to the SoundFont file (.sf2). #### `program_select(channel, soundfont_id, bank, preset)` - **channel** (int) - Required - The MIDI channel (0-15). - **soundfont_id** (int) - Required - The ID returned by `sfload()`. - **bank** (int) - Required - The SoundFont bank number. - **preset** (int) - Required - The SoundFont preset number. #### `channel_info(channel)` - **channel** (int) - Required - The MIDI channel to query. #### `sfpreset_name(soundfont_id, bank, preset)` - **soundfont_id** (int) - Required - The ID of the loaded SoundFont. - **bank** (int) - Required - The bank number. - **preset** (int) - Required - The preset number. #### `sfunload(soundfont_id)` - **soundfont_id** (int) - Required - The ID of the SoundFont to unload. ### Request Example ```python import fluidsynth fs = fluidsynth.Synth() fs.start() # Load SoundFont and get its ID sfid = fs.sfload("FluidR3_GM.sf2") # Select different instruments on different channels # program_select(channel, soundfont_id, bank, preset) fs.program_select(0, sfid, 0, 0) # Channel 0: Piano (bank 0, preset 0) fs.program_select(1, sfid, 0, 40) # Channel 1: Violin (bank 0, preset 40) fs.program_select(2, sfid, 0, 73) # Channel 2: Flute (bank 0, preset 73) fs.program_select(9, sfid, 128, 0) # Channel 9: Standard drum kit (bank 128) # Get channel info sfont_id, bank, program, name = fs.channel_info(0) print(f"Channel 0: {name.decode()} (bank {bank}, preset {program})") # Get preset name directly preset_name = fs.sfpreset_name(sfid, 0, 40) print(f"Bank 0, Preset 40: {preset_name}") # Unload SoundFont when done fs.sfunload(sfid) fs.delete() ``` ### Response #### Success Response (200) - **channel_info()**: Returns a tuple `(soundfont_id, bank, program, name)` where `name` is a byte string. - **sfpreset_name()**: Returns a string representing the preset name. #### Response Example ``` Channel 0: Acoustic Grand Piano (bank 0, preset 0) Bank 0, Preset 40: Violin ``` ``` -------------------------------- ### Basic Note Playback with pyFluidSynth Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md This snippet demonstrates how to initialize FluidSynth, load a SoundFont, select an instrument, play a chord with noteon events, and stop the notes with noteoff events. It utilizes the `fluidsynth.Synth` class for playback and `time.sleep` for duration control. ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) fs.noteon(0, 60, 30) fs.noteon(0, 67, 30) fs.noteon(0, 76, 30) time.sleep(1.0) fs.noteoff(0, 60) fs.noteoff(0, 67) fs.noteoff(0, 76) time.sleep(1.0) fs.delete() ``` -------------------------------- ### Playing Notes with noteon and noteoff Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Explains how to trigger individual notes and chords using `noteon()` and `noteoff()`, including methods to stop all notes. ```APIDOC ## Playing Notes with noteon and noteoff ### Description The `noteon()` method starts a note on a channel with a given MIDI key (0-127) and velocity (0-127). The `noteoff()` method stops the note. Multiple notes can play simultaneously for chords and polyphonic music. ### Method `noteon(channel, note, velocity)` `noteoff(channel, note)` `all_notes_off(channel)` `all_sounds_off(channel)` ### Endpoint N/A (Class methods) ### Parameters #### `noteon(channel, note, velocity)` - **channel** (int) - Required - The MIDI channel (0-15). - **note** (int) - Required - The MIDI note number (0-127). - **velocity** (int) - Required - The note velocity (0-127). #### `noteoff(channel, note)` - **channel** (int) - Required - The MIDI channel (0-15). - **note** (int) - Required - The MIDI note number (0-127) to stop. #### `all_notes_off(channel)` - **channel** (int) - Required - The MIDI channel (0-15) to stop all notes on. #### `all_sounds_off(channel)` - **channel** (int) - Required - The MIDI channel (0-15) to immediately silence. ### Request Example ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Play an ascending scale with varying velocities scale = [60, 62, 64, 65, 67, 69, 71, 72] # C major scale for i, note in enumerate(scale): velocity = 60 + i * 8 # Increasing velocity fs.noteon(0, note, velocity) time.sleep(0.3) fs.noteoff(0, note) # Play a chord (multiple simultaneous notes) chord = [60, 64, 67, 72] # C major with octave for note in chord: fs.noteon(0, note, 80) time.sleep(1.5) # Release all notes at once for note in chord: fs.noteoff(0, note) # Or use all_notes_off to release all notes on a channel fs.all_notes_off(0) # Or all_sounds_off to immediately silence (like mute) fs.all_sounds_off(0) fs.delete() ``` ### Response #### Success Response (N/A - methods trigger audio events) #### Response Example N/A ``` -------------------------------- ### Manage Synth Settings with PyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Explains how to configure FluidSynth's global settings using `setting()` and retrieve them with `get_setting()`. This includes audio driver parameters, synthesis options like polyphony and gain, and enabling effects. Settings can be applied during Synth initialization or afterward. ```python import fluidsynth # Create synth with custom keyword arguments fs = fluidsynth.Synth( gain=0.5, samplerate=48000, channels=256, ) # Set additional settings programmatically fs.setting('synth.polyphony', 256) # Max simultaneous voices fs.setting('synth.reverb.active', 1) # Enable reverb fs.setting('synth.chorus.active', 1) # Enable chorus fs.setting('audio.driver', 'pulseaudio') # Audio driver fs.setting('audio.periods', 2) # Audio buffer periods fs.setting('audio.period-size', 64) # Samples per period # Get current settings sample_rate = fs.get_setting('synth.sample-rate') polyphony = fs.get_setting('synth.polyphony') gain = fs.get_setting('synth.gain') driver = fs.get_setting('audio.driver') print(f"Sample rate: {sample_rate}") print(f"Polyphony: {polyphony}") print(f"Gain: {gain}") print(f"Audio driver: {driver}") # Start after configuration fs.start() # ... use synth ... fs.delete() ``` -------------------------------- ### Real-time MIDI Playback with pyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This snippet illustrates basic real-time MIDI note playback using pyFluidSynth. It shows how to turn notes on and off on a specified channel with a given velocity, and includes a delay for playback duration. This is fundamental for interactive music applications. ```python # Assuming fs is an initialized FluidSynth instance # fs.start() # Play a note fs.noteon(0, 60, 100) # Channel 0, Note 60 (Middle C), Velocity 100 # Hold the note for 2 seconds time.sleep(2.0) # Turn the note off fs.noteoff(0, 60) # Channel 0, Note 60 # fs.stop() ``` -------------------------------- ### Configure Reverb and Chorus Effects in PyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Illustrates how to apply and configure built-in reverb and chorus audio effects using setter methods like `set_reverb()` and `set_chorus()`. It also shows how to retrieve current settings using `get_reverb_*()` and `get_chorus_*()` methods. A SoundFont file (e.g., 'example.sf2') is needed. ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Configure reverb # roomsize: 0.0-1.0 (room size) # damping: 0.0-1.0 (high frequency damping) # width: 0.0-100.0 (stereo width) # level: 0.0-1.0 (wet signal level) fs.set_reverb(roomsize=0.8, damping=0.3, width=50.0, level=0.7) # Or set individual parameters fs.set_reverb_roomsize(0.9) fs.set_reverb_damp(0.4) fs.set_reverb_level(0.6) fs.set_reverb_width(80.0) # Get current reverb settings print(f"Reverb roomsize: {fs.get_reverb_roomsize()}") print(f"Reverb damping: {fs.get_reverb_damp()}") print(f"Reverb level: {fs.get_reverb_level()}") print(f"Reverb width: {fs.get_reverb_width()}") # Configure chorus # nr: 0-99 (voice count, affects CPU usage) # level: 0.0-10.0 (effect level) # speed: 0.29-5.0 Hz (modulation rate) # depth: 0.0-21.0 ms (modulation depth) # type: 0=sine, 1=triangle (waveform) fs.set_chorus(nr=3, level=2.0, speed=0.5, depth=8.0, type=0) # Individual chorus parameters fs.set_chorus_nr(5) fs.set_chorus_level(3.0) fs.set_chorus_speed(0.8) fs.set_chorus_depth(10.0) fs.set_chorus_type(1) # Triangle wave # Play a note to hear the effects fs.noteon(0, 60, 100) time.sleep(3.0) fs.noteoff(0, 60) time.sleep(1.0) fs.delete() ``` -------------------------------- ### Play Musical Notes and Chords Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Explains how to trigger notes using noteon and noteoff events, including playing scales and chords. It also covers methods for stopping all sounds on a channel. ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) scale = [60, 62, 64, 65, 67, 69, 71, 72] for i, note in enumerate(scale): velocity = 60 + i * 8 fs.noteon(0, note, velocity) time.sleep(0.3) fs.noteoff(0, note) chord = [60, 64, 67, 72] for note in chord: fs.noteon(0, note, 80) time.sleep(1.5) for note in chord: fs.noteoff(0, note) fs.all_notes_off(0) fs.all_sounds_off(0) fs.delete() ``` -------------------------------- ### Initialize PyFluidSynth Sequencer Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md Demonstrates how to create a new Sequencer instance. The default time scale is 1000 ticks per second. You can customize the time scale and choose between system timer or manual processing. ```python import fluidsynth seq = fluidsynth.Sequencer() ``` -------------------------------- ### Apply MIDI Control Changes Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Demonstrates the use of the cc method to modify synthesizer parameters such as volume, panning, reverb, and chorus. These controls allow for dynamic sound shaping during playback. ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) fs.cc(0, 7, 100) fs.cc(0, 10, 64) fs.cc(0, 91, 50) fs.cc(0, 93, 30) fs.noteon(0, 60, 80) ``` -------------------------------- ### Convert MIDI to WAV Audio with PyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Shows how to use the `midi2audio()` method to render MIDI files into WAV audio files without real-time playback. This is suitable for batch processing and offline rendering. It requires a SoundFont file (e.g., 'FluidR3_GM.sf2') to be accessible. ```python import fluidsynth # Create synth (no need to start audio driver for file rendering) fs = fluidsynth.Synth() # Load SoundFont sfid = fs.sfload("FluidR3_GM.sf2") # Convert MIDI to WAV fs.midi2audio("input.mid", "output.wav") # Process multiple files with the same synth files = ["song1.mid", "song2.mid", "song3.mid"] for midi_file in files: output_file = midi_file.replace(".mid", ".wav") fs.midi2audio(midi_file, output_file) print(f"Converted {midi_file} to {output_file}") fs.delete() ``` -------------------------------- ### Register and Schedule a Sequencer Callback Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md Demonstrates registering a custom Python callback function to be executed at a specific time. The callback receives time, event, sequencer, and data arguments. The timer function schedules when the callback should be invoked. ```python def seq_callback(time, event, seq, data): print('callback called!') callback_id = sequencer.register_client("myCallback", seq_callback) sequencer.timer(current_time + 2000, dest=callback_id) ``` -------------------------------- ### Register Fluidsynth Synthesizer with Sequencer Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md Shows how to register a FluidSynth synthesizer instance with the sequencer. The returned synth_id is crucial for directing MIDI events to the correct synthesizer. ```python fs = fluidsynth.Synth() # init and start the synthesizer as described above… synth_id = seq.register_fluidsynth(fs) ``` -------------------------------- ### Apply Just Intonation Tuning in pyFluidSynth Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt This snippet demonstrates how to apply just intonation tuning to FluidSynth. It calculates the tuning offsets, activates the tuning for a specific bank and program, and then plays a chord using this tuning. Finally, it deactivates the tuning to revert to equal temperament. ```python import fluidsynth as fs import time # Initialize FluidSynth (assuming fs.synth is already initialized) # fs.synth = fs.fluid_synth_new(soundfont='your_soundfont.sf2') # Just intonation ratios and their deviation from Equal Temperament in cents just_cents = [0, 4, -14, -2, 2, -16, -12, 0] # Deviation from ET in cents tuning = [0] * 128 # Calculate tuning offsets for 11 octaves for octave in range(11): base = octave * 12 for i, cent_offset in enumerate(just_cents): if base + i < 128: tuning[base + i] = cent_offset # Activate tuning on bank 0, program 0 with a custom name fluidsynth.fluid_synth_activate_key_tuning( fs.synth, 0, 0, b"Just Intonation", tuning, True ) # Apply tuning to channel 0 fluidsynth.fluid_synth_activate_tuning(fs.synth, 0, 0, 0, True) # Play a just-intoned major chord fs.noteon(0, 60, 100) # C fs.noteon(0, 64, 100) # E (just third) fs.noteon(0, 67, 100) # G (just fifth) time.sleep(2.0) fs.noteoff(0, 60) fs.noteoff(0, 64) fs.noteoff(0, 67) # Deactivate tuning to return to equal temperament fluidsynth.fluid_synth_deactivate_tuning(fs.synth, 0, True) # Clean up FluidSynth instance (assuming fs.delete() is the correct cleanup method) # fs.delete() ``` -------------------------------- ### Schedule MIDI Note On Event (Relative Timing) Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md Schedules a 'note on' event using relative timing. The event will occur after the specified time offset from the current sequencer position. Requires a registered synthesizer ID. ```python seq.note_on(time=500, absolute=False, channel=0, key=60, velocity=80, dest=synth_id) ``` -------------------------------- ### Control Changes and Pitch Bend Source: https://context7.com/nwhitehead/pyfluidsynth/llms.txt Covers sending MIDI control change messages for parameters like volume, pan, and effects, as well as pitch bending. ```APIDOC ## Control Changes and Pitch Bend ### Description Use `cc()` to send MIDI control change messages for effects like volume, pan, vibrato, sustain, reverb, and chorus. Use `pitch_bend()` to smoothly bend the pitch of playing notes. ### Method `cc(channel, controller, value)` `pitch_bend(channel, value)` ### Endpoint N/A (Class methods) ### Parameters #### `cc(channel, controller, value)` - **channel** (int) - Required - The MIDI channel (0-15). - **controller** (int) - Required - The control change number (e.g., 7 for volume, 10 for pan, 64 for sustain). - **value** (int) - Required - The value for the control change (typically 0-127). #### `pitch_bend(channel, value)` - **channel** (int) - Required - The MIDI channel (0-15). - **value** (int) - Required - The pitch bend value. Typically -8192 (down) to +8191 (up), with 0 being the center. ### Request Example ```python import time import fluidsynth fs = fluidsynth.Synth() fs.start() sfid = fs.sfload("example.sf2") fs.program_select(0, sfid, 0, 0) # Common control change values: # CC 1: Modulation (vibrato) # CC 7: Volume (0-127) # CC 10: Pan (0=left, 64=center, 127=right) # CC 11: Expression # CC 64: Sustain pedal (0=off, 127=on) # CC 91: Reverb send # CC 93: Chorus send # Set initial controls fs.cc(0, 7, 100) # Volume at ~80% fs.cc(0, 10, 64) # Center pan fs.cc(0, 91, 50) # Some reverb fs.cc(0, 93, 30) # Light chorus # Play a note fs.noteon(0, 60, 80) # Example of pitch bend (bend up) fs.pitch_bend(0, 4096) # Bend up by one octave time.sleep(1.0) fs.pitch_bend(0, 0) # Return to center # Example of sustain pedal fs.cc(0, 64, 127) # Sustain on fs.noteon(0, 60, 80) time.sleep(1.0) fs.cc(0, 64, 0) # Sustain off fs.noteoff(0, 60) fs.delete() ``` ### Response #### Success Response (N/A - methods trigger audio events) #### Response Example N/A ``` -------------------------------- ### Schedule MIDI Note On Event (Absolute Timing) Source: https://github.com/nwhitehead/pyfluidsynth/blob/master/README.md Schedules a 'note on' event using absolute timing. The event will occur at the specified tick position. This requires knowing the current tick of the sequencer. ```python current_time = seq.get_tick() seq.note_on(current_time + 500, 0, 60, 80, dest=synth_id) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.