2017-03-17 1 views
-1

J'essaie de dessiner une forme d'onde à partir d'un flux audio .mp3 avec l'algorithme min/max qu'audacity utilise. Cet algorithme calcule les valeurs min et max à partir d'un "bloc" d'échantillons et trace une ligne verticale entre les deux points. Je peux dessiner la forme d'onde de cette façon presque correctement, mais avec quelques erreurs. Voici une image: waveformComment dessiner une forme d'onde avec algorithme min/max correctement? (comme le fait Audacity)

Comme vous pouvez le voir, au début, la forme d'onde se dessine correctement, mais alors des "espaces vides" commencent à apparaître, comme si j'évitais de dessiner quelques lignes. Je ne trouve pas l'erreur dans mon code et viens ici pour trouver de l'aide! voici le code:

/** 
* 
* */ 
private void createWaveform(){ 

    //Array that will contain all the chunks from the audio 
    Array<float[]> chunks = new Array<float[]>(); 
    //the length of the audio in samples 
    int length = audio.getLengthInSamples(); 
    //the amount of samples per pixel. w = screen width 
    samplesPerPixel = length/(int)w; 
    //get all samples 
    float[] samples = audio.getSamples(); 
    //this is strange, but divides the samples in chunks. i can't find other way, better options are welcome 
    int max = samplesPerPixel; 
    int n = 0; 

    for (int i = 0; i < w; i++){  
     float[] chunk = new float[samplesPerPixel]; 
     int k = 0; 
     for (int j = n ; j < max; j++){ 
      chunk[k] = samples[j]; 
      k++; 
     } 
     chunks.add(chunk); 
     n = max; 
     max+=samplesPerPixel; 
    } 

    min_max(chunks); 

} 

/** 
* perform the min/max algorithm of all chunks and creates the lines between points 
* */ 
public void min_max(Array<float[]> chunks){ 
    float max, min; 
    float x = this.getX(); 
    float y = this.getY()+this.h/2; 

    for (int i = 0; i < chunks.size; i++){ 

     max = getMax(chunks.get(i))*(h/2); 
     min = getMin(chunks.get(i))*(h/2); 

     Line l = new Line(new Point(x+i,y+max), new Point(x+i,y+min)); 
     lines.add(l); 
    } 

} 

/** 
* 
* */ 
private void drawLines(ShapeRenderer shapeRenderer){ 

    for (int i = 0 ; i <lines.size; i++) { 
     Line l = lines.get(i); 
     Point p1 = l.getPMin(); 
     Point p2 = l.getPMax(); 
     try { 
      shapeRenderer.line(p1.x, p1.y, p2.x, p2.y); 
     }catch(Exception e){ 
      System.out.println("error"); 
     } 
    } 

} 
+0

J'utilise java et libgdx –

Répondre

1

Si quelqu'un tente de mettre en oeuvre le même algorithme en Java avec Libgdx, je l'ai trouvé une solution. N'utilisez pas ShapeRenderer, utilisez plutôt Pixmaps et le bug disparaitra. Si vous n'utilisez que java ne vous inquiétez pas, l'algorithme du premier post fonctionne très bien, vous avez juste besoin d'adapter certaines choses car vous utilisez probablement swing ou une autre bibliothèque graphique, mais la logique est la même. Résultat final: waveformFixed