audio - org - processing sound examples
Aumenta programáticamente el tono de una matriz de muestras de audio (6)
Para disminuir y aumentar el tono es tan simple como reproducir la muestra a una velocidad más baja o más alta que 44.1kHz. Esto producirá un sonido de grabación más lento / más rápido, pero deberá agregar el ''scratchiness'' de los registros reales.
Hola gente amable del mundo de la informática de audio,
Tengo una serie de muestras que respresentan una grabación. Digamos que son 5 segundos a 44100Hz. ¿Cómo jugaría esto con un tono aumentado? ¿Y es posible aumentar y disminuir el tono de forma dinámica? Al igual que el tono aumenta lentamente para duplicar la velocidad y luego retroceder.
En otras palabras, quiero tomar una grabación y reproducirla como si estuviera siendo ''arañada'' por un dj
El seudocódigo siempre es bienvenido. Escribiré esto en C.
Gracias,
EDIT 1
Permíteme aclarar mis intenciones. Quiero mantener la reproducción a 44100 Hz y, por lo tanto, necesito manipular las muestras antes de la reproducción . Esto también se debe a que me gustaría mezclar el audio que tiene un tono aumentado con audio que se ejecuta a una velocidad normal .
Expresado de otra manera, ¿tal vez necesito reducir el audio en el mismo número de muestras de alguna manera? De esa manera, cuando se reproduce, ¿sonará más rápido?
EDIT 2
Además, me gustaría hacer esto yo mismo. No hay bibliotecas, por favor (a menos que sienta que podría elegir el código y encontrar algo interesante).
EDIT 3
Una muestra de código escrito en C que toma 2 argumentos (matriz de muestras y factor de tono) y luego devuelve una matriz del nuevo audio ¡sería fantástico!
PD. Empecé una recompensa por esto no porque no creo que las respuestas ya dadas no sean válidas. Solo pensé que sería bueno obtener más comentarios sobre el tema.
PREMIO DE BOUNTY
Honestamente, me gustaría poder distribuir la recompensa por varias respuestas diferentes, ya que fueron bastantes las que pensé que fueron muy útiles. Grito especial a Daniel por pasarme un código y AShelly y Hotpaw2 por poner en tales respuestas detalladas.
Aunque finalmente utilicé una respuesta de otra pregunta SO a la que hace referencia el datageist y, por lo tanto, el premio se lo concedo a él.
Gracias de nuevo a todos!
Esto me ayudó con el remuestreo, que es lo mismo que necesitabas solo mirar desde el lado opuesto.
Si no puede encontrar el código, haga ping, tengo una buena rutina de C para esto.
Sí, es posible.
Pero esto no es una pequeña cantidad de pseudo código. Usted está pidiendo un algoritmo de modificación de tono de tiempo, que es una cantidad bastante grande y complicada de código DSP para resultados decentes.
Aquí hay una descripción de estiramiento del tiempo de paso de DSP Dimensions . También puedes buscar algoritmos de vocoder de fase en Google.
ADICIONAL:
Si desea "scratch", como un DJ podría hacer con un LP en un tocadiscos físico, no necesita modificación de tono de tiempo. El rayado cambia el tono y la velocidad de juego en la misma cantidad (no de forma independiente, ya que requeriría una modificación de paso de tiempo).
Y la matriz resultante no será de la misma longitud, pero será más corta o más larga en una cantidad de cambio de tono / velocidad.
Puede cambiar el tono, así como hacer que el sonido se reproduzca más rápido o más lento en la misma proporción, simplemente remuestreando la señal utilizando una interpolación filtrada adecuada. Simplemente mueva cada punto de muestra, en lugar de 1.0, por suma de coma flotante según el cambio de velocidad deseado, luego filtre e interpole los datos en ese punto. La interpolación usando un kernel de interpolación Sinc con ventana, con una frecuencia de transición de filtro de paso bajo por debajo de la frecuencia de muestreo local original e interpolada, funcionará bastante bien. La búsqueda de "interpolación Sinc con ventana" en la web arroja muchos resultados adecuados.
Necesita un método de interpolación que incluya un filtro de paso bajo, de lo contrario, escuchará un ruido de alias molesto. (La excepción a esto podría ser si su archivo de sonido original ya está severamente filtrado de paso bajo una década o más por debajo de la frecuencia de muestreo).
Si desea que esto se haga fácilmente, vea la sugerencia de AShelly [edit: de hecho, pruébelo primero de todos modos] . Si necesitas buena calidad, básicamente necesitas un vocoder de fase .
La idea más básica de un vocoder de fase es encontrar las frecuencias en las que se compone el sonido, cambiar esas frecuencias según sea necesario y resintetizar el sonido. Entonces una simplificación brutal sería:
- ejecutar FFT
- cambiar todas las frecuencias por un factor
- ejecutar FFT inversa
Si va a implementar esto usted mismo, definitivamente debe leer una explicación detallada de cómo funciona un vocoder de fase . El algoritmo realmente necesita muchas más consideraciones que la simplificación de tres pasos anterior.
Por supuesto, existen implementaciones ya hechas , pero de la pregunta que reúno, usted quiere hacer esto usted mismo.
Eche un vistazo al documento "Elefante" en la respuesta de Nosredna a esta pregunta (muy similar) ASÍ: ¿Cómo se hace una interpolación bicúbica (u otra no lineal) de los datos de audio re-muestreados?
Las implementaciones de muestra se proporcionan a partir de la página 37 y, como referencia, la respuesta de AShelly corresponde a la interpolación lineal (en esa misma página). Con un pequeño ajuste, cualquiera de las otras fórmulas en el documento podría ser conectada a ese marco.
Para evaluar la calidad de un método de interpolación dado (y comprender los posibles problemas con el uso de esquemas "más baratos"), eche un vistazo a esta página:
http://www.discodsp.com/highlife/aliasing/
Para obtener más teoría de la que probablemente quiera tratar (con el código fuente), esta también es una buena referencia:
Una forma es mantener un índice de punto flotante en la onda original y mezclar las muestras interpoladas en la onda de salida.
//Simulate scratching of `inwave`:
// `rate` is the speedup/slowdown factor.
// result mixed into `outwave`
// "Sample" is a typedef for the raw audio type.
void ScratchMix(Sample* outwave, Sample* inwave, float rate)
{
float index = 0;
while (index < inputLen)
{
int i = (int)index;
float frac = index-i; //will be between 0 and 1
Sample s1 = inwave[i];
Sample s2 = inwave[i+1];
*outwave++ += s1 + (s2-s1)*frac; //do clipping here if needed
index+=rate;
}
}
Si desea cambiar la rate
sobre la marcha, puede hacerlo también.
Si esto crea artefactos ruidosos cuando rate> 1, intente reemplazar *outwave++ += s1 + (s2-s1)*frac;
con esta técnica ( de esta pregunta )
*outwave++ = InterpolateHermite4pt3oX(inwave+i-1,frac);
dónde
public static float InterpolateHermite4pt3oX(Sample* x, float t)
{
float c0 = x[1];
float c1 = .5F * (x[2] - x[0]);
float c2 = x[0] - (2.5F * x[1]) + (2 * x[2]) - (.5F * x[3]);
float c3 = (.5F * (x[3] - x[0])) + (1.5F * (x[1] - x[2]));
return (((((c3 * t) + c2) * t) + c1) * t) + c0;
}
Ejemplo de uso de la técnica de interpolación lineal en "Windows Startup.wav" con un factor de 1.1. El original está en la parte superior, la versión acelerada está en la parte inferior:
Puede que no sea matemáticamente perfecto, pero suena como debería y debería funcionar bien para las necesidades del OP.