تحويل int موقعة (2Bytes ، 16 بت) بتنسيق مزدوج. مع جافا

StackOverflow https://stackoverflow.com/questions/4616310

سؤال

لدي مشكلة. في Java ، أحتاج إلى قراءة العينات من ملف WAV. تنسيق الملف هو: wav ، pcm_signed ، int int of 2bytes = 16bits ، Little Endian ... يقرأ الكائن عينات الصوت بالبايت وأحتاج إلى تحويل هذه البايتات في قيمة مزدوجة واحدة. حاولت استخدام هذه الصيغة ولكنها غير صحيحة تمامًا:

mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8));

مقارنة النتائج مع MATLAB ، ألاحظ دائمًا الاختلافات بين القيمة الحقيقية في MATLAB والمعدل في Java. هل يمكن لأي شخص مساعدتي رجاءا؟ شكرا لك ديف

هل كانت مفيدة؟

المحلول

لم تقدم لنا معلومات كافية لمعرفة سبب حصولك على نتائج مختلفة في Matlab و Java. عادةً ما تقوم بتوسيع نطاق بيانات القناة القصيرة [-32768..32767] إلى مضاعفة في النطاق [-1..1] والتي يبدو أنك تحاول القيام بها. نتيجة Java الخاصة بك: -3.0517578125E -5 صحيحة بالنسبة للقيمة القصيرة -1: -1/32768. لا أعرف لماذا تختلف نتيجة MATLAB الخاصة بك. لم تظهر لنا كيف تصل إلى نتائج MATLAB الخاصة بك.

إذا كان لديك سلسلة كبيرة من البايتات (التي أظن أنك تفعلها) ، ولا تريد أن تقلق بشأن البتات الكبرى مقابل البتات الصغيرة أو المتغيرة ، فليتم الاعتناء بها من أجلك:

import java.nio.*;
...
ByteBuffer buf = ByteBuffer.wrap(audioBytes);
buf.order(ByteOrder.LITTLE_ENDIAN);

while (buf.remaining() >= 2) {
    short s = buf.getShort();
    double mono = (double) s;
    double mono_norm = mono / 32768.0;
    ...
}

bytebuffer.getshort () يقرأ البايتين التاليين من المخزن المؤقت ، ويعتني بالطلب الصغير ، ويحول البايتات إلى قصيرة ، ويوضع نفسه لمكالمة getxxx () التالية.

نصائح أخرى

هذه هي الطريقة الصحيحة:

double sampleValue = (double)(( bytes[0]<<8 ) | ( bytes[1]&0x00FF ));

(تغيير المؤشرات لمبادلة Little/Big)

لا يمكنك القيام Most_sIgnificant Byte * 256 + money_significant_byte ثم يلقي للمضاعفة؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top