如何减少Java中振幅数组的大小?

时间:2018-08-16 16:16:48

标签: java audio javafx wav amplitude

  

在网上搜索了数周,我来到了以下代码   计算Java中给定.wav文件的幅度。现在   问题是它无法像大型音频文件那样很好地扩展   假设30分钟,生产数组很大。

要绘制它,我使用的是JavaFX created this repository(ps的代码可能会有所不同,因为我现在有几天没提交)。

所以:

/**                                                                                                                             
 * Get Wav Amplitudes                                                                                                           
 *                                                                                                                              
 * @param file                                                                                                                  
 * @return                                                                                                                      
 * @throws UnsupportedAudioFileException                                                                                        
 * @throws IOException                                                                                                          
 */                                                                                                                             
private int[] getWavAmplitudes(File file) throws UnsupportedAudioFileException , IOException {                                  
    System.out.println("Calculting WAV amplitudes");                                                                            
    int[] amplitudes = null;                                                                                                    

    //Get Audio input stream                                                                                                    
    try (AudioInputStream input = AudioSystem.getAudioInputStream(file)) {                                                      
        AudioFormat baseFormat = input.getFormat();                                                                             

        Encoding encoding = AudioFormat.Encoding.PCM_UNSIGNED;                                                                  
        float sampleRate = baseFormat.getSampleRate();                                                                          
        int numChannels = baseFormat.getChannels();                                                                             

        AudioFormat decodedFormat = new AudioFormat(encoding, sampleRate, 16, numChannels, numChannels * 2, sampleRate, false); 
        int available = input.available();                                                                                      
        amplitudes = new int[available];                                                                                        

        //Get the PCM Decoded Audio Input Stream                                                                                
        try (AudioInputStream pcmDecodedInput = AudioSystem.getAudioInputStream(decodedFormat, input)) {                        
            final int BUFFER_SIZE = 4096; //this is actually bytes                                                              
            System.out.println(available);                                                                                      

            //Create a buffer                                                                                                   
            byte[] buffer = new byte[BUFFER_SIZE];                                                                              

            //Read all the available data on chunks                                                                             
            int counter = 0;                                                                                                    
            while (pcmDecodedInput.readNBytes(buffer, 0, BUFFER_SIZE) > 0)                                                      
                for (int i = 0; i < buffer.length - 1; i += 2, counter += 2) {                                                  
                    if (counter == available)                                                                                   
                        break;                                                                                                  
                    amplitudes[counter] = ( ( buffer[i + 1] << 8 ) | buffer[i] & 0xff ) << 16;                                  
                    amplitudes[counter] /= 32767;                                                                               
                    amplitudes[counter] *= WAVEFORM_HEIGHT_COEFFICIENT;                                                         
                }                                                                                                               
        } catch (Exception ex) {                                                                                                
            ex.printStackTrace();                                                                                               
        }                                                                                                                       
    } catch (Exception ex) {                                                                                                    
        ex.printStackTrace();                                                                                                   
    }                                                                                                                           

    //System.out.println("Finished Calculting amplitudes");                                                                     
    return amplitudes;                                                                                                          
}   

然后我像这样处理振幅:

/**                                                                 
 * Process the amplitudes                                           
 *                                                                  
 * @param sourcePcmData                                             
 * @return An array with amplitudes                                 
 */                                                                 
private float[] processAmplitudes(int[] sourcePcmData) {            
    System.out.println("Processing WAV amplitudes");                

    //The width of the resulting waveform panel                     
    int width = waveVisualization.width;                            
    System.out.println("P Width :" + width);                        
    float[] waveData = new float[width];                            
    int samplesPerPixel = sourcePcmData.length / width;             

    //Calculate                                                     
    float nValue;                                                   
    for (int w = 0; w < width; w++) {                               
        //if (isCancelled())                                        
        //  break;                                                  

        //For performance keep it here                              
        int c = w * samplesPerPixel;                                
        nValue = 0.0f;                                              

        //Keep going                                                
        for (int s = 0; s < samplesPerPixel; s++) {                 
            //if (isCancelled())                                    
            //  break;                                              
            nValue += ( Math.abs(sourcePcmData[c + s]) / 65536.0f );
        }                                                           

        //Set WaveData                                              
        waveData[w] = nValue / samplesPerPixel;                     
    }                                                               

    System.out.println("Finished Processing amplitudes");           
    return waveData;                                                
}     

输出是这样的:

enter image description here

1 个答案:

答案 0 :(得分:1)

找到了一个非常好的解决方案,尽管我不确定最终数组的最大大小应该是多少,经过一些实验@receiver(post_save, sender= ww_manholes) def copy_id(sender, **kwargs): data = ww_manholes.objects.get(id=kwargs.get('instance').id) data.no_man = data.id data.save() 似乎是一个很好的数字。

所有代码都在this github存储库中。

因此方法 getWavAmplitudes 变为:

100.000

非常欢迎任何建议和改进。