#!/usr/bin/env python # coding: utf-8 # # Pachete necesare pentru folosirea acestui Notebook # # Vom folosi [numpy](https://numpy.org/), [matplotlib](https://matplotlib.org/), și [sounddevice](https://python-sounddevice.readthedocs.io/). # In[4]: import numpy as np import matplotlib.pyplot as plt import sounddevice as sd # # Generarea unui semnal sinusoidal # # Întâi trebuie să definim parametrii sinusoidei continuue: # # * orizontul de timp ($t$) # * frecvența semnalului original ($f_0$) # * amplitudinea ($A$) # * faza ($\varphi$) # In[5]: time_of_view = 1 # s frequency = 2 # Hz amplitude = 1 phase = 0 # Iar apoi parametrii de măsurare, sinusoida discretizată: # * frecvența de eșantionare ($f_s$) # * perioada de eșantionare ($t_s$) # * numărul de eșantionare ($n$) # In[6]: sampling_rate = 12 # Hz sampling_period = 1./sampling_rate # s n_samples = time_of_view/sampling_period # Cu datele de mai sus putem genera orizontul de timp cu momentele de interes pentru semnalul continuu și cel discretizat ($t$, respectiv $nt_s$): # In[7]: atime = np.linspace (0, time_of_view, int(10e5 + 1)) # s. time = np.linspace (0, time_of_view, int(n_samples + 1)) # *Observație*: orizontul de timp continuu (analog) este de fapt un orizont de timp discret ($nt_s$) foarte dens ($n=10^5$ eșantione). # # Cu aceste date putem crea o funcție sinus ce generează sinusoidele parametrizate conform variabilelor de mai sus: # In[8]: def sine (amplitude, frequency, time, phase): return amplitude * np.sin (2 * np.pi * frequency * time + phase) # ## Sinusoidă continuă # Pentru a obține o sinusoidă "continuă" putem apela funcția ```sine```: # In[9]: asignal = sine(amplitude, frequency, atime, phase) plt.grid(True) plt.plot (atime, asignal) # ## Sinusoidă discretizată # Discretizarea se obține apelând aceiași funcție ```sine``` dar cu parametrii discreți și folosind ```stem``` pentru a obține cele $n$ eșantioane: # In[10]: signal = sine(amplitude, frequency, time, phase) plt.grid(True) plt.stem (time, signal) # # Producerea și audiția unui ton # # Pentru a produce o sinusoidă ce poate fi percepută de urechea umană trebuie să creștem frecvența și amplitudinea acesteia. # # În exemplul de mai jos generăm o sinusoidă de frecvență $f_0=440\text{Hz}$ și amplitudine $10.000$ pe care o discretizăm cu frecvența de eșantionare $f_s=44.100\text{Hz}$ pe un orizont de timp de $2\text{s}$. # In[11]: time_of_view = 2 # s frequency = 440 # Hz amplitude = 10000 phase = 0 sampling_rate = 44100 sampling_period = 1./sampling_rate # s n_samples = time_of_view/sampling_period time = np.linspace (0, time_of_view, int(n_samples + 1)) tone = sine(amplitude, frequency, time, phase) # Aceast ton îl vom discretiza cu o frecvență de eșantionare $f_s$ conform ```sampling_rate``` și îl vom transforma în formatul WAV prin conversia eșantioanelor la întregi pe 16-biți: # In[12]: sd.default.samplerate = sampling_rate wav_wave = np.array(tone, dtype=np.int16) sd.play(wav_wave, blocking=True) sd.stop() # # Sarcini # # 1. [8p] Scrieți tonurile pentru notele muzicale Do, Re, Mi, Fa, Sol, La, Si, Do. # # 2. [8p] Compuneți un cântec simplu clasic (ex. Frère Jacques) într-un singur semnal. # # 3. [4p] Citiți o partitură la intrare (folosind [LilyPond](https://lilypond.org/) sau formatul propriu) și produceți semnalul ce conține melodia la ieșire prin compunerea tonurilor asociate notelor automat.