Categoría: Sigma-Delta

  • Sigma-Delta Decodificador con Python

    Referencia: Leon-Couch, 3–8 Modulación Delta, p.192 ; Delta-sigma_modulation Wikipedia, Sigma-Delta – Modulación

    La señal de entrada para el decodificador es la señal codificada en los archivo.txt del ejemplo anterior:

    deltasigma_datos.txt, deltasigma_parametros.txt

    Los archivos para ser leidos deben copiarse al directorio donde se encuentra el algoritmo.py.

    Los parametros obtenidos del archivo.txt son:

    • ΔY = deltaY = datos[1]
    • Δt = datos[0]
    • muestras en el rango de observación: k como tamaño del arreglo yentrada.

    DeltaSigma_Decodificador

    % matplotlib inline
    # Modulacion Sigma-Delta Decodificador
    #  entrada y[n], salida: x[n]
    # propuesta:edelros@espol.edu.ec
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.io.wavfile as waves
    
    # INGRESO - Lectura de datos desde archivos
    # archivoparam = intput('archivo.txt de parametros: ')
    # archivodatos = input('archivo.txt de datos: ')
    # arhivoaudio = input('archivo.wav a grabar: ')
    
    archivoparam = 'deltasigma_parametros.txt'
    archivodatos = 'deltasigma_datos.txt'
    archivoaudio = 'sigmadeltaaudio.wav'
    
    param = np.loadtxt(archivoparam,dtype=float)
    yentrada = np.loadtxt(archivodatos,dtype=int)
    

    Decodificar la señal +1 y -1 en el vector yentrada consiste en acumular los valores de la secuencia en xdigital usando escalones de tamaño deltaY.

    Se procede de forma semejante para los tiempos td usados para el eje de las abscisas usando pasos deltaT.

    # PROCEDIMIENTO
    deltaT = param[0] # Tamaño delta en eje tiempo
    deltaY = param[1] # Tamaño delta en eje Y
    k = len(yentrada) # número de muestras
    xdigital = np.zeros(k, dtype='int16')
    punto = np.zeros(k, dtype=int)      # número de muestras
    td = np.zeros(k, dtype=float)    # tiempo muestreo
    
    # DECOdifica Sigma-Delta
    xdigital[0] = yentrada[0]
    punto[0] = 0
    td[0] = 0
    for i in range(1,k):
        punto[i] = i
        td[i] = deltaT*i
        xdigital[i] = xdigital[i-1]+yentrada[i]*deltaY
    

    El resultado puede ser observado en los vectores, en una gráfica de los vectores y en un archivoaudio.wav.

    # SALIDA
    print('entrada: ')
    print(yentrada)
    print('salida: ')
    print(xdigital)
    
    entrada: 
    [ 0  1 -1  1 -1  1  1 -1  1 -1  1  1 -1  1 -1  1 -1  1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1  1 -1  1 -1  1]
    salida: 
    [     0   6801      0   6801      0   6801  13602   6801  13602   6801   13602  20403  13602  20403  13602  20403  13602  20403  27204  20403 27204  20403  27204  20403  27204  20403  27204  20403  27204  20403  27204  20403  27204  20403  13602  20403  13602  20403  13602  20403  13602   6801  13602   6801  13602   6801      0   6801      0   6801  0  -6801   0  -6801      0  -6801 -13602  -6801 -13602  -6801  -13602 -20403 -13602 -20403 -13602 -20403 -13602 -20403 -27204 -20403  -27204 -20403 -27204 -20403 -27204 -20403 -27204 -20403 -27204 -20403  -27204 -20403 -27204 -20403 -13602 -20403 -13602 -20403 -13602]
    
    # Graficar
    plt.figure(1)       # define la grafica
    plt.suptitle('Decodifica Delta-Sigma')
    
    plt.subplot(211)    # grafica de 2x1 y subgrafica 1
    plt.ylabel('entrada: y[n]')
    plt.axis((0,k-1,-1.1,1.1)) # Ajusta ejes
    plt.step(punto,yentrada, where='post')
    
    plt.subplot(212)    # grafica de 2x1 y subgrafica 2
    plt.ylabel('salida: x[t]')
    xmax = np.max(xdigital)+0.1*np.max(xdigital)# rango en el eje y
    xmin = np.min(xdigital)-0.1*np.max(xdigital)
    plt.axis((0,td[k-1],xmin,xmax)) # Ajusta ejes
    plt.step(td,xdigital, where='post', color='m')
    
    plt.show()
    

    Archivo de Audio del decodificador

    Para crear el archivo de audio que permita escuchar el resultado del decodificador, se utiliza una instrucción de scipy que require:

    • el nombre del archivoaudio.wav: 'sigmadeltaaudioruido.wav'
    • la frecuencia de muestreo del sonido: muestreo
    • el arreglo con la señal digital reconstruida: xdigital

    El archivo.wav creado puede ejecutarse con windows media player:
    sigmadeltaaudio440Hz_1s.wav

    # Salida
    # Archivo de audio.wav
    muestreo = int(1/deltaT)
    waves.write(archivoaudio, muestreo, xdigital)
    print(' ... ' + archivoaudio + ' ...')
    
    ... sigmadeltaaudio.wav ...
    

    windowsmediaplayer

  • Sigma-Delta Codificador con Python

    Referencia: Leon-Couch, 3–8 Modulación Delta, p.192; Delta-sigma_modulation, Wikipedia ; Sigma-Delta – Modulación

    La señal de entrada es el archivo de sonido:

    440Hz_44100Hz_16bit_05sec.wav

    que es tipo monofónica. La modulación delta-sigma se aplica usando los parámetros:

    • ΔY = deltaY = 0.3 * max(sonido)
    • rango de observación [0, 0.002] segundos para la gráfica
    • muestras en el rango de observación: k

    Nota: En el caso de sonido estéreo, con dimensión kx2, se usa solo un canal (sonido[:,0])

    Hay que tomar en cuenta que para graficar, la misma se satura con un número grande de muestras . Para escuchar el sonido el tiempo de 'termina' será de al menos 1 segundo.
    codifica Delta Sigma

    Algoritmo en Python

    A continuación se describe el algoritmo para codificar en Python, que el el bloque de ingreso especifica el rango de observación en segundos.

    % matplotlib inline
    # Modulacion Delta Sigma - Codificador
    # entrada x(t), salida: y[n]
    # propuesta:edelros@espol.edu.ec
    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.io.wavfile as waves
    
    # INGRESO 
    # archivo = input('archivo de sonido:' )
    archivo = '440Hz_44100Hz_16bit_05sec.wav'
    muestreo, sonido = waves.read(archivo)
    
    # rango de observación en segundos
    inicia = 0
    termina = 0.002
    canal = 0   #Usar un canal en caso de estereo
    
    c:\python34\lib\site-packages\scipy\io\wavfile.py:179: WavFileWarning: Chunk (non-data) not understood, skipping it. WavFileWarning)
    

    Si el archivo.wav contiene etiquetas, el proceso de lectura emite una advertencia (WavFileWarning) que no afecta al proceso de codificación.

    Se extrae solo una porción del sonido que contiene las k muestras en el intervalo de observación y se envía graficar.

    La señal xdigital y ysalida se calcula con las diferencias entre el valor de cada muestra analógica y el valor xdigital anterior; se toma en cuenta solo el signo para acumular y generar el vector ysalida.

    # PROCEDIMIENTO
    # Codificar Sigma-Delta
    deltaY = 0.1*np.max(sonido) 
    deltaT = 1/muestreo 
    
    # Usar un canal en caso de estereo
    canales=sonido.shape
    cuantos=len(canales)
    canal = 0   
    if (cuantos==1): # Monofónico
        uncanal=sonido[:]  
    if (cuantos==2): # Estéreo
        uncanal=sonido[:,canal] 
    
    # Extrae solo una porcion del sonido
    donde = int(inicia/deltaT)
    # tiempo muestreo de la señal analógica
    t = np.arange(inicia,termina,deltaT) 
    k = len(t) 
    
    muestra = np.copy(uncanal[donde:donde+k])
    
    # Señal Digital
    xdigital = np.zeros(k, dtype=float) 
    ysalida = np.zeros(k, dtype=int) 
    
    for i in range(1,k):
        diferencia = muestra[i]-xdigital[i-1]
        if (diferencia>0):
            signo = 1
        else:
            signo = -1
        xdigital[i] = xdigital[i-1]+signo*deltaY
        ysalida[i] = signo
        
    parametros=np.array([deltaT,deltaY,k])
    

    Los resultados de pueden observar de dos maneras, en los archivos.txt de parámetros y datos, o en una gráfica.

    # SALIDA
    print('parámetros:[deltaT, deltaY, k]')
    print(parametros)
    print('datos:')
    print(ysalida)
    np.savetxt('deltasigma_parametros.txt',parametros)
    np.savetxt('deltasigma_datos.txt',ysalida,fmt='%i')
    print('... archivos.txt guardados ...')
    
    parámetros:[deltaT, deltaY, k]
    [  2.26757370e-05   6.80100000e+03   8.90000000e+01]
    datos:
    [ 0  1 -1  1 -1  1  1 -1  1 -1  1  1 -1  1 -1  1 -1  1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1 -1  1  1 -1  1 -1  1]
    ... archivos.txt guardados ...
    

    Gráficas

    para graficar y no saturar el gráfico, se recomienda observar solo una porción de los datos determinada por 'verdesde' y 'verhasta' muestras desde [0,k-1]

    verdesde=0
    verhasta=90
    
    # Graficar
    plt.figure(1)       # define la grafica
    plt.suptitle('Codificador Delta-Sigma')
    
    plt.subplot(211)    # grafica de 2x1 y subgrafica 1
    plt.ylabel('x(t), x[n]')
    plt.plot(t[verdesde:verhasta],muestra[verdesde:verhasta], 'g')
    plt.step(t[verdesde:verhasta],xdigital[verdesde:verhasta], where='post',color='m') # Puntos x[n]
    
    plt.subplot(212)    # grafica de 2x1 y subgrafica 2
    plt.ylabel('y[n]')
    #plt.plot(ysalida, 'bo')     # Puntos y[n]
    plt.axis((verdesde,verhasta,-1.1,1.1))
    puntos=np.arange(verdesde,verhasta,1)     #posicion eje x para escalon
    plt.step(puntos[verdesde:verhasta],ysalida[verdesde:verhasta], where='post')
    
    plt.show()
    

    codifica Delta Sigma
    Archivos Resultantes: deltasigma_datos.txt, deltasigma_parametros.txt