AudioKit y síntesis de audio en iOS / OSX



AudioKit es un marco de audio desarrollado por ingenieros de audio, programadores y m√ļsicos espec√≠ficamente para iOS y OSX. Proporciona herramientas para procesar y sintetizar sonido. Debajo del cap√≥ hay una mezcla de Swift, Objective-C, C ++ y C, y la API de Audio Unit de Apple. ¬°Las tecnolog√≠as impresionantes (y bastante sofisticadas) est√°n envueltas en una API Swift muy amigable, a la que se puede acceder directamente desde Xcode Playgrounds!

En este tutorial, realizaremos un viaje a través de AudioKit, así como la historia de la síntesis de sonido. Aprenderá los conceptos básicos de la física del sonido y cómo funcionaron los primeros sintetizadores como el Hammond Organ. Además, se considerarán técnicas modernas, por ejemplo, muestreo.

¡Haz tu bebida favorita, siéntate y vete!

Primer paso


Comenzando con AudioKit 3.6, configurar parques infantiles para trabajar con el marco se ha vuelto bastante simple. Descargue y descomprima la lista de reproducción de inicio aquí .

El viaje comienza con unos pocos pasos para configurar los parques infantiles para trabajar con AudioKit.

Abra el archivo AudioKitPlaygrounds.xcodeproj en Xcode. Haga clic en el botón + en la esquina inferior izquierda de la pantalla, seleccione Archivo ... y luego En blanco en la sección Zona de juegos , guarde el nuevo archivo en la carpeta Zona de juegos junto con áreas de juegos de demostración.

El área de juegos recientemente agregada comenzará y se verá más o menos así:


Reemplace el código generado con lo siguiente:

import AudioKitPlaygrounds import AudioKit let oscillator = AKOscillator()  AudioKit.output = oscillator try AudioKit.start() oscillator.start() sleep(10) 

El √°rea de juegos no comenzar√° hasta que al menos una vez que haya ensamblado el proyecto, para esto puede usar el elemento de men√ļ Producto / Construcci√≥n o la combinaci√≥n de teclas ‚Ćė-B . Despu√©s de eso, vuelva a correr el patio de recreo y escuche un zumbido durante 10 segundos. (Nota del traductor: a veces el error no desaparece, y debe cambiar a otro patio de juegos y volver para que funcione). Puede usar el bot√≥n Reproducir / Detener en la parte inferior izquierda de la ventana de reproducci√≥n para detener la reproducci√≥n o reiniciarla.
Nota: Si a√ļn ve errores, intente reiniciar Xcode. Desafortunadamente, los frameworks y parques infantiles no son muy buenos amigos entre s√≠ y pueden comportarse de manera impredecible.

Osciladores y física del sonido.


La humanidad ha estado tocando m√ļsica a trav√©s de varios objetos f√≠sicos durante miles de a√Īos. Muchos de nuestros instrumentos habituales, como guitarras o bater√≠as, tienen cientos de a√Īos. La primera experiencia registrada de usar circuitos electr√≥nicos para generar sonido fue llevada a cabo en 1874 por Elias Gray. Elisha trabaj√≥ en el campo de las telecomunicaciones, e invent√≥ el oscilador, el sintetizador musical m√°s simple. Con √©l comenzaremos nuestra inmersi√≥n.

Haga clic derecho en su área de juegos, seleccione Nueva página de juegos y reemplace el código generado con lo siguiente:

 import AudioKitPlaygrounds import AudioKit import PlaygroundSupport // 1. Create an oscillator let oscillator = AKOscillator() // 2. Start the AudioKit 'engine' AudioKit.output = oscillator try AudioKit.start() // 3. Start the oscillator oscillator.start() PlaygroundPage.current.needsIndefiniteExecution = true 

El patio de juegos comenzar√° a generar un zumbido continuo, seg√ļn lo previsto. Puede hacer clic en detener para detenerlo.

Esto es casi lo mismo que hicimos en el patio anterior, pero esta vez vamos a profundizar en los detalles.

Considere todos los pasos en orden:

  1. Aquí creamos un oscilador. El oscilador es el sucesor de AKNode . Los nodos son los elementos que forman una cadena de audio que genera y modifica el sonido.
  2. Aqu√≠ conectamos la salida de nuestro √ļltimo nodo con el motor AudioKit. En nuestro caso, solo un nodo. Adem√°s, el marco dirigir√° la salida del nodo al dispositivo de reproducci√≥n de audio.
  3. Bueno, comenzamos el oscilador, en la salida comienza a enviar una onda de sonido.

El oscilador genera una se√Īal repetitiva que no se detiene. En este libro de jugadas, AKOscillator genera una onda sinusoidal. Usando AudioKit, se env√≠a una se√Īal digital de onda sinusoidal a los altavoces o auriculares. Como resultado, escuchamos un sonido que oscila a la misma frecuencia que la onda sinusoidal que generamos. Esta onda sinusoidal no suena muy musical.



Dos par√°metros son responsables del sonido de este oscilador: la amplitud, la altura de la onda sinusoidal, determina el volumen y la frecuencia del sonido, la altura del sonido depende de ello.

En el patio de recreo, agregue las siguientes líneas de código justo después de crear el oscilador:

 oscillator.frequency = 300 oscillator.amplitude = 0.5 

El sonido ha cambiado, ahora suena el doble de silencioso y mucho m√°s bajo. La frecuencia de la se√Īal se mide en hercios (n√ļmero de repeticiones por segundo) y determina el tono de la nota. La amplitud (amplitud) se establece de 0 a 1 y es responsable del volumen.

La invención de Elijah Gray fue registrada en la primera patente de un instrumento musical electrónico.



Muchos a√Īos despu√©s, Leo Theremin invent√≥ un instrumento musical un poco extra√Īo utilizado hasta el d√≠a de hoy: theremin. En el theremin, puede cambiar la frecuencia del sonido con movimientos de las manos sobre el instrumento. Para entender c√≥mo suena el theremin, puedes escuchar las vibraciones de los Beach Boys, y no hay nada con lo que confundir el theremin.

Puede simular el sonido de thereminvox, para esto, agregue el siguiente código a la configuración del oscilador:

 oscillator.rampDuration = 0.2 

Y reemplace la línea que inicia AudioKit ( try AudioKit.start() ) con lo siguiente:

 let performance = AKPeriodicFunction(every: 0.5) { oscillator.frequency = oscillator.frequency == 500 ? 100 : 500 } try AudioKit.start(withPeriodicFunctions: performance) performance.start() 

La propiedad rampDuration permite que el oscilador cambie suavemente los valores de sus par√°metros (por ejemplo, frecuencia o amplitud). AKPeriodicFunction es una utilidad √ļtil de AudioKit para la ejecuci√≥n peri√≥dica de c√≥digo. En nuestro ejemplo, cambia la frecuencia de la onda sinusoidal de 500Hz a 100Hz cada 0.5 segundos.

Felicidades Acabas de hacer tu primer theremin. Un oscilador simple puede generar notas musicales, pero no suena muy bien. Hay muchos factores que afectan el sonido de los instrumentos físicos, como el piano, por ejemplo. Y además consideraremos algunos de ellos.

Sobres de sonido


Cuando un instrumento musical toca una nota, el volumen de su sonido cambia con el tiempo y la naturaleza de los cambios difiere de un instrumento a otro. Un modelo que puede simular este efecto se llama el sobre Ataque-Decaimiento-Liberación-sostenido (ADSR) (Nota: los sintetizadores disponibles para la compra nunca se localizan, por lo que el nombre de la curva es el mismo que se puede ver en el panel de este sintetizador).



El sobre ADSR consta de:

  • Ataque : ataque o tiempo en el que el sonido alcanza su volumen m√°ximo.
  • Decaimiento : salvaje o tiempo durante el cual el volumen cae del m√°ximo al principal
  • Sostener : el volumen principal, a diferencia de los dos par√°metros anteriores, no es el tiempo, despu√©s de que pasan el ataque y los salvajes y antes de soltar la tecla del sintetizador, se generar√° sonido con este volumen
  • Liberaci√≥n : liberaci√≥n o tiempo en el que el volumen se convierte en cero

En el piano, el sonido se extrae con martillos que tocan las cuerdas y, por lo tanto, son r√°pidos o, tambi√©n dicen, ataques cortos y salvajes. El viol√≠n puede tener un ataque largo, salvaje y sostenido, el m√ļsico puede influir en estos par√°metros por la forma en que usa el arco.

Uno de los primeros instrumentos musicales electrónicos fue Hammond Novachord. Este instrumento fue fabricado en 1939, constaba de 163 tubos de vacío y más de 1000 condensadores, y pesaba 230 kilogramos. Desafortunadamente, solo se hicieron unos cientos de copias, y nunca recibió el éxito comercial.



Haga clic derecho en Journey Playground , seleccione New Playground Page y cree una nueva página llamada ADSR . Reemplace el código generado con lo siguiente:

 import AudioKitPlaygrounds import AudioKit import PlaygroundSupport          let oscillator = AKOscillator() 

Simplemente crea un oscilador con el que ya estamos familiarizados. A continuación, agregue el siguiente código al final del patio de recreo:

 let envelope = AKAmplitudeEnvelope(oscillator) envelope.attackDuration = 0.01 envelope.decayDuration = 0.1 envelope.sustainLevel = 0.1 envelope.releaseDuration = 0.3 

Esto crea un AKAmplitudeEnvelope que define el sobre ADSR. Los parámetros de duración (attackDuration, decayDuration, releaseDuration) se especifican en segundos, y el volumen (sustainLevel) se establece en el rango de 0 a 1.

AKAmplitudeEnvelope es el sucesor de AKNode de la misma manera que AKOscillator . En el código anterior, pasamos los nodos de envolvente del oscilador al inicializador, conectando así los nodos.

A continuación, agregue el siguiente código:

 AudioKit.output = envelope let performance = AKPeriodicFunction(every: 0.5) { if (envelope.isStarted) { envelope.stop() } else { envelope.start() } } try AudioKit.start(withPeriodicFunctions: performance) performance.start() oscillator.start() PlaygroundPage.current.needsIndefiniteExecution = true 

Lanzará AudioKit, pero esta vez alimentamos la salida del nodo ADSR a su entrada. Para escuchar el efecto ADSR, constantemente AKPeriodicFunction y desactivamos el nodo utilizando la función AKPeriodicFunction .



Ahora puedes escuchar cómo se toca la nota en ciclos, pero esta vez es un poco más como un piano.

El ciclo se ejecuta dos veces por segundo en cada iteración, iniciando o deteniendo el ADSR. Cuando el ADSR comienza con un ataque rápido, el volumen alcanza su valor máximo en 0.01 segundos, después de lo cual el volumen disminuye en 0.1 segundos al nivel principal y permanece allí durante 0.5 segundos, y finalmente decae en 0.3 segundos.

Puede tocar con los parámetros usted mismo e intentar tocar, por ejemplo, el sonido de un violín.

Los sonidos que encontramos se basan en la onda sinusoidal que genera AKOscillator . Aunque ASDR ayuda a suavizar los sonidos fuertes, a√ļn no puede llamar a estos sonidos musicales.

Además, consideraremos cómo obtener un sonido más profundo.

Síntesis aditiva


Cada instrumento musical tiene su propio sonido o timbre especial. Un timbre es lo que distingue los sonidos de un piano de los sonidos de un violín, a pesar de que pueden tocar la misma nota. Un parámetro importante del timbre es el espectro de sonido. El espectro de sonido describe el rango de frecuencias reproducidas que, cuando se suman, dan una nota. Nuestro patio de recreo actual usa un oscilador que suena solo a una frecuencia y suena bastante artificial.

Puede obtener un sonido más vivo utilizando un conjunto de osciladores para tocar una sola nota. Este enfoque se conoce como síntesis aditiva, y este es el tema de nuestro próximo patio de recreo.

Haga clic derecho en el área de juegos, seleccione Nueva página de juegos y cree una nueva página llamada Síntesis aditiva . Reemplace el código generado con lo siguiente:

 import AudioKitPlaygrounds import AudioKit import AudioKitUI import PlaygroundSupport func createAndStartOscillator(frequency: Double) -> AKOscillator { let oscillator = AKOscillator() oscillator.frequency = frequency return oscillator } 

Para la síntesis aditiva, necesita varios osciladores, para esto usaremos. createAndStartOscillator

A continuación, agregue el código:

 let frequencies = (1...5).map { $0 * 261.63 } 

Aqu√≠ tomamos un intervalo de n√ļmeros del 1 al 5 y multiplicamos cada uno por 261.53, la frecuencia de la nota. Las m√ļltiples frecuencias resultantes se denominan arm√≥nicos.

Ahora agregue el código:

 let oscillators = frequencies.map { createAndStartOscillator(frequency: $0) } 

Aquí creamos un oscilador para cada una de las frecuencias que usamos.

Para combinar osciladores, agregue el siguiente código:

 let mixer = AKMixer() oscillators.forEach { $0.connect(to: mixer) } 

AKMixer es otro tipo de nodo AudioKit. Recibe información de uno o más nodos y los combina en uno.

Agregue el siguiente código:

 let envelope = AKAmplitudeEnvelope(mixer) envelope.attackDuration = 0.01 envelope.decayDuration = 0.1 envelope.sustainLevel = 0.1 envelope.releaseDuration = 0.3 AudioKit.output = envelope let performance = AKPeriodicFunction(every: 0.5) { if (envelope.isStarted) { envelope.stop() } else { envelope.start() } } try AudioKit.start(withPeriodicFunctions: performance) performance.start() oscillators.forEach { $0.start() } 

Todo debe quedar claro con este código: agregue ADSR a la salida del mezclador, salida a través de AudioKit y actívelo / desactívelo periódicamente.

Para lidiar bien con la s√≠ntesis aditiva, ser√° √ļtil jugar con varias combinaciones de estas frecuencias. Y en esto, la oportunidad de parques infantiles como Live View es ideal para nosotros.

Para hacer esto, agregue el código:

 class LiveView: AKLiveViewController { override func viewDidLoad() { addTitle("Harmonics") oscillators.forEach { oscillator in let harmonicSlider = AKSlider( property: "\(oscillator.frequency) Hz", value: oscillator.amplitude ) { amplitude in oscillator.amplitude = amplitude } addView(harmonicSlider) } } } PlaygroundPage.current.needsIndefiniteExecution = true PlaygroundPage.current.liveView = LiveView() 

En AudioKit hay clases específicamente para el trabajo conveniente en parques infantiles. En nuestro ejemplo, usamos AKLiveViewController , al usarlo colocamos elementos verticalmente. Y también para cada oscilador creamos un AKSlider . Los controles deslizantes se inicializan por los valores de la frecuencia y la amplitud de los osciladores, y causan un bloqueo al interactuar con ellos. En el bloque de cada control deslizante, cambiamos la amplitud del oscilador correspondiente. Así que solo puede agregar interactividad a sus áreas de juego.

Para ver los resultados del √°rea de juegos, debe tener Live View en la pantalla. Para hacer esto, seleccione el bot√≥n con c√≠rculos que se cruzan en la parte superior derecha de la ventana y aseg√ļrese de que est√© seleccionada la lista de reproducci√≥n correcta para Live View.



Para cambiar el tono de su instrumento, puede cambiar los valores de cada control deslizante individualmente. Para un sonido realista, le sugiero que pruebe la configuración que se muestra en la captura de pantalla anterior.

¬°Uno de los primeros sintetizadores en usar s√≠ntesis aditiva fue Teleharmonium y pesaba 200 toneladas! Su incre√≠ble peso y tama√Īo, muy probablemente, se convirti√≥ en la raz√≥n de su oscuridad. El √≥rgano Hammond m√°s exitoso us√≥ ruedas de tonos similares, pero era mucho m√°s peque√Īo. Inventado en 1935, todav√≠a es ampliamente conocido como un instrumento popular en la era del rock progresivo.



La rueda de tonos es un disco giratorio con peque√Īas cavidades a lo largo del borde y una pastilla ubicada cerca del borde. El √≥rgano Hammond ten√≠a un conjunto completo de ruedas de tono que pod√≠an girar a diferentes velocidades. Una forma bastante inusual de generar sonido es m√°s bien electromec√°nica que electr√≥nica.

Para generar un espectro de sonido más realista, existen varias técnicas más: modulación de frecuencia (Modulación de frecuencia o FM) y modulación de ancho de pulso (Modulación de ancho de pulso o PWM), ambas técnicas están disponibles en AudioKit en las AKPWMOscillator AKFMOscillator y AKPWMOscillator respectivamente. Le sugiero que pruebe ambos, sustituyéndolos en lugar del AKOscillator , que usamos anteriormente.

Polifonía


En la década de 1970, el movimiento comenzó desde sintetizadores modulares, que consisten en osciladores de envolvente y filtros separados, hasta microprocesadores. En lugar de utilizar circuitos analógicos, el sonido comenzó a generarse en formato digital. Esto hizo que los sintetizadores fueran más baratos y compactos, y los sintetizadores de marcas como Yamaha muy populares.



Todos nuestros parques infantiles se limitaban a tocar una nota a la vez. Muchos instrumentos son capaces de tocar más de una nota a la vez; se llaman polifónicos . Los instrumentos que solo pueden tocar una nota se llaman monofónicos .

Para obtener un sonido polifónico, puede crear varios osciladores y enviarlos al mezclador, pero en AudioKit hay una forma más adecuada para esto.

Cree una nueva página en el patio de juegos y asígnele el nombre Polifonía. Reemplace el código generado con lo siguiente:

 import AudioKitPlaygrounds import AudioKit import AudioKitUI import PlaygroundSupport let bank = AKOscillatorBank() AudioKit.output = bank try AudioKit.start() 

Aquí creamos el banco de osciladores AKOscillatorBank . Si va a la declaración de clase, puede encontrar que es el heredero de AKPolyphonicNode , que, a su vez, es el heredero del AKNode ya conocemos, y también implementa el protocolo AKPolyphonic .

Como resultado, el banco de osciladores es el mismo nodo AudioKit que revisamos anteriormente. Su salida se puede enviar a mezcladores, sobres o cualquier otro filtro y efecto. El protocolo AKPolyphonic describe cómo tocar notas en una nota polifónica; consideremos con más detalle.

Para probar nuestro oscilador, necesitamos una forma de tocar varias notas a la vez. ¡Esto no es del todo difícil!

Agregue el siguiente c√≥digo a la lista de reproducci√≥n y aseg√ļrese de que Live View est√© abierto:

 class LiveView: AKLiveViewController, AKKeyboardDelegate { override func viewDidLoad() { let keyboard = AKKeyboardView(width: 440, height: 100) addView(keyboard) } } PlaygroundPage.current.liveView = LiveView() PlaygroundPage.current.needsIndefiniteExecution = true 

Cuando se compile el patio de recreo, ver√° lo siguiente:



Genial, ¬Ņeh? ¬°El teclado musical est√° justo en el patio de recreo!

AKKeyboardView es otra utilidad de AudioKit que facilita la exploraci√≥n de las posibilidades del marco. Presione las teclas y ver√° que no emiten ning√ļn sonido.

Actualice la setUp su PlaygroundView con lo siguiente:

 let keyboard = AKKeyboardView(width: 440, height: 100) keyboard.delegate = self addView(keyboard) 

Esto har√° que PlaygroundView un delegado de teclado y le permitir√° responder a las pulsaciones de teclas.

Actualice la declaración de clase de la siguiente manera:

 class LiveView: AKLiveViewController, AKKeyboardDelegate 


Agregue también un par de métodos justo después de la setUp :

 func noteOn(note: MIDINoteNumber) { bank.play(noteNumber: note, velocity: 80) } func noteOff(note: MIDINoteNumber) { bank.stop(noteNumber: note) } 

Cada vez que presiona una tecla, se noteOn método noteOn , todo lo que hace es decirle al banco de osciladores que comience a tocar la nota, respectivamente, en el método noteOff , la noteOff se detiene.

Sostenga el mouse y deslice las teclas, escuchará un hermoso crescendo (un término musical para un aumento gradual de la potencia del sonido). El banco de osciladores ya contiene un efecto ADSR incorporado, como resultado, la atenuación de una nota se mezcla con el ataque de la siguiente y suena bastante bien.

Es posible que haya notado que las notas que nos dieron las claves no vienen en forma de frecuencia. Se declaran como MIDINoteNumber . Si va a un anuncio de este tipo, ver√° lo siguiente:

 public typealias MIDINoteNumber = Int 

MIDI significa interfaz digital de instrumentos musicales. Este es un formato extendido para la interacci√≥n de instrumentos musicales entre s√≠. Los n√ļmeros de nota corresponden a notas en un teclado de m√ļsica est√°ndar. El segundo par√°metro: esta velocidad (velocidad) corresponde a la fuerza del golpe en la tecla. Cuanto menor sea el valor, m√°s suave ser√° el toque de la tecla, m√°s silencioso ser√° el sonido final.

Al final, debe habilitar el modo polifónico en las teclas. Agregue el siguiente código al método de setUp :

 keyboard.polyphonicMode = true 

Ahora puede tocar varias notas al mismo tiempo, como se muestra en la imagen:



Esto, por cierto, est√° en Do mayor :)

AudioKit comenz√≥ su historia hace mucho tiempo. Hoy usa Soundpipe y el c√≥digo de Csound (un proyecto MIT que se lanz√≥ en 1985). Sorprendentemente, el c√≥digo que ahora estamos lanzando en los parques infantiles y agregando al iPhone se escribi√≥ hace casi 30 a√Īos.

Muestreo


Las técnicas de síntesis de sonido que exploramos anteriormente están tratando de recrear un sonido realista usando bloques básicos simples: osciladores, filtros y mezcladores. A principios de la década de 1970, el desarrollo de la potencia de la computadora condujo a la aparición de un nuevo enfoque: el muestreo de sonido, cuyo propósito es crear una copia digital del sonido.

El muestreo es una tecnología bastante simple similar a la fotografía digital. Durante el muestreo a intervalos regulares, se registra la amplitud de las ondas de sonido:



Dos parámetros afectan la precisión con la que se grabó el sonido:

  • Profundidad de bits : o profundidad de bits, el n√ļmero de niveles de volumen individuales que puede reproducir la muestra
  • Frecuencia de muestreo: o frecuencia de muestreo, indica con qu√© frecuencia se toman las mediciones de amplitud. Medido en hercios.

Exploremos estas propiedades en un nuevo parque infantil. Cree una nueva página y asígnele el nombre "Muestras". Reemplace el código generado con lo siguiente:

 import AudioKitPlaygrounds import AudioKit import PlaygroundSupport let file = try AKAudioFile(readFileName: "climax-disco-part2.wav", baseDir: .resources) let player = try AKAudioPlayer(file: file) player.looping = true 

El código anterior carga la muestra, crea un reproductor de audio y lo pone en reproducción sin fin.

Un archivo con un archivo WAV para este tutorial está disponible aquí . Descárguelo y descomprímalo en la carpeta Recursos de su área de juegos.

Luego agregue el siguiente código al final del patio de recreo:

 AudioKit.output = player try AudioKit.start() player.play() PlaygroundPage.current.needsIndefiniteExecution = true 

Esto conectar√° su reproductor de audio con AudioKit, ¬°solo necesita subir el volumen y disfrutar!

, .

MP3-, , , . :

 let bitcrusher = AKBitCrusher(player) bitcrusher.bitDepth = 16 bitcrusher.sampleRate = 40000 

AudioKit:

 AudioKit.output = bitcrusher 

. , .

AKBitCrusher ‚ÄĒ AudioKit, . , , ZX Spectrum BBC Micro. , .

, (. delay). , AKBitCrusher . :

 let delay = AKDelay(player) delay.time = 0.1 delay.dryWetMix = 1 

0.1 . dryWetMix . 1 , .

:

 let leftPan = AKPanner(player, pan: -1) let rightPan = AKPanner(delay, pan: 1) 

AKPanner , - . .

AudioKit. , AKBitCrusher AudioKit :

 let mix = AKMixer(leftPan, rightPan) AudioKit.output = mix 

, , .



Que sigue


AudioKit. , -, , , . , , .

.

Source: https://habr.com/ru/post/440226/


All Articles