Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[34.231.180.210] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте, форумчане!
Возникла проблема.. Записываю речевые сигналы, анализирую их программой(в основном там библиотека MFCC Java) И получаю один и тот же результат: -1 4 -10 6 -1 -1 3 -1 -1 2 -3 0 2 Хотя.. я анализирую целый звуковой файл, возможно поможет деление на кусочки, жаль я не очень это умею)) Но попробуем. Добавлено Записал слова привет и москва, результаты ниже: МОСКВА | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 2 | -3 | 0 | 2 | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 2 | -3 | 0 | 2 | -1 | 5 | -10 | 7 | 0 | -1 | 4 | -1 | 0 | 3 | -2 | 0 | 3 | 0 | 5 | -10 | 5 | -2 | -3 | 0 | -7 | -4 | 1 | -1 | 1 | 1 | 0 | 6 | -9 | 7 | 0 | -2 | 3 | -1 | -1 | 2 | -4 | -2 | 1 | 0 | 3 | -11 | 1 | -4 | 2 | 5 | -1 | 0 | 1 | -5 | -2 | -1 | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 3 | -3 | 0 | 2 ПРИВЕТ | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 2 | -3 | 0 | 2 | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 2 | -3 | 0 | 2 | 0 | 5 | -9 | 8 | 0 | -2 | 2 | 0 | 0 | 3 | -2 | 0 | 3 | 0 | 6 | -8 | 9 | 0 | -3 | 2 | -3 | -3 | 0 | -6 | -3 | 0 | -1 | 4 | -10 | 6 | -1 | -1 | 3 | -1 | -1 | 2 | -3 | 0 | 2 В принципе мне понятно, почему такое творится одинаковые результаты это "тишина" Каждая строчка это 0.25 секунды.Видно что в первом случае я говорил примерно 0.75 секунды, на втором половина секунды oO Но вот почему он читает именно тишину, даю код "чтения", может быть гуру подскажут что он выдает: String PatnToFile = "C:\\test\\music\\05L.wav"; File AudioFile = new File(PatnToFile); ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in; try { audioInputStream = AudioSystem.getAudioInputStream(AudioFile); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } format = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); if (!AudioSystem.isLineSupported(info)) { System.out.println("Error"); } TargetDataLine line = null; try { line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); } catch (LineUnavailableException ex) { System.out.println("Error"); } line.start(); byte[] data = new byte[W * format.getSampleSizeInBits() / BITS_IN_BYTE*2]; double[] inbuf = new double[W/2]; try { in = new BufferedInputStream(new FileInputStream(AudioFile)); int read; while ((read = in.read(data)) > 0) { out.write(data, 0, read); } out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } data = out.toByteArray(); decode(data, inbuf); Где звуковой файл, собс, записанная речь. Добавлено Заранее спасибо за ответы! |
Сообщ.
#2
,
|
|
|
Цитата Но вот почему он читает именно тишину, даю код "чтения", может быть гуру подскажут что он выдает: Что в файле есть, то и читает. Ничего необычного в этом нет Цитата В принципе мне понятно, почему такое творится одинаковые результаты это "тишина" Если в файле нет одинаковых кусков в начале и конце, то одинаковые результаты это не тишина, а ошибка в коде. Чтобы получить помощь по коду,нужно этот код показать. Цитата Каждая строчка это 0.25 секунды Для анализа речи каждая строчка должна быть в 10 раз меньше - 0.025 секунды. |
Сообщ.
#3
,
|
|
|
Уху спасибо nsh! Делал с помощью вот этой библиотеки:
http://code.ohloh.net/file?fid=EQDSocdzPtN...elected=true#L0 Не знаю, авсоь там и есть какая то ошибочка... Цитата nsh @ Для анализа речи каждая строчка должна быть в 10 раз меньше - 0.025 секунды. Ого, это сколько же файлов получится.... Ведь каждый еще и прогнать надо.. Ну не знаю,вроде одинаковых моментов в звуковых файлах нет, просто милисекунды перед началом записи и перед завершением я же молчу)) Вот он это молчание анализирует и выдает одинаковые участки векторов. |
Сообщ.
#4
,
|
|
|
Цитата Не знаю, авсоь там и есть какая то ошибочка... Свой код надо показывать, а не код библиотеки. В библиотеках обычно ошибки есть, но не такие значительные. Ошибки прежде всего в собственном коде нужно искать. Файлы используемые тоже стоит выложить. Цитата Ого, это сколько же файлов получится.... Файлов будет столько же. Строк будет больше. |
Сообщ.
#5
,
|
|
|
Так это и есть весь код) код библиотеки + код в моем первом посте)))
А про файлы я имел в виду, что аюдасити делит когда по промежуткам, создает много файлов, если у меня с 0.25 секунд 6 файлов, то сколько же будет с 0.025... Как это потом анализировать.. Ухх)) В любом случае спасибо вам, nsh, что тяните и помогаете)) Добавлено ОЙ, забыл, там же еще метод декоде: public static void decode(byte[] input, double[] output) { assert input.length == 2 * output.length; for (int i = 0; i < output.length; i++) { output[i] = (short) (((0xFF & input[2 * i + 1]) << 8) | (0xFF & input[2 * i])); output[i] /= Short.MAX_VALUE; } } Вот и все, а потом выводим ответы: inbuf[2] = 10; inbuf[4] = 14; double[] dparameters = mfcc.getParameters(inbuf); System.out.println("MFCC parameters:"); for (int i = 0; i < dparameters.length; i++) { System.out.print(" " + dparameters[i]); } int[] mfccresult = new int[dparameters.length]; for(int i = 0; i < dparameters.length; i++){ mfccresult[i] = (int) dparameters[i]; } for(int i = 0; i < mfccresult.length;i++){ System.out.print(mfccresult[i]); } Это весь код. |
Сообщ.
#6
,
|
|
|
Ну так как,nsh, что посоветуете?)
|
Сообщ.
#7
,
|
|
|
Цитата Ну так как,nsh, что посоветуете?) Пока не видно: 1. Полный код, а не отрывки. Где определена переменная W? где создается объект mfcc? 2. Чистый код. Зачем открывать DataLine для чтения с микрофона, если можно читать из файла? Зачем странные присваивания вроде inbuf[4] = 14? 3. Исходные звуковые файлы Посоветовать что-нибудь сложно |
Сообщ.
#8
,
|
|
|
Цитата nsh @ Зачем странные присваивания вроде inbuf[4] = 14? Вот это уже было... Вот весь код: Часть 1: import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.TargetDataLine; import javax.sound.sampled.UnsupportedAudioFileException; public class mfcc { private static final boolean m_ousePowerInsteadOfMagnitude = false; private final int m_nnumberOfParameters; private final double m_dsamplingFrequency; private final int m_nnumberOfFilters; private final int m_nFFTLength; private final int m_nlifteringCoefficient; private final boolean m_oisLifteringEnabled; private final double m_dminimumFilterOutput = 1.0; private final boolean m_oisZeroThCepstralCoefficientCalculated; private final double m_dlogFilterOutputFloor = 0.0; private int[][] m_nboundariesDFTBins; private double[][] m_dweights; private fftt m_fft; private double[][] m_ddCTMatrix; private double[] m_dfilterOutput; private final double[] m_nlifteringMultiplicationFactor; private final double m_dscalingFactor; //Тип файла private static AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE; private static AudioInputStream audioInputStream; private static AudioFormat format; //Размер массива чтения файла final static int W = 1024; private static int BITS_IN_BYTE = 8; public static void main(String[] args) { int nnumberofFilters = 24; int nlifteringCoefficient = 22; boolean oisLifteringEnabled = true; boolean oisZeroThCepstralCoefficientCalculated = false; int nnumberOfMFCCParameters = 13; //Количество коэфицентов double dsamplingFrequency = 8000.0; int nFFTLength = 512; if (oisZeroThCepstralCoefficientCalculated) { // take in account the zero-th MFCC nnumberOfMFCCParameters = nnumberOfMFCCParameters + 1; } else { nnumberOfMFCCParameters = nnumberOfMFCCParameters; } mfcc mfcc = new mfcc(nnumberOfMFCCParameters, dsamplingFrequency, nnumberofFilters, nFFTLength, oisLifteringEnabled, nlifteringCoefficient, oisZeroThCepstralCoefficientCalculated); System.out.println(mfcc.toString()); //String PatnToFile = "C:\\test\\music\\mix20" + "." + fileType; String PatnToFile = "C:\\test\\music\\05L.wav"; File AudioFile = new File(PatnToFile); ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in; try { audioInputStream = AudioSystem.getAudioInputStream(AudioFile); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } format = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); if (!AudioSystem.isLineSupported(info)) { System.out.println("Error"); } TargetDataLine line = null; try { line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); } catch (LineUnavailableException ex) { System.out.println("Error"); } line.start(); byte[] data = new byte[W * format.getSampleSizeInBits() / BITS_IN_BYTE*2]; double[] inbuf = new double[W/2]; try { in = new BufferedInputStream(new FileInputStream(AudioFile)); int read; while ((read = in.read(data)) > 0) { out.write(data, 0, read); } out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } data = out.toByteArray(); decode(data, inbuf); /* * TEST * TEST * TEST */ //double[] x = new double[160]; inbuf[2] = 10; inbuf[4] = 14; double[] dparameters = mfcc.getParameters(inbuf); System.out.println("MFCC parameters:"); for (int i = 0; i < dparameters.length; i++) { System.out.print(" " + dparameters[i]); } int[] mfccresult = new int[dparameters.length]; for(int i = 0; i < dparameters.length; i++){ mfccresult[i] = (int) dparameters[i]; } System.out.println("====================="); System.out.println("Результаты: "); for(int i = 0; i < mfccresult.length;i++){ System.out.print(" | " + mfccresult[i]); } } /* * Перевод массива байтов в массив типа double * на выходе 2048 значений (по стандарту) */ public static void decode(byte[] input, double[] output) { assert input.length == 2 * output.length; for (int i = 0; i < output.length; i++) { output[i] = (short) (((0xFF & input[2 * i + 1]) << 8) | (0xFF & input[2 * i])); output[i] /= Short.MAX_VALUE; } } public mfcc(int nnumberOfParameters, double dsamplingFrequency, int nnumberofFilters, int nFFTLength, boolean oisLifteringEnabled, int nlifteringCoefficient, boolean oisZeroThCepstralCoefficientCalculated) { m_oisZeroThCepstralCoefficientCalculated = oisZeroThCepstralCoefficientCalculated; if (m_oisZeroThCepstralCoefficientCalculated) { m_nnumberOfParameters = nnumberOfParameters - 1; } else { m_nnumberOfParameters = nnumberOfParameters; } m_dsamplingFrequency = dsamplingFrequency; m_nnumberOfFilters = nnumberofFilters; m_nFFTLength = nFFTLength; calculateMelBasedFilterBank(dsamplingFrequency, nnumberofFilters, nFFTLength); m_fft = new fftt(m_nFFTLength); // initialize FFT initializeDCTMatrix(); m_nlifteringCoefficient = nlifteringCoefficient; m_oisLifteringEnabled = oisLifteringEnabled; m_dfilterOutput = new double[m_nnumberOfFilters]; m_dscalingFactor = Math.sqrt(2.0 / m_nnumberOfFilters); if (m_oisLifteringEnabled) { int nnumberOfCoefficientsToLift = m_nnumberOfParameters; m_nlifteringMultiplicationFactor = new double[m_nlifteringCoefficient]; double dfactor = m_nlifteringCoefficient / 2.0; double dfactor2 = Math.PI / m_nlifteringCoefficient; for (int i = 0; i < m_nlifteringCoefficient; i++) { m_nlifteringMultiplicationFactor[i] = 1.0 + dfactor * Math.sin(dfactor2 * (i + 1)); } if (m_nnumberOfParameters > m_nlifteringCoefficient) { new Error( "Liftering is enabled and the number " + "of parameters = " + m_nnumberOfParameters + ", while " + "the liftering coefficient is " + m_nlifteringCoefficient + ". In this case some cepstrum coefficients would be made " + "equal to zero due to liftering, what does not make much " + "sense in a speech recognition system. You may want to " + "increase the liftering coefficient or decrease the number " + "of MFCC parameters."); } } else { m_nlifteringMultiplicationFactor = null; } } /** Initializes the DCT matrix. */ private void initializeDCTMatrix() { m_ddCTMatrix = new double[m_nnumberOfParameters][m_nnumberOfFilters]; for (int i = 0; i < m_nnumberOfParameters; i++) { for (int j = 0; j < m_nnumberOfFilters; j++) { m_ddCTMatrix[i][j] = Math.cos((i + 1.0) * (j + 1.0 - 0.5) * (Math.PI / m_nnumberOfFilters)); } } } public static double[] convertHzToMel(double[] dhzFrequencies, double dsamplingFrequency) { double[] dmelFrequencies = new double[dhzFrequencies.length]; for (int k = 0; k < dhzFrequencies.length; k++) { dmelFrequencies[k] = 2595.0 * (Math .log(1.0 + (dhzFrequencies[k] / 700.0)) / Math.log(10)); } return dmelFrequencies; } private void calculateMelBasedFilterBank(double dsamplingFrequency, int nnumberofFilters, int nfftLength) { // frequencies for each triangular filter double[][] dfrequenciesInMelScale = new double[nnumberofFilters][3]; // the +1 below is due to the sample of frequency pi (or fs/2) double[] dfftFrequenciesInHz = new double[nfftLength / 2 + 1]; // compute the frequency of each FFT sample (in Hz): double ddeltaFrequency = dsamplingFrequency / nfftLength; for (int i = 0; i < dfftFrequenciesInHz.length; i++) { dfftFrequenciesInHz[i] = i * ddeltaFrequency; } // convert Hz to Mel double[] dfftFrequenciesInMel = this.convertHzToMel( dfftFrequenciesInHz, dsamplingFrequency); // compute the center frequencies. Notice that 2 filters are // "artificially" created in the endpoints of the frequency // scale, correspondent to 0 and fs/2 Hz. double[] dfilterCenterFrequencies = new double[nnumberofFilters + 2]; // implicitly: dfilterCenterFrequencies[0] = 0.0; ddeltaFrequency = dfftFrequenciesInMel[dfftFrequenciesInMel.length - 1] / (nnumberofFilters + 1); for (int i = 1; i < dfilterCenterFrequencies.length; i++) { dfilterCenterFrequencies[i] = i * ddeltaFrequency; } // initialize member variables m_nboundariesDFTBins = new int[m_nnumberOfFilters][2]; m_dweights = new double[m_nnumberOfFilters][]; // notice the loop starts from the filter i=1 because i=0 is the one // centered at DC for (int i = 1; i <= nnumberofFilters; i++) { m_nboundariesDFTBins[i - 1][0] = Integer.MAX_VALUE; // notice the loop below doesn't include the first and last FFT // samples for (int j = 1; j < dfftFrequenciesInMel.length - 1; j++) { // see if frequency j is inside the bandwidth of filter i if ((dfftFrequenciesInMel[j] >= dfilterCenterFrequencies[i - 1]) & (dfftFrequenciesInMel[j] <= dfilterCenterFrequencies[i + 1])) { // the i-1 below is due to the fact that we discard the // first filter i=0 // look for the first DFT sample for this filter if (j < m_nboundariesDFTBins[i - 1][0]) { m_nboundariesDFTBins[i - 1][0] = j; } // look for the last DFT sample for this filter if (j > m_nboundariesDFTBins[i - 1][1]) { m_nboundariesDFTBins[i - 1][1] = j; } } } } // check for consistency. The problem below would happen just // in case of a big number of MFCC parameters for a small DFT length. for (int i = 0; i < nnumberofFilters; i++) { if (m_nboundariesDFTBins[i][0] == m_nboundariesDFTBins[i][1]) { new Error( "Error in MFCC filter bank. In filter " + i + " the first sample is equal to the last sample !" + " Try changing some parameters, for example, decreasing the number of filters."); } } // allocate space for (int i = 0; i < nnumberofFilters; i++) { m_dweights[i] = new double[m_nboundariesDFTBins[i][1] - m_nboundariesDFTBins[i][0] + 1]; } // calculate the weights for (int i = 1; i <= nnumberofFilters; i++) { for (int j = m_nboundariesDFTBins[i - 1][0], k = 0; j <= m_nboundariesDFTBins[i - 1][1]; j++, k++) { if (dfftFrequenciesInMel[j] < dfilterCenterFrequencies[i]) { m_dweights[i - 1][k] = (dfftFrequenciesInMel[j] - dfilterCenterFrequencies[i - 1]) / (dfilterCenterFrequencies[i] - dfilterCenterFrequencies[i - 1]); } else { m_dweights[i - 1][k] = 1.0 - ((dfftFrequenciesInMel[j] - dfilterCenterFrequencies[i]) / (dfilterCenterFrequencies[i + 1] - dfilterCenterFrequencies[i])); } } } } public double[] getParameters(double[] fspeechFrame) { // use mel filter bank for (int i = 0; i < m_nnumberOfFilters; i++) { m_dfilterOutput[i] = 0.0; // Notice that the FFT samples at 0 (DC) and fs/2 are not considered // on this calculation if (m_ousePowerInsteadOfMagnitude) { double[] fpowerSpectrum = m_fft.calculateFFTPower(fspeechFrame); for (int j = m_nboundariesDFTBins[i][0], k = 0; j <= m_nboundariesDFTBins[i][1]; j++, k++) { m_dfilterOutput[i] += fpowerSpectrum[j] * m_dweights[i][k]; } } else { double[] fmagnitudeSpectrum = m_fft .calculateFFTMagnitude(fspeechFrame); for (int j = m_nboundariesDFTBins[i][0], k = 0; j <= m_nboundariesDFTBins[i][1]; j++, k++) { m_dfilterOutput[i] += fmagnitudeSpectrum[j] * m_dweights[i][k]; } } // ISIP (Mississipi univ.) implementation if (m_dfilterOutput[i] > m_dminimumFilterOutput) {// floor power to // avoid log(0) m_dfilterOutput[i] = Math.log(m_dfilterOutput[i]); // using ln } else { m_dfilterOutput[i] = m_dlogFilterOutputFloor; } } double[] dMFCCParameters = null; if (m_oisZeroThCepstralCoefficientCalculated) { dMFCCParameters = new double[m_nnumberOfParameters + 1]; // calculates zero'th cepstral coefficient and pack it // after the MFCC parameters of each frame for the sake // of compatibility with HTK double dzeroThCepstralCoefficient = 0.0; for (int j = 0; j < m_nnumberOfFilters; j++) { dzeroThCepstralCoefficient += m_dfilterOutput[j]; } dzeroThCepstralCoefficient *= m_dscalingFactor; dMFCCParameters[dMFCCParameters.length - 1] = dzeroThCepstralCoefficient; } else { // allocate space dMFCCParameters = new double[m_nnumberOfParameters]; } // cosine transform for (int i = 0; i < m_nnumberOfParameters; i++) { for (int j = 0; j < m_nnumberOfFilters; j++) { dMFCCParameters[i] += m_dfilterOutput[j] * m_ddCTMatrix[i][j]; // the original equations have the first index as 1 } // could potentially incorporate liftering factor and // factor below to save multiplications, but will not // do it for the sake of clarity dMFCCParameters[i] *= m_dscalingFactor; } if (m_oisLifteringEnabled) { for (int i = 0; i < m_nnumberOfParameters; i++) { dMFCCParameters[i] *= m_nlifteringMultiplicationFactor[i]; } } return dMFCCParameters; } // end method /** * Returns the sampling frequency. */ public double getSamplingFrequency() { return this.m_dsamplingFrequency; } /** * Returns the number of points of the Fast Fourier Transform (FFT) used in * the calculation of this MFCC. */ public int getFFTLength() { return m_nFFTLength; } /** * Returns the number of MFCC coefficients, including the 0-th if required * by user in the object construction. */ public int getNumberOfCoefficients() { return (m_oisZeroThCepstralCoefficientCalculated ? (m_nnumberOfParameters + 1) : m_nnumberOfParameters); } /** * Return a string with all important parameters of this object. */ public String toString() { return "MFCC.nnumberOfParameters = " + (m_oisZeroThCepstralCoefficientCalculated ? (m_nnumberOfParameters + 1) : m_nnumberOfParameters) + "\n" + "MFCC.nnumberOfFilters = " + m_nnumberOfFilters + "\n" + "MFCC.nFFTLength = " + m_nFFTLength + "\n" + "MFCC.dsamplingFrequency = " + m_dsamplingFrequency + "\n" + "MFCC.nlifteringCoefficient = " + m_nlifteringCoefficient + "\n" + "MFCC.oisLifteringEnabled = " + m_oisLifteringEnabled + "\n" + "MFCC.oisZeroThCepstralCoefficientCalculated = " + m_oisZeroThCepstralCoefficientCalculated; } public double[] getFilterBankOutputs(double[] fspeechFrame) { double dfilterOutput[] = new double[m_nnumberOfFilters]; for (int i = 0; i < m_nnumberOfFilters; i++) { if (m_ousePowerInsteadOfMagnitude) { double[] fpowerSpectrum = m_fft.calculateFFTPower(fspeechFrame); for (int j = m_nboundariesDFTBins[i][0], k = 0; j <= m_nboundariesDFTBins[i][1]; j++, k++) { dfilterOutput[i] += fpowerSpectrum[j] * m_dweights[i][k]; } } else { double[] fmagnitudeSpectrum = m_fft .calculateFFTMagnitude(fspeechFrame); for (int j = m_nboundariesDFTBins[i][0], k = 0; j <= m_nboundariesDFTBins[i][1]; j++, k++) { dfilterOutput[i] += fmagnitudeSpectrum[j] * m_dweights[i][k]; } } if (dfilterOutput[i] > m_dminimumFilterOutput) {// floor power to // avoid log(0) dfilterOutput[i] = Math.log(dfilterOutput[i]); // using ln } else { dfilterOutput[i] = m_dlogFilterOutputFloor; } } return dfilterOutput; } } Вторая часть тут: http://pastebin.com/sR52wqYR Не знаю, думал так правильнее будет с помощью ДатаЛайна... Звуковых файлов особо и нет) Вот пример файла, могу еще выложить многа многа файлов которые аюдасити получил из этого, когда делил на 0.25 секунд. Спасибо вам! Прикреплённый файлmix21.WAVE (56,04 Кбайт, скачиваний: 394) Добавлено У меня нет нормального микрофона, честно говоря )) так что подумывал где бы взять хотя бы пару словечек в WAVE формате... |
Сообщ.
#9
,
|
|
|
Размер окна 1024, а должен быть 320
double dsamplingFrequency в программе 8000.0, а файлы у Вас в 16khz На окна звук нужно в программе резать, а не в audacity dataline не нужен, его можно убрать Программу лучше выкладывать в архиве, чтобы её запустить можно было, а не вставлять в два разных места сразу Mel коэффициенты не надо к int приводить, они должны быть с плавающей точностью Свой код лучше писать не внутри чужого, а в отдельных файлах. Тогда понятнее будет, где искать ошибку. Попробуйте хотя бы какие-то замечания исправить сначала |
Сообщ.
#10
,
|
|
|
Цитата nsh @ Размер окна 1024, а должен быть 320 double dsamplingFrequency в программе 8000.0, а файлы у Вас в 16khz На окна звук нужно в программе резать, а не в audacity dataline не нужен, его можно убрать Программу лучше выкладывать в архиве, чтобы её запустить можно было, а не вставлять в два разных места сразу Mel коэффициенты не надо к int приводить, они должны быть с плавающей точностью Свой код лучше писать не внутри чужого, а в отдельных файлах. Тогда понятнее будет, где искать ошибку. Попробуйте хотя бы какие-то замечания исправить сначала Исправил размер окна, а почему 320?) Пока программно звук резать не умею, вообще как?) Может разделить прочитанные байты из него? на равные участки.. Про мелы пока не вижу что-то.. Спасибо вам, что помогаете! |
Сообщ.
#11
,
|
|
|
Или вы имели в виду вывод самого результата в double сделать?)
|
Сообщ.
#12
,
|
|
|
Хорошо, как что-нибудь получите, выкладывайте обновлённый код и результаты.
По поводу нарезки на окна в коде, это можно делать так: ArrayList<float[]> frames = new ArrayList<float[]>(); for (int i = 0; i < data.length; i = i + frame_shift) { float[] frame = new float[frame_size]; System.arraycopy(data, i, frame, 0, frame_size); frames.append(frame); } |
Сообщ.
#13
,
|
|
|
Уху, спасибки нш! А можно , пожалуйста, уточнить что где в коде, получается перевод в double не нужен уже что ли? А на сколько окон будет нарезка?)
Как бы не было стыка величин байты с флотами и т д... |
Сообщ.
#14
,
|
|
|
Просто у вас там величины их свои брать или из формата добывать?:
System.out.println("=====Info====="); System.out.println(format.getFrameSize()); double sampleSize = format.getSampleSizeInBits()/8; double FramesCount = data.length / (sampleSize*format.getChannels()); System.out.println(FramesCount); |
Сообщ.
#15
,
|
|
|
> там величины их свои брать или из формата добывать
frame size 410 отсчетов frame shift 320 отсчетов fft size 512 sample rate 16000 Добавлено А вообще лучше более разумную библиотеку взять, например CMUSphinx http://cmusphinx.sourceforge.net/wiki/sphinx4. Код для извлечения MFCC в sphinx4/edu/cmu/sphinx/tools/feature/FeatureFileDumper.java. В этом спантусе классов много, а толку от них мало. Видимо, автор перечитал книгу о шаблонах проектирования и наделал кучу сервисов, фасадов и прочего. |
Сообщ.
#16
,
|
|
|
Спасибо! Да уж попробую на этой пока сделать...
Почему то подчеркивает вот эту строчку: frames.append(frame); А именно append. Кстати начал получать совсем другие результаты, после ваших советов, попробую сегодня еще записать пару словечек и выложу результаты) |
Сообщ.
#17
,
|
|
|
Провел небольшой тест, все снова плохо...
Раньше я получал вот этот результат для всего: -1 4 -10 6 -1 -1 3 -1 -1 2 -3 0 2 а теперь вот этот получаю: -3 1 -9 8 -5 1 0 -3 1 -1 -1 2 -2 Или вот в таком виде: Какие бы слова не записывал, вот такой результат... -3.4991932068498093 1.9694426457336287 -9.273643571223644 8.99255184947278 -5.435321526906497 1.5855738872936378 0.984217953196569 -3.502277131398279 1.8184110813882457 -1.4623570085484268 -1.1914909785382624 2.6995256102639735 -2.9756843183744692 Вот участок кода, который я обновил: final static int W = 320; // Размер окна, как я понял! [ИЗМЕНЕНИЕ] private static int BITS_IN_BYTE = 8; public static void main(String[] args) { int nnumberofFilters = 24; int nlifteringCoefficient = 22; boolean oisLifteringEnabled = true; boolean oisZeroThCepstralCoefficientCalculated = false; int nnumberOfMFCCParameters = 13; double dsamplingFrequency = 16000.0; // Сделал 16000 [ИЗМЕНЕНИЕ] int nFFTLength = 512; if (oisZeroThCepstralCoefficientCalculated) { // take in account the zero-th MFCC nnumberOfMFCCParameters = nnumberOfMFCCParameters + 1; } else { nnumberOfMFCCParameters = nnumberOfMFCCParameters; } mfcc mfcc = new mfcc(nnumberOfMFCCParameters, dsamplingFrequency, nnumberofFilters, nFFTLength, oisLifteringEnabled, nlifteringCoefficient, oisZeroThCepstralCoefficientCalculated); System.out.println(mfcc.toString()); String PatnToFile = "C:\\test\\hello1." + fileType; File AudioFile = new File(PatnToFile); ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in; try { audioInputStream = AudioSystem.getAudioInputStream(AudioFile); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } format = audioInputStream.getFormat(); byte[] data = new byte[W * format.getSampleSizeInBits() / BITS_IN_BYTE*2]; double[] inbuf = new double[W/2]; try { in = new BufferedInputStream(new FileInputStream(AudioFile)); int read; while ((read = in.read(data)) > 0) { out.write(data, 0, read); } out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } data = out.toByteArray(); decode(data, inbuf); inbuf[2] = 10; inbuf[4] = 14; double[] dparameters = mfcc.getParameters(inbuf); System.out.println("MFCC parameters:"); for (int i = 0; i < dparameters.length; i++) { System.out.print(" " + dparameters[i]); } int[] mfccresult = new int[dparameters.length]; for(int i = 0; i < dparameters.length; i++){ mfccresult[i] = (int) dparameters[i]; } for(int i = 0; i < mfccresult.length;i++){ System.out.print(mfccresult[i]); } } Также убрал ДатаЛайн, пока все)) Добавлено Все же надо прямо в программе все делить... Может заменить эту строчку frames.append(frame); На эту надо? Или как... frames.add(frame); Добавлено Выдает ошибку такую кстати: Exception in thread "main" java.lang.ArrayStoreException Ну и с аппендом: The method append(float[]) is undefined for the type ArrayList<float[]> |
Сообщ.
#18
,
|
|
|
Уважаемый MrKor. Чтобы получить совет, нужно поработать самому немного. Руками и мозгом. Не ожидайте, что кто-то будет разгребать кашу в Вашей голове.
Как я уже писал, не нужно выкладывать программу по частям. Части не собираются в полную картину. Доступа на Ваш компьютер у меня нет, в ФСБ я не работаю, мои штатные телепаты в отпуске. Пока вы не выложите программу целиком в полном удобном виде, тяжело Вам подсказать, что у Вас на компьютере происходит. Цитата Выдает ошибку такую кстати: Exception in thread "main" java.lang.ArrayStoreException Если выдаётся ошибка, стоит задуматься о её причинах, попытаться понять, почему ошибка возникает, попробовать исправить ситуацию самому. Обычно такие ошибки легко решаются, если чуть-чуть пошевелить мозгами. Решение таких ошибок - основная часть работы программиста, ей нужно учиться. |
Сообщ.
#19
,
|
|
|
Вот и архивчик:
Прикреплённый файлSoundeD.rar (23,88 Кбайт, скачиваний: 134) Надеюсь так будет лучше, example файл там для тестов... Добавлено Попробовал решить вот так вот: import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.TargetDataLine; import javax.sound.sampled.UnsupportedAudioFileException; public class example { private static AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE; private static AudioInputStream audioInputStream; private static AudioFormat format; final static int W = 1024; private static int BITS_IN_BYTE = 8; public static void main(String[] args) { String PatnToFile = "C:\\test\\mix20" + "." + fileType; File AudioFile = new File(PatnToFile); ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in; try { audioInputStream = AudioSystem.getAudioInputStream(AudioFile); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } format = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); if (!AudioSystem.isLineSupported(info)) { System.out.println("Error"); } TargetDataLine line = null; try { line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); } catch (LineUnavailableException ex) { System.out.println("Error"); } line.start(); byte[] data = new byte[W * format.getSampleSizeInBits() / BITS_IN_BYTE * 2]; try { in = new BufferedInputStream(new FileInputStream(AudioFile)); int read; while ((read = in.read(data)) > 0) { out.write(data, 0, read); } out.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } data = out.toByteArray(); double[] inbuf = new double[W/2]; decode(data, inbuf); int frame_shift = 320; int frame_size = 410; ArrayList<float[]> frames = new ArrayList<float[]>(); for (int i = 0; i < inbuf.length; i = i + frame_shift) { float[] frame = new float[frame_size]; System.arraycopy(inbuf, i, frame, 0, frame_size); //frames.append(frame); } } public static void decode(byte[] input, double[] output) { assert input.length == 2 * output.length; for (int i = 0; i < output.length; i++) { output[i] = (short) (((0xFF & input[2 * i + 1]) << 8) | (0xFF & input[2 * i])); output[i] /= Short.MAX_VALUE; } } } Все равно вылезает эта чортова ошибка... Добавлено Я думал там был стык байтов с дублями, а оказалось в другом проблемка... |
Сообщ.
#20
,
|
|
|
Почти написал программку делящую файл на равные кусочки) Завтра выложу!
|
Сообщ.
#21
,
|
|
|
ПамПамПам!)
Вот и программка, поддерживает звукозаписи до 2.25 секунд(можно увеличить), что мне как раз подходит, ибо больше мне пока не надо) Файлик прикрепил, завтра попробую соединить все вместе и провести маленькие тесты) Думаю, nsh, вы покруче меня шарите в программной части, поделитесь, пожалуйста! Какие недостатки есть сейчас. Прикреплённый файлexample.java (4,02 Кбайт, скачиваний: 199) Добавлено Её можно улучшить в сотни раз..Чем я и займусь, надо все это сделать автоматом..Чтобы только время можно было вводить, а она тебе массивы отдавала бы)) |
Сообщ.
#22
,
|
|
|
Цитата Прикреплённый файл: SoundeD.rar (23,88 Кбайт, скачиваний: 2) Уже лучше Если Вы прочитаете документацию по ArrayStoreException, Вам станет понятно, что причиной ошибки является попытка поместить элемент в массив несовместимого типа. В Вашем случае Вы пытаетесь скопировать из массива типа byte в массив типа float. ТАк нельзя делать. Сначала нужно преобразовать сигнал в вид float, это Вы уже делали. Потом разбивать на окна. Вы этап преобразования пропустили. Если Eclipse подчеркивает метод add, это означает, что такой метод отсутствует. Нужно поискать похожий метод, для класса ArrayList это append. |
Сообщ.
#23
,
|
|
|
Цитата nsh @ Сначала нужно преобразовать сигнал в вид float, это Вы уже делали. Потом разбивать на окна. Вы этап преобразования пропустили. Аааааа, а я думал сначала разделить, а потом уже делать.Спасибки! Попробую сейчас! |
Сообщ.
#24
,
|
|
|
Попробовал еще раз все сделать, прикрепил в архивчике кодец.
Прикреплённый файлSoundeD.rar (23,66 Кбайт, скачиваний: 124)
Опять ошибка, теперь ошибка java.lang.ArrayIndexOutOfBoundsException, то бишь не существующий элемент массива... УЖ не знаю что там и как, разделял frame_size frame_shift на два, все равно не помогло... Преобразование сделал.Метод add не подчеркивает, а метод append подчеркивает. Кстати, если что у меня Java 6, может быть какие-то проблемы могут и из-за этого возникнуть... Попробую исправить Добавлено Кстати, когда я преобразование сделал, то размер основного массива в 8 раз уменьшился.. Может стоит изменить размеры переменных? ( frame_size frame_shift ) Разделение этих переменных ( 410 и 320) на 8 не помагает.. |
Сообщ.
#25
,
|
|
|
А вот если 256 подставить, как значение двум переменных, то все работает!)
|
Сообщ.
#26
,
|
|
|
Чтобы не возникало выхода за границы в цикле должно быть такое ограничение:
for (int i = 0; i + frame_size < inbuf.length; i = i + frame_shift) вместо for (int i = 0; i < inbuf.length; i = i + frame_shift) |
Сообщ.
#27
,
|
|
|
Спасибо!
Числа я оставил те же: int frame_size = 410; int frame_shift = 320; Только вот проблемка, если вы смотрели код, то могли видеть, что длина inbuf = 512... После деления на окна у меня создается 1 массив.Так что не знаю...По сути это же тоже самое, что и без этого деления на окна,может ч=стоит где то что то поменять? например, числа..Просто если массив inbuf делать больше, чем 512, то вылезает куча ошибок в MFCC.. |
Сообщ.
#28
,
|
|
|
Цитата могли видеть, что длина inbuf = 512... После деления на окна у меня создается 1 массив.Так что не знаю... Когда декодируете длина полученного результата должна определяться из длины прочитанных данных, а не жёстко задаваться. |
Сообщ.
#29
,
|
|
|
Так тут без задавания - никак, мы же массив создаем:
double[] inbuf = new double[size]; Где size , собс-но, его длинна... Добавлено Хотя, мы же можем поставить длинну такую же, какую имеет начальный массив байт, мы же все потом все равно поделим! Добавлено Уже проверил, кстати, с длинной, как у начального массива, все отлично работает! И деление происходит. |
Сообщ.
#30
,
|
|
|
Вот такие результаты получаю:
| -3.4991926718054214 | 1.9694437093558208 | -9.273642067864989 | 8.992553509896249 | -5.435318907995241 | 1.5855762086177776 | 0.9842192881737314 | -3.502275544221704 | 1.818413705659863 | -1.4623546239919465 | -1.191487821368453 | 2.6995279299149963 | -2.975681484559656 | 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.6564014681664422 | 0.7802389891166934 | -0.5337068124193423 | -0.06493042991671547 | 0.8677194640315364 | -1.6509748044712116 | 2.19500447203845 | -2.3579418212099754 | 2.1163660589417583 | -1.5606290284132405 | 0.8517246308393844 | -0.16080061139311216 | -0.38363003286907366 Это из одного файла.Что то сбой чую я во втором массиве... Чуть позже выложу код, если необходимо. Добавлено Построил график в каком то гугло сервисе, вот что получилось, примерно: http://imgur.com/Q3uCo6T Небольшие сходства есть, если приглядеться ко второй и третьей части графика... Вот векторы к этому графику: | -3.4991926718054214 | 1.9694437093558208 | -9.273642067864989 | 8.992553509896249 | -5.435318907995241 | 1.5855762086177776 | 0.9842192881737314 | -3.502275544221704|1.818413705659863|-1.462354623991946|-1.19148782136845| 2.6995279299149963 | -2.975681484559656 | 1.5043523440403215 | 2.344562533745208 | 3.0548060948902296 | 3.5893221734407432 | 3.9176900825769265 | 4.027299370480302 | 3.9240151371497727 | 3.6309938207747043 | 3.1858045418955365 | 2.636192420068367 | 2.034962909112171 | 1.4345544043083465 | 0.8818906236179873 | 2.0998034007168607 | 1.492814403340775 | 3.3858159393738045 | 2.8549893292179402 | 1.9577773064511086 | 0.06261290082420551 | -1.2570835235662836 | -1.1431390040840532 | 0.42541655948905943 | 0.45563912379060556 | 1.2673896378430856 | 0.38270850481087354 | - 0.7609497682647048 |
Сообщ.
#31
,
|
|
|
Сообщ.
#32
,
|
|
|
Дальше надо остальной код писать. В чем проблема-то?
|
Сообщ.
#33
,
|
|
|
Просто хотелось узнать, а сейчас там все в порядке?)
Остальной код, напишу, уже придумал кое чего. |
Сообщ.
#34
,
|
|
|
Кстати, nsh, что думаете о системе многократного сравнивания, скажем так.
Допустим, имеется звуковой файл "Привет.wav" Анализируем его, получаем набор MFCC векторов по всему файлу, сравниваем с эталоном, если неудачно, делим на несколько частей, опять сравниваем с эталоном, если и опять нет, то делим еще и сравниваем уже с эталонами букв. Какие минусы такой системы?) Наверняка будет долго работать, но все же) |
Сообщ.
#35
,
|
|
|
Цитата Анализируем его, получаем набор MFCC векторов по всему файлу, сравниваем с эталоном, если неудачно, делим на несколько частей, опять сравниваем с эталоном, если и опять нет, то делим еще и сравниваем уже с эталонами букв. Какие минусы такой системы?) Да вроде нет минусов. Работать должно неплохо. |