2016-04-12 42 views
1

Java'nın -buffer'ını nasıl kullanacağım konusunda biraz kafam karıştı: Programımda ses üretmeye çalışıyorum SourceDataLine üzerinden oynattığım veri. Ancak, double -values ​​üretiyorum ve bir örnek için 4 bayt kullanıyorum (AudioFormat: new AudioFormat(8000f, 32, 1, true, true)).SourceDataLine.write üzerinden ses çalma - Byte [] - Buffer çift değerlerle nasıl kullanılır

Bir double'u dört byte s'ye dönüştürmenin en iyi yolu nedir (çift için "oynat")?

[Not: normal ses oynatımı için iyi 32 bis örnek boyutu var mı?]

+1

İlgili: http://stackoverflow.com/q/26824663/2891664. Cevabım genellikle baytları örneklere dönüştürmekle ilgili olsa da, ne sorduğunuzu gösteren bir kod örneği var. Diğer bir ortak yöntem ise java.nio.ByteBuffer/java.nio.DoubleBuffer'ın kullanılmasıdır. – Radiodef

+2

32 bit örnek boyutu, ses için aldığı kadar iyidir, ancak 8kHz oldukça korkunç bir örnekleme oranıdır. 8kHz frekans aralığını 4kHz'nin altında sınırlar; bu da genellikle konuşma için sadece kabul edilebilir (VOIP/telefon). – Radiodef

+2

Referans için, 16100 fps'de 16 bit kodlama, yaygın olarak "CD Kalitesi" olarak bilinir. Stereo ile, bu çerçeve başına dört bayt (iki şort) gelir. İki katına sahip olmak, bu kadar düşük bir örnekleme oranını telafi etmeyecektir. (Radiodef'in kaliteyle ilgili yorumunu güçlendirir.) –

cevap

2

bağlantılı cevabı bu konuda ayrıntılı gider ama senin direk soruya cevap olacak. İlk olarak, çifte değerlerin -1.0 ile 1.0 arasında olduğunu varsayalım. Bu genellikle kurulum. 32 bit imzalı tamsayılara gitmek için 1.0'ın 0x7fffffff olduğu ve -1.0'ın basit çarpma ile yapılabilen 0x80000001 olduğu şekilde ölçeklendirmeniz gerekir.

int sampleInt = sampleDouble * 0x7fffffff; 

Sonra bayt içine int'leri bölmek gerekir:

byte[0] = (byte)((sampleInt >> 24) & 0xff); 
byte[1] = (byte)((sampleInt >> 16) & 0xff); 
byte[2] = (byte)((sampleInt >> 8) & 0xff); 
byte[3] = (byte)((sampleInt >> 0) & 0xff); 

sizin çıkış Endianess bağlı olarak sipariş takas gerekebilir.

+0

Neden bölüyorsunuz? Integer.MAX_VALUE ile çarpmak ve benim için 'AudioFormat.Encoding.PCM_Signed' özelliğini kullanmak daha sezgisel olacaktır. – sammex

+1

Üzgünüm, bir hataydı. Cevabı ben düzenleyeceğim. Integer.MAX_VALUE kullanmakta özgürsünüz, ancak gerçekten son bit derinliğine bağlı. Doğru çarpan, 32 bitlik durumda Integer.MAX_VALUE olur 2^(numBits-1) -1 'dir. – jaket