2010-07-15 3 views
5

Die Anwendung, die ich für andriod entwickeln möchte, zeichnet Bilder bei 48Khz (PCM 16bits & Mono) und sendet sie an das Netzwerk. Außerdem gibt es einen eingehenden Audiostream mit 8 kHz. Also erhalte ich 8Khz gesampelte Frames und spiele sie ab (mein AudioTrack-Objekt ist auf 8Khz eingestellt), aber beim Abspielen funktioniert alles, aber die Latenz ist RIESIG. Es dauert etwa 3 Sekunden, bis Sie etwas hören.resample/upsample Soundframes von 8Khz bis 48Khz (Java/Android)

Ich denke, wenn ich die empfangenen Frames von 8 Khz auf 48 Khz upsamplen und spiele sie, wird es nicht so eine große Spiel Latenz. In der Tat, wenn ich Frames mit derselben Rate aufnehme und spiele, ist die Latenz wirklich niedrig. Das Schlimme ist, dass ich gezwungen bin, es so zu machen: sende an 48Khz und empfange bis 8Khz.

Wie bereits erwähnt, versuche ich ein Soundframe (16bit PCM) von 8 Khz bis 48 Khz upsample. Kennt irgendjemand irgendeine Routine/Bibliothek/API in Java, die das tut ???

Ich kenne die Grundlagen über Upsampling ein diskretes Signal, aber ich denke, dass, um meinen eigenen FIR-Filter zu entwerfen und zu implementieren, und es mit dem Audiostream zusammenfalten .... ist viel zu viel. Außerdem ist es über mein Wissen.

Also ... kann mir jemand dabei helfen ?? Kennt irgendjemand irgendeine Bibliothek/Routine in Java, die ich verwenden kann? Irgendwelche Vorschläge oder Alternativen ??

+4

@juergen, wenn Sie eine alte Frage stoßen werden Fehler in „Dank fortschrittlichen“, zu beheben * mindestens * entfernen Sie den Satz vollständig, wie Es hat keinen Wert und behebt die anderen Rechtschreibfehler. –

Antwort

6

Eine schnelle und schmutzige Lösung wäre eine lineare Interpolation. Da Sie immer um einen Faktor von sechs Sampling sind, ist dies wirklich einfach zu tun:

Es funktioniert in etwa so (C-Code, und ungetestet, und ich handle nicht die letzte Iteration richtig, aber es zeigt die Idee denke ich).

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; 
    } 

Die lineare Interpolation bietet keine großartige Klangqualität, ist aber billig und schnell. Sie können dies mit der kubischen Interpolation verbessern, wenn Sie möchten.

Wenn Sie ein schnelles und qualitativ hochwertiges Resampling wünschen, schlage ich vor, dass Sie eine c Resampling-Bibliothek wie libresample mit dem Android-NDK kompilieren und aus Java mit JNI aufrufen. Das wird viel schneller sein. Das Schreiben des JNI-Codes ist etwas, vor dem die meisten Leute zurückschrecken, aber es ist ziemlich einfach. Das NDK hat viele Beispiele dafür.

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

2

Linearinterpolation führt Artefakte. Es gibt eine nette Java-Bibliothek mit hochwertigem Resampling - JSSRC (http://jssrc.khadkevich.org/).

Der Code ist jetzt auf Github: https://github.com/hutm/JSSRC

+1

Du hast mir Kopfschmerzen erspart. Die Seite, die Sie verlinkt haben, ist unten, hier ist das Archiv https://web.archive.org/web/20130902203226/http://jssrc.khadkevich.org und hier ist das Github-Repository .. https: // github.com/hutm/JSSRC –