sintetizador_fm_para_archivos_midi_en_python

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
sintetizador_fm_para_archivos_midi_en_python [2025/01/12 20:40] – created ososintetizador_fm_para_archivos_midi_en_python [2025/01/13 21:25] (current) – [Overview] oso
Line 1: Line 1:
-poly synth+====== Creating an FM Synthesizer in Python ======
  
-<code python>+ 
 +===== Objective: ===== 
 + 
 +This project implements an FM (Frequency Modulation) Synthesizer in Python. The synthesizer processes MIDI files and generates audio in real-time, focusing on emulating polyphonic instruments. The project also aims to explore FM synthesis techniques and create custom audio effects for MIDI playback. 
 + 
 +===== App ===== 
 + 
 + 
 +<code python:fm_synthesizer.py>
 import mido import mido
 import numpy as np import numpy as np
Line 163: Line 171:
     # Example: Play only piano (Program 1) and electric piano (Program 5), [1, 5]     # Example: Play only piano (Program 1) and electric piano (Program 5), [1, 5]
     #play_midi_file("C:/Users/unapa/Downloads/DXdiag.mid", selected_instruments=[33, 78, 16, 18, 53, 27, 29, 30])     #play_midi_file("C:/Users/unapa/Downloads/DXdiag.mid", selected_instruments=[33, 78, 16, 18, 53, 27, 29, 30])
 +
 </code> </code>
 +
 +===== Script Overview =====
 +
 +
 +  * **Filename:** `fm_synthesizer.py`
 +  * **Dependencies:** `mido`, `numpy`, `sounddevice`, `time`
 +  * **Features:**
 +  - **FM Synth Engine:** Generates FM-based audio for MIDI notes.
 +  - **Polyphony:** Supports multiple simultaneous notes with a configurable maximum polyphony limit.
 +  - **MIDI Playback:** Reads and processes MIDI files to generate real-time audio.
 +  - **Instrument Selection:** Allows filtering specific instruments for playback.
 +
 +===== Script Execution =====
 +
 +
 +==== FM Synthesis Engine: ====
 +
 +  * **Carrier and Modulator Frequencies:** Derived from the MIDI note number.
 +  * **Modulation Index:** Affects the timbre by varying modulation depth.
 +  * **Envelope:** Simple attack-release envelope applied to smooth transitions.
 +
 +==== Polyphonic Note Handling: ====
 +
 +  * **Dynamic Management:** Tracks active notes, ensuring the maximum polyphony limit isn’t exceeded.
 +  * **Automatic Note Cleanup:** Frees resources of finished notes to manage performance.
 +
 +==== Real-Time Audio Playback ====
 +
 +  * **Callback Architecture:** Processes audio blocks in real-time using `sounddevice`.
 +  * **Audio Limiting:** Avoids clipping by gently limiting the output amplitude.
 +
 +==== MIDI Parsing: ====
 +
 +  * Processes MIDI messages (e.g., `note_on`, `note_off`, `program_change`).
 +  * Provides the option to select specific instruments via their MIDI program numbers.
 +
 +==== Command-Line Execution: ====
 +
 +  * Modify the script to accept a MIDI file as a parameter for better flexibility.
 +  * Example:
 +<code>python fm_synthesizer.py example.mid</code>
 +
 +
 +==== Error Handling: ====
 +
 +     * Detects and reports errors during audio generation, MIDI parsing, or playback.
 +
 +===== Usage Example =====
 +
 +To play a MIDI file (e.g. `canyon.mid`), run the script as shown below. You can optionally specify a list of instruments to filter:
 +
 +<code>play_midi_file("C:/temp/canyon.mid", selected_instruments=[1, 5])</code>
 +
 +- **Without Filtering:**  
 +   All instruments in the MIDI file will be played.
 +   
 +- **Filtered Playback:**  
 +   Example: Play only pianos (Program 1) and electric pianos (Program 5).
 +
 +===== Limitations =====
 +
 +1. **Simplistic Envelope:**  
 +   The attack-release envelope could be extended with sustain and decay stages for greater realism.
 +   
 +2. **Basic Modulation:**  
 +   The FM synthesis implementation uses a fixed modulation scheme. Extending it with dynamic modulation indexes or additional oscillators could improve the tonal range.
 +
 +3. **No Visualization:**  
 +   Currently, the synthesizer does not include any graphical or waveform visualizations.
 +
 +4. **Input Handling:**  
 +   The script does not yet parse command-line arguments for file paths or instrument filters.
 +
 +===== Final Note =====
 +
 +
 +This FM synthesizer provides a starting point for experimenting with audio synthesis and real-time MIDI playback in Python. Its modular design makes it easy to extend with additional features, such as better envelopes, more advanced synthesis techniques, or visualization tools.
 +
 +
 +====== Appendix: Monophonic Synthesizer ======  
 +
 +This section covers a **simple mono synthesizer** that processes a single piano track from a MIDI file, synthesizing FM-based audio for each note and playing it in real time.  
 +
 +<code python>  
 +import mido  # For MIDI parsing
 +import numpy as np  # For waveform synthesis
 +import sounddevice as sd  # For real-time audio playback
 +
 +def read_midi(file_path):
 +    midi = mido.MidiFile(file_path)
 +    return midi
 +
 +def fm_synth(note, velocity, duration, sample_rate=44100):
 +    # Example parameters for FM synthesis
 +    carrier_freq = 440 * 2**((note - 69) / 12)  # MIDI note to frequency
 +    modulator_freq = carrier_freq * 2 + carrier_freq * 4 + carrier_freq * 6 + carrier_freq * 8
 +    modulation_index = 0.33
 +    
 +    t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
 +    modulator = np.sin(2 * np.pi * modulator_freq * t) * modulation_index
 +    carrier = np.sin(2 * np.pi * carrier_freq * t + modulator)
 +    
 +    return carrier * velocity / 127
 +
 +def process_piano_track(midi):
 +    sample_rate = 44100
 +    for track in midi.tracks:
 +        for msg in track:
 +            if msg.type == 'note_on' and msg.velocity > 0:  # Note on
 +                duration = msg.time / midi.ticks_per_beat  # Estimate duration from MIDI timing
 +                note_audio = fm_synth(msg.note, msg.velocity, duration, sample_rate)
 +                
 +                # Play the synthesized audio for the note
 +                sd.play(note_audio, samplerate=sample_rate)
 +                sd.wait()  # Wait until the audio is finished playing
 +
 +midi = read_midi("C:/temp/canyon.mid")
 +process_piano_track(midi)
 +</code>  
 +
 +===== Overview =====  
 +
 +  * **Purpose:** To demonstrate a basic FM synthesis-based mono synthesizer that processes MIDI piano tracks. Each note is synthesized and played one at a time.  
 +  * **Limitations:**  
 +    - **Mono Only:** The synthesizer processes and plays a single note at a time. Overlapping notes or chords are not supported.  
 +    - **No Envelope Control:** The FM synthesis does not include dynamic ADSR envelopes, which might result in abrupt starts/stops.  
 +    - **Simplistic Waveform Modulation:** Only sine waves are used as the carrier and modulator.  
 +
 +===== Customizing the Modulation Signal =====  
 +
 +To achieve different sound characteristics, you can modify the `fm_synth` function to generate various modulation waveforms. Here are examples:  
 +
 +**1. Triangle Wave Modulation:**  
 +<code python>  
 +modulator = 2 * np.arcsin(np.sin(2 * np.pi * modulator_freq * t)) / np.pi * modulation_index  
 +</code>  
 +
 +**2. Sawtooth Wave Modulation:**  
 +<code python>  
 +modulator = 2 * (t * modulator_freq - np.floor(t * modulator_freq + 0.5)) * modulation_index  
 +</code>  
 +
 +**3. Square Wave Modulation:**  
 +<code python>  
 +modulator = np.sign(np.sin(2 * np.pi * modulator_freq * t)) * modulation_index  
 +</code>  
 +
 +Each of these alternatives changes the timbre of the output, providing greater flexibility for sound design.  
 +
 +===== Final Notes =====  
 +
 +  * **Expected Behavior:** This script processes the MIDI file track by track, playing each note sequentially. It is best suited for simple piano tracks with minimal overlap between notes.  
 +  * **Recommendations:**
 +    - Use this script for experimentation or as a starting point for more advanced synthesizer projects.  
 +    - To handle polyphony or add envelopes, consider integrating this code with the main FM synthesizer described earlier.  
 +
 +By customizing the modulation signal and adjusting parameters like `modulation_index`, `carrier_freq`, and `modulator_freq`, you can experiment with creating unique sound textures and effects.  
 +
sintetizador_fm_para_archivos_midi_en_python.1736714404.txt.gz · Last modified: 2025/01/12 20:40 by oso