Почему Java и MATLAB создают разные массивы из одного и того же файла WAV? - PullRequest
0 голосов
/ 05 июня 2019

Я использую код Java, который читает файл sample.wav (с 2 каналами) и сохраняет каждый канал в формате yy [] [].

public class zoom {

    public static void main(String[] args) throws IOException, WavFileException {
        // TODO Auto-generated method stub

        try {
            File a_file = new File("src/sample.wav");
            WavFile read_raw = WavFile.openWavFile(a_file);
           AudioSampleReader sampleReader = new AudioSampleReader(a_file);
           AudioFormat format = sampleReader.getFormat();
           long nbSamples = sampleReader.getSampleCount();
           int numFrames = (int) read_raw.getNumFrames();
           int numChannels = read_raw.getNumChannels();
           double[] y = new double[numChannels*(int)nbSamples];
           sampleReader.getInterleavedSamples(0, nbSamples, y,16);


           double[][] yy = new double[numChannels][numFrames];
           for(int i =0;i< numChannels*numFrames; i++)
            yy[i%numChannels][i/numChannels] = y[i];

            long fs = read_raw.getSampleRate();  

            GJ method = new GJ(yy[0], yy[1], (int)fs);
            double[] samples = method.run();


          for(int i=0;i<samples.length;i++)
            yy[i%numChannels][i/numChannels] = samples[i];


          File outFile = new File("trial_check.wav");
          WavFile wavFile = WavFile.newWavFile(outFile, 2, numFrames,16, (long) format.getSampleRate());
          wavFile.writeFrames(yy, numFrames);


            } catch (UnsupportedAudioFileException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }

      System.out.println("completed");

    }

}
public void getInterleavedSamples(long begin, long end,
                                      double[] samples, int bit_len) throws IOException,
            IllegalArgumentException {
        long nbSamples = end - begin;
        // nbBytes = nbSamples * sampleSizeinByte * nbChannels
        long nbBytes = nbSamples * (format.getSampleSizeInBits() / bit_len) *
                format.getChannels();
        if (nbBytes > Integer.MAX_VALUE)
            throw new IllegalArgumentException("too many samples");
        // allocate a byte buffer
        byte[] inBuffer = new byte[(int)nbBytes];
        // read bytes from audio file
        audioInputStream.read(inBuffer, 0, inBuffer.length);
        // decode bytes into samples. Supported encodings are:
        // PCM-SIGNED, PCM-UNSIGNED, A-LAW, U-LAW
        decodeBytes(inBuffer, samples,16);
    }
private void decodeBytes(byte[] audioBytes, double[] audioSamples,int bit_len) {
        int sampleSizeInBytes = format.getSampleSizeInBits() / bit_len;
        int[] sampleBytes = new int[sampleSizeInBytes];
        int k = 0; // index in audioBytes
        for (int i = 0; i < audioSamples.length; i++) {
            // collect sample byte in big-endian order
            if (format.isBigEndian()) {
                // bytes start with MSB
                for (int j = 0; j < sampleSizeInBytes; j++) {
                    sampleBytes[j] = audioBytes[k++];
                }
            } else {
                // bytes start with LSB
                for (int j = sampleSizeInBytes - 1; j >= 0; j--) {
                    sampleBytes[j] = audioBytes[k++];
                    if (sampleBytes[j] != 0)
                        j = j + 0;
                }
            }
            // get integer value from bytes
            int ival = 0;
            for (int j = 0; j < sampleSizeInBytes; j++) {
                ival += sampleBytes[j];
                if (j < sampleSizeInBytes - 1) ival <<= bit_len;
            }
            // decode value
            double ratio = Math.pow(2., format.getSampleSizeInBits() - 1);
            double val = ((double) ival) / ratio;
            audioSamples[i] = val;
        }
    }

вывод для yy [0] [] в java равен

0.0, 0.0, 0.0, 0.0, 1.52587890625E-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.8310546875E-4...

В то время как в MATLAB (simple audioread ()) равен

0,0,1.52e-04,0,0,0,0,0,0,0,-1.83e-04

Если изменить его на 8-битный yy [0] [] совершенно другой

0.0, 0.0, 1.52587890625E-4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00799560546875,

Вывод Java для 16 битов в порядке, но интервал между значениями необычен.Если кто-то скажет мне, как правильно задать интервал или, по крайней мере, форму yy [] [], это было бы очень полезно.

...