Advertisement
Jann24

audio_signal_sythesis_template.py

Dec 3rd, 2024
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.71 KB | None | 0 0
  1. import numpy as np
  2. from scipy.io import wavfile
  3. import matplotlib.pyplot as plt
  4.  
  5. sampling_rate = 44100
  6.  
  7. def generate_sine_wave(frequency, duration, amplitude):
  8.   """
  9.  Generates a simple audio signal with a sine wave form.
  10.  
  11.  Arguments:
  12.    frequency: The frequency of the signal in Hz.
  13.    duration: The duration of the signal in seconds.
  14.    amplitude: The amplitude of the signal.
  15.  
  16.  Returns:
  17.    A simple audio signal with a sine wave form.
  18.  """
  19.  
  20.   # Calculate number of samples
  21.   num_samples = int(sampling_rate * duration)
  22.  
  23.   # Generate a time scale.
  24.   time = np.linspace(0, duration, num_samples)
  25.  
  26.   # Form the audio signal (eq. 1).
  27.   audio_signal = amplitude * np.sin(2*np.pi*frequency*time)
  28.   return audio_signal
  29.  
  30. def generate_rectangular_wave(frequency, duration, amplitude):
  31.   """
  32.  Generates a simple audio signal with a rectangular wave form.
  33.  
  34.  Arguments:
  35.    frequency: The frequency of the signal in Hz.
  36.    duration: The duration of the signal in seconds.
  37.    amplitude: The amplitude of the signal.
  38.  
  39.  Returns:
  40.    A simple audio signal with a rectangular wave form.
  41.  """
  42.  
  43.   # Calculate number of samples
  44.   num_samples = int(sampling_rate*duration)
  45.  
  46.   # Generate a time scale.
  47.   time = np.linspace(0, duration, num_samples)
  48.  
  49.   # Form the audio signal (eq. 2).
  50.   audio_signal = amplitude * np.sign(np.sin(2*np.pi*frequency*time))
  51.  
  52.   return audio_signal
  53.  
  54. def generate_asymetric_triangular_wave(frequency, duration, amplitude):
  55.   """
  56.  Generates a simple audio signal with an asymetric triangular wave form.
  57.  
  58.  Arguments:
  59.    frequency: The frequency of the signal in Hz.
  60.    duration: The duration of the signal in seconds.
  61.    amplitude: The amplitude of the signal.
  62.  
  63.  Returns:
  64.    A simple audio signal with an asymetric triangular wave form.
  65.  """
  66.  
  67.   # Calculate number of samples
  68.   num_samples = int(sampling_rate*duration)
  69.  
  70.   # Generate a time scale.
  71.   time = np.linspace(0, duration, num_samples)
  72.  
  73.   # Calculate the period
  74.   period = 1 / frequency
  75.   rise_fraction = 0.6
  76.  
  77.   audio_signal = np.zeros_like(time)
  78.   for i, t in enumerate(time):
  79.     # Time within the current period
  80.     mod_t = t % period
  81.  
  82.     if mod_t < rise_fraction * period:  # Rising phase
  83.         audio_signal[i] = (mod_t / (rise_fraction * period)) * amplitude
  84.     else:  # Falling phase
  85.         audio_signal[i] = amplitude - ((mod_t - rise_fraction * period) / ((1 - rise_fraction) * period)) * 2 * amplitude
  86.  
  87.   # Form the audio signal (eq. 3).
  88.  
  89.  
  90.   return audio_signal
  91.  
  92. def generate_symetric_triangular_wave(frequency, duration, amplitude):
  93.   """
  94.  Generates a simple audio signal with a symetric triangular wave form.
  95.  
  96.  Arguments:
  97.    frequency: The frequency of the signal in Hz.
  98.    duration: The duration of the signal in seconds.
  99.    amplitude: The amplitude of the signal.
  100.  
  101.  Returns:
  102.    A simple audio signal with a symetric triangular wave form.
  103.  """
  104.   # Calculate number of samples
  105.   num_samples = int(sampling_rate*duration)
  106.  
  107.   # Generate a time scale.
  108.   time = np.linspace(0, duration, num_samples)
  109.  
  110.   # Calculate the period
  111.   period = 1/frequency
  112.  
  113.   # Form the audio signal (eq. 4).
  114.   mod_time = (time % period) / period  # Normalize to [0, 1] within each period
  115.   audio_signal = amplitude * (1 - 4 * np.abs(mod_time - 0.5))  # Symmetric triangle formula
  116.  
  117.   return audio_signal
  118.  
  119. def visualize_signal(audio_signal, duration, title="Audio signal"):
  120.   """
  121.  Visualizes an audio signal.
  122.  
  123.  Arguments:
  124.    audio_signal: The audio signal to visualize.
  125.    duration: The duration of the signal in seconds.
  126.    
  127.  Returns:
  128.    None: This function displays the plot but does not return any values.
  129.  """
  130.  
  131.   # Plot the audio signal.
  132.   num_samples = len(audio_signal)
  133.   time_axis = np.linspace(0, duration, num_samples, endpoint=False)
  134.   plt.figure(figsize=(10, 4))
  135.   plt.plot(time_axis, audio_signal, color='blue', label='Audio Signal')
  136.   # Add labels to the axes.
  137.   plt.xlabel('Time (s)')
  138.   plt.ylabel('Amplitude')
  139.   # Add title
  140.   plt.title('Audio Signal Visualization')
  141.  
  142.   # Show the plot.
  143.   plt.grid(True)
  144.   plt.legend()
  145.  
  146.  
  147. def plot_positive_spectrum(signal, title = "Signal Spectrum (Positive Frequencies Only)"):
  148.   """
  149.  Plot the amplitude spectrum of a signal, showing only positive frequencies.
  150.  
  151.  Arguments:
  152.    signal (array-like): The input signal for which to calculate the spectrum.
  153.    title (str, optional): The title for the plot (default is "Signal Spectrum (Positive Frequencies Only)").
  154.  
  155.  Returns:
  156.    None: This function displays the plot but does not return any values.
  157.  """
  158.  
  159.   # Perform FFT on the signal
  160.   signal_fft = np.fft.fft(signal)
  161.  
  162.   # Calculate the frequencies associated with the FFT result
  163.   frequencies = np.fft.fftfreq(len(signal), 1 / sampling_rate)
  164.  
  165.   # Select only positive frequencies
  166.   positive_frequencies = frequencies[:len(frequencies)//2]
  167.   positive_signal_fft = 2.0 / len(signal) * np.abs(signal_fft[:len(signal)//2])
  168.  
  169.   # Plot the amplitude spectrum for positive frequencies
  170.   plt.figure(figsize=(10, 6))
  171.   plt.plot(positive_frequencies, positive_signal_fft, color='blue', label='Amplitude Spectrum')
  172.  
  173.   # Add labels to the axes.
  174.   plt.xlabel('Frequency (Hz)')
  175.   plt.ylabel('Amplitude')
  176.  
  177.   # Add title
  178.   plt.title(title)
  179.   # Add grid
  180.   plt.grid(True)
  181.   # Show the plot.
  182.   plt.tight_layout()
  183.   plt.show()
  184.  
  185.  
  186. def save_signal_to_wav(filename, signal):
  187.   """
  188.  Save a signal to a WAV file.
  189.  
  190.  Arguments:
  191.    filename (str): The name of the output WAV file.
  192.    signal (numpy.ndarray): The signal data as a NumPy array.
  193.  
  194.  Returns:
  195.    None
  196.  """
  197.  
  198.   # Calculate the maximum amplitude of the signal
  199.   max_amplitude = np.max(np.abs(signal))
  200.  
  201.   # Normalize the signal to the range [-1, 1]
  202.   if max_amplitude > 0:
  203.       normalized_signal = signal / max_amplitude
  204.   else:
  205.       normalized_signal = signal
  206.  
  207.   normalized_signal = np.int16(normalized_signal * 32767)
  208.  
  209.   # Write the signal to a WAV file
  210.   wavfile.write(filename, sampling_rate, normalized_signal)
  211.  
  212. def main():
  213.   """
  214.  The main function.
  215.  
  216.  This function generates simple audio signals, plays them, visualizes them, plots the spectrum, and saves the signals to wav file formats.
  217.  """
  218.  
  219.   # Define the parameters for the audio signal.
  220.   frequency = 4x0 # where x is the last digit of your faculty number !
  221.   duration = 1
  222.   amplitude = 1
  223.  
  224.   # Generate sine audio signal.
  225.   audio_signal = generate_sine_wave(frequency, duration, amplitude)
  226.   visualize_signal(audio_signal, duration, title="Sin wave")
  227.   plot_positive_spectrum(audio_signal, title = "Sin wave spectrum (positive frequencies only)")
  228.   save_signal_to_wav("sin_wave.wav", audio_signal)
  229.  
  230.   # Generate rectangular audio signal.
  231.   audio_signal = generate_rectangular_wave(frequency, duration, amplitude)
  232.   visualize_signal(audio_signal, duration, title="Rectangle wave")
  233.   plot_positive_spectrum(audio_signal, title="Rectangle wave spectrum")
  234.   save_signal_to_wav("rectangular_wave.wav", audio_signal)
  235.  
  236.   # Generate asymetric triangular audio signal.
  237.   audio_signal = generate_asymetric_triangular_wave(frequency, duration, amplitude)
  238.   visualize_signal(audio_signal, duration, title="Asymetric triangular wave")
  239.   plot_positive_spectrum(audio_signal, title="Asymetric triangular wave spectrum")
  240.   save_signal_to_wav("asymetric_triangular_wave.wav", audio_signal)
  241.  
  242.   # Generate symetric triangular audio signal.
  243.   audio_signal = generate_symetric_triangular_wave(frequency, duration, amplitude)
  244.   visualize_signal(audio_signal, duration, title="Symetric triangular wave")
  245.   plot_positive_spectrum(audio_signal, title="Symetric triangular wave spectrum")
  246.   save_signal_to_wav("symetric_triangular.wav", audio_signal)
  247.  
  248.  
  249. if __name__ == "__main__":
  250.   main()
  251.  
  252. # LINE 220
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement