2010-07-15 12 views
5

andriod için geliştirmeye çalıştığım uygulama, 48Khz (PCM 16 bit & mono) kayıtlarını kaydeder ve bunları ağa gönderir. Ayrıca, 8Khz'de gelen ses akışı var. Bu yüzden, 8Khz örneklenmiş çerçeveler alıp bunları çalıyorum (AudioTrack neslim 8Khz'ye ayarlı), ancak bunları oynatırken her şey çalışıyor, ancak gecikme BÜYÜK. Bir şey duyana kadar yaklaşık 3 saniye sürer.8Khz'den 48Khz'ye (örnekleme/sonrasındaki örnek ses çerçeveleri) örnekleme/sonlandırma örnek kareleri

Alınan çerçeveleri 8Khz'den 48Khz'ye çıkarır ve oynatırsam çok büyük bir oyun gecikmesi olmayacağını düşünüyorum. Aslında aynı oranda kareleri kaydedip oynattığımda, gecikme gerçekten çok düşük. Kötü olan şey şu şekilde yapmaya zorlandığım: 48Khz'ye gönder ve 8Khz'ye gönder.

Daha önce açıklandığı gibi, 8Khz'den 48Khz'e bir ses karesi (16 bit PCM) örneklemeye çalışıyorum. Java'da herhangi bir rutin/kütüphane/API bilen var mı?

Gizli bir sinyale örnek alma ile ilgili temel bilgileri biliyorum, ancak kendi FIR filtresini tasarlayıp uyguladığımı ve ses akışıyla onu sarsacağını düşünüyorum .... çok fazla. Ayrıca, benim bilgimin üzerindedir.

Öyleyse ... bu konuda bana kim yardım edebilir? Java'da kullanabileceğim herhangi bir kütüphane/rutini bilen var mı? Herhangi bir öneri veya alternatifler?

+4

@juergen, * En az * gibi tamamen ibaresinin kaldırılmasına hiçbir değeri yoktur ve diğer yazım hatalarını düzeltin. –

cevap

6

Hızlı ve kirli bir çözüm, doğrusal enterpolasyon olabilir. Her zaman altı kat daha fazla örnekleme yaptığınız için bu gerçekten çok kolay:

Böyle bir şekilde çalışıyor (C kodu ve test edilmedi, ve son yinelemeyi düzgün kullanmıyorum, ancak düşündüğüm fikir).

void resample (short * output, short * input, int n) 
{ 
    // output ought to be 6 times as large as input (48000/8000). 

    int i; 
    for (i=0; i<n-1; i++) 
    { 
    output[i*6+0] = input[i]*6/6 + input[i+1]*0/6; 
    output[i*6+1] = input[i]*5/6 + input[i+1]*1/6; 
    output[i*6+2] = input[i]*4/6 + input[i+1]*2/6; 
    output[i*6+3] = input[i]*3/6 + input[i+1]*3/6; 
    output[i*6+4] = input[i]*2/6 + input[i+1]*4/6; 
    output[i*6+5] = input[i]*1/6 + input[i+1]*5/6; 
    } 

Doğrusal enterpolasyon size mükemmel ses kalitesi sunmaz, ancak ucuz ve hızlıdır. İsterseniz kübik enterpolasyon kullanarak bunu geliştirebilirsiniz.

Hızlı ve yüksek kaliteli bir yeniden örnekleme istiyorsanız Android-NDK kullanarak libresample gibi bir c resampling kütüphanesi derlemenizi ve JNI kullanarak java'dan çağırmanızı öneririm. Bu çok daha hızlı olacak. JNI kodunu yazmak çoğu insanın utangaç olduğu bir şeydir, ama oldukça kolaydır .. NDK'nın bunun için birçok örneği vardır.

http://www.mega-nerd.com/SRC/index.html

2

Doğrusal interpolasyon eserler tanıtır. Yüksek kaliteli yeniden örnekleme ile güzel java kütüphanesi var - JSSRC (http://jssrc.khadkevich.org/).

kod Github artık daha mevcuttur: "gelişmiş sayesinde" in yazım hatalarını düzeltmek için eski bir soruyu çarpmak için gidiyoruz https://github.com/hutm/JSSRC

+1

Bana baş ağrısını kurtardın. Bağlandığınız site aşağıdaysa, burada Arşiv https://web.archive.org/web/20130902203226/http://jssrc.khadkevich.org ve işte github deposu .. https: // github.com/hutm/JSSRC –