2012-08-05 7 views
5

Estoy haciendo una clase que toma una matriz de valores de frecuencias (es decir, 440Hz, 880Hz, 1760Hz) y reproduce cómo suenan combinados en un solo AudioTrack. No soy un programador de sonido, por lo que me resulta difícil escribirme, y creo que es un problema relativamente fácil para un programador de sonido con experiencia. Aquí está una parte del código a continuación en el método de reproducción:Android - Mezcla múltiples formas de onda estáticas en un solo AudioTrack

public void play() { 
    // Get array of frequencies with their relative strengths 
    double[][] soundData = getData(); 

    // TODO 
    // Perform a calculation to fill an array with the mixed sound - then play it in an infinite loop 
    // Need an AudioTrack that will play calculated loop 
    // Track sample info 
    int numOfSamples = DURATION * SAMPLE_RATE; 
    double sample[] = new double[numOfSamples]; 
    byte sound[] = new byte[2 * numOfSamples]; 

    // fill out the array 
    for (int i = 0; i < numOfSamples; ++i) { 
      sample[i] = Math.sin(2 * Math.PI * i/(SAMPLE_RATE/440)); 
    } 

    int i = 0; 
    for (double dVal : sample) { 
     // scale to maximum amplitude 
     final short val = (short) ((dVal * 32767)); 
     // in 16 bit wav PCM, first byte is the low order byte 
     sound[i++] = (byte) (val & 0x00ff); 
     sound[i++] = (byte) ((val & 0xff00) >>> 8); 
    } 

    // Obtain a minimum buffer size 
    int minBuffer = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 

    if (minBuffer > 0) { 
     // Create an AudioTrack 
     AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, numOfSamples, AudioTrack.MODE_STATIC); 

     // Write audio data to track 
     track.write(sound, 0, sound.length); 

     // Begin playing track 
     track.play(); 
    } 

    // Once everything has successfully begun, indicate such. 
    isPlaying = true; 
} 

En este momento, el código simplemente juega un concierto A (440Hz). Fue para probar si este código funciona. Ahora, necesito tomar un montón de frecuencias, realizar algún tipo de cálculo y escribir los datos de muestra.

+0

Hola gracias por código, pero me gustaría saber que lo que está haciendo la función leedato – Nitin

Respuesta

2

Ok, entonces la respuesta resultó ser un simple ciclo de suma. Aquí está, basta con sustituir esto por bucle con el original:

// fill out the array 
    for (int i = 0; i < numOfSamples; ++i) { 
      double valueSum = 0; 

      for (int j = 0; j < soundData.length; j++) { 
       valueSum += Math.sin(2 * Math.PI * i/(SAMPLE_RATE/soundData[j][0])); 
      } 

      sample[i] = valueSum/soundData.length; 
    } 

Ahora, lo que hace es simplemente tomar todas las frecuencias posibles, sumarlos en la variable, valueSum, y luego dividir que por la longitud de la matriz de frecuencias, soundData, que es un promedio simple. Esto produce una buena mezcla de onda sinusoidal de una variedad de frecuencias arbitrariamente larga.

No he probado el rendimiento, pero tengo esto funcionando en un hilo, de lo contrario, podría bloquear la interfaz de usuario. Entonces, espero que esto ayude, estoy marcando esto como la respuesta.

2

Si tiene la intención de mezclar múltiples formas de onda en una, puede evitar el recorte de varias maneras.

Suponiendo muestra [i] es un flotador que representa la suma de todos los sonidos.

recorte duro:

if (sample[i]> 1.0f) 
{ 
    sample[i]= 1.0f; 
} 
if (sample[i]< -1.0f) 
{ 
    sample[i]= -1.0f; 
} 

HEADROOM (y = 1,1x - 0,2x^3 para la curva, min y la tapa max levemente bajo 1.0f)

if (sample[i] <= -1.25f) 
{ 
    sample[i] = -0.987654f; 
} 
else if (sample[i] >= 1.25f) 
{ 
    sample[i] = 0.987654f; 
} 
else 
{ 
    sample[i] = 1.1f * sample[i] - 0.2f * sample[i] * sample[i] * sample[i]; 
} 

para una tercera waveshapper polinómica (menos suave), sustituya la última línea anterior con:

sample[i]= 1.1f * sample[i]- 0.2f * sample[i] * sample[i] * sample[i]; 
Cuestiones relacionadas