Advertisement
EdmundC

backend

Oct 11th, 2024
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.26 KB | None | 0 0
  1. from flask import Flask, request, jsonify
  2. import mido  # MIDI processing
  3. from music21 import converter, instrument, note, stream  # Melody playback
  4. import os
  5. import wave
  6. import numpy as np
  7.  
  8. app = Flask(__name__)
  9.  
  10. @app.route('/submit', methods=['POST'])
  11. def submit():
  12.     data = request.json
  13.     title = data['title']
  14.     bpm = int(data['bpm'])
  15.     voice_path = data['voicePath']
  16.     melody = data['melody']
  17.     microtones = data['microtones']
  18.  
  19.     # Handle voice file playback (placeholder for actual voice processing)
  20.     if os.path.exists(voice_path):
  21.         play_voice(voice_path)
  22.  
  23.     # Parse melody
  24.     melody_notes = parse_melody(melody)
  25.     microtone_notes = parse_microtones(microtones)
  26.  
  27.     # Play the melody
  28.     play_melody(melody_notes, microtone_notes, bpm)
  29.  
  30.     return jsonify({"status": "success", "message": "Melody and microtones played"})
  31.  
  32. def parse_melody(melody_str):
  33.     """Parse the melody string into notes and durations."""
  34.     melody_list = melody_str.split()
  35.     notes_list = []
  36.     for i in range(0, len(melody_list), 2):
  37.         pitch = melody_list[i]
  38.         duration = melody_list[i+1]
  39.         n = note.Note(pitch)
  40.         n.quarterLength = parse_duration(duration)
  41.         notes_list.append(n)
  42.     return notes_list
  43.  
  44. def parse_microtones(microtones_str):
  45.     """Parse microtones into frequency and duration pairs."""
  46.     if not microtones_str:
  47.         return []
  48.     microtones_list = microtones_str.split()
  49.     return [(float(microtones_list[i][:-2]), parse_duration(microtones_list[i+1])) for i in range(0, len(microtones_list), 2)]
  50.  
  51. def parse_duration(duration_str):
  52.     """Convert string durations like '1/4' into float values."""
  53.     if '/' in duration_str:
  54.         num, denom = map(int, duration_str.split('/'))
  55.         return num / denom
  56.     return float(duration_str)
  57.  
  58. def play_melody(notes, microtones, bpm):
  59.     """Create a stream and play notes and microtones at the specified BPM."""
  60.     s = stream.Stream()
  61.     s.append(instrument.Piano())
  62.  
  63.     # Add regular notes
  64.     s.append(notes)
  65.  
  66.     # Add microtones as custom frequencies
  67.     for freq, duration in microtones:
  68.         sine_wave = generate_sine_wave(freq, duration * 60 / bpm)
  69.         play_wave(sine_wave)
  70.  
  71.     s.metronomeMarkBoundaries(0, bpm)
  72.     s.show('midi')  # Plays the melody as a MIDI file
  73.  
  74. def generate_sine_wave(freq, duration, sample_rate=44100):
  75.     """Generate a sine wave for a specific frequency and duration."""
  76.     t = np.linspace(0, duration, int(sample_rate * duration), False)
  77.     sine_wave = 0.5 * np.sin(2 * np.pi * freq * t)
  78.     return sine_wave
  79.  
  80. def play_wave(data, sample_rate=44100):
  81.     """Play a sine wave by writing to a WAV file and playing it."""
  82.     with wave.open('temp.wav', 'w') as wf:
  83.         wf.setnchannels(1)
  84.         wf.setsampwidth(2)
  85.         wf.setframerate(sample_rate)
  86.         wf.writeframes((data * 32767).astype(np.int16).tobytes())
  87.     os.system("aplay temp.wav")  # On Linux; for other platforms, adjust playback command
  88.  
  89. def play_voice(voice_path):
  90.     """Play a voice file using an external player or custom playback."""
  91.     os.system(f"aplay {voice_path}")  # Modify for other platforms (use a suitable library like Pygame for portability)
  92.  
  93. if __name__ == '__main__':
  94.     app.run(debug=True)
  95.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement