2010-10-25 4 views
1

Je veux mélanger plusieurs échantillons ULAW en Java. Y at-il un moyen de le faire sans convertir en PCM? Im essayant de faire une application VoIP 8000Hz 8bit. Je suis en train de tester avec des fichiers AU (créés dans goldwave) car ils utilisent le codage ULAW. Mon implémentation actuelle est:Quelle est la manière la plus simple de mixer des échantillons PCM_ULAW 8 bits 8000Hz?

[code]

AudioFormat f = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 16, 1, 2, 8000, false); 
    SourceDataLine sdl = AudioSystem.getSourceDataLine(f); 
    sdl.open(f); 
    sdl.start(); 

    File file1 = new File("C:\\Scream3.au"); 
    AudioInputStream ais1 = AudioSystem.getAudioInputStream(file1); 
    AudioInputStream aisTarget1 = AudioSystem.getAudioInputStream(f, ais1); 

    File file2 = new File("C:\\Blackout3.au"); 
    AudioInputStream ais2 = AudioSystem.getAudioInputStream(file2); 
    AudioInputStream aisTarget2 = AudioSystem.getAudioInputStream(f, ais2); 

    byte[] data = new byte[10000]; 
    int[] calc = new int[5000]; 
    AudioInputStream[] streams = {aisTarget1, aisTarget2}; 
    int count = streams.length + 1; 
    while (true) { 
     int r = -1; 
     for (int i = 0; i < streams.length; i++) { 
      r = streams[i].read(data, 0, data.length); 
      if (r == -1) break; 
      for (int j = 0; j < calc.length; j++) { 
       int tempVal = ((data[j * 2 + 1] << 8) | (data[j * 2] & 0xFF)); 
       calc[j] += tempVal; 
      } 
     } 
     for (int i = 0; i < calc.length; i++) { 
      calc[i] /= count; 
      data[i * 2 + 0] = (byte) (calc[i] & 0xFF); 
      data[i * 2 + 1] = (byte) (calc[i] >> 8); 
     } 
     if (r == -1) break; 
     sdl.write(data, 0, data.length); 
    } 

[/ code]

Si ce ne est pas possible de mélanger les échantillons de ULAW directement et je dois convertir en PCM, comment puis-je convertir de Format PCM (AudioFormat.Encoding.PCM_SIGNED, 8000 Hz, 16 bits, 1 canal, taille de trame de 2 octets, fréquence d'images de 8000, peu d'endian) à ULAW (8bit 8000Hz).

Est-ce que je fais quelque chose comme: 1) Ecrire un en-tête WAVE à un flux d'octets 2) Ecrire les données PCM au flux d'octets 3) Obtenez PCM AIS avec AudioSystem.getAudioInputStream (de flux d'octets) 4) Inscrivez-vous ULAW Target AIS avec AudioSystem.getAudioInputStream (ulawFormat, PCM AIS)

Toute aide est appréciée.

EDIT: Essayer de convertir les mu-law PCM (Tenter d'utiliser l'équation de http://en.wikipedia.org/wiki/Ulaw):

[CODE]

AudioFormat f = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 8000, 8, 1, 1, 8000, false); 
    SourceDataLine sdl = AudioSystem.getSourceDataLine(f); 
    sdl.open(f); 
    sdl.start(); 
    File file1 = new File("C:\\scream3.au"); 
    FileInputStream fis = new FileInputStream(file1); 
    // Skip header 
    fis.skip(24); 
    byte[] data = new byte[8196]; 

    while (true) { 
     int r = fis.read(data, 0, data.length); 
     if (r == -1) break; 
     for (int i = 0; i < r; i++) { 
      float y = ((float) data[i]/Byte.MAX_VALUE); 
      float sample = -1.0f * (float) (Math.signum(y) * (1.0f/255.0f) * (Math.pow(1 + 255, Math.abs(y)) - 1.0f)); 
      data[i] = (byte) (sample * Byte.MAX_VALUE); 
     } 
     sdl.write(data, 0, data.length); 
    } 
    sdl.drain(); 
    sdl.stop(); 
    sdl.close(); 
    fis.close(); 

[/ CODE]

Répondre

1

je convertir de/à codage linéaire à la main, un échantillon à la fois, en utilisant les formules de Wikipedia:μ-law algorithm.

code Exemple (basé sur le code OP):

float sample1 = Math.signum(y1)/255.0*(Math.pow(256, Math.abs(y1))-1); 
float sample2 = Math.signum(y2)/255.0*(Math.pow(256, Math.abs(y2))-1); 
float combined = somethig * sample1 + (1-something) * sample2; 
float result = Math.signum(combined)*Math.log(1+255*Math.abs(combined))/Math.log(256); 
+0

Merci pour la réponse! Im essayant de faire ceci, malheureusement je ne suis pas si bon en maths. Peux-tu m'aider? – Xiphias3

+0

Comment est-ce que ce n'est pas la même chose que la conversion en PCM et retour? – Gabe

+0

@Gabe: Il est le même. Je veux juste dire que vous n'avez pas besoin d'écrire des en-têtes, d'utiliser des flux d'octets et ainsi de suite. –

Questions connexes