I have developed a kernel module (Android) which provides me:
PCM
16-bit
48000 Hz
2 channel
and I want to stream it to an Apple's Airport Express (AEX) in java.
The AEX needs 44.1 kHz PCM so I have to resample the PCM-stream.
I have following possibilities, but which is the best?
advantages:
high-performant due to native C
already uses libsamplerate to resample wav, mp3, ogg, flac, aac, pls
openssl as static library
usable via command-line from my java-program via Runtime.exec()
disadvantages:
I am relative new to C
overloaded: I don't need wav, mp3.. only PCM
many dependencies with GPL-libraries which I have to compile for Android
only supports PCM already with 44.1 kHz, no resampling for PCM implemented yet
-> have to implement resampling for PCM
advantages:
I CAN java :)
middle-performant due to resamling in C , but streaming in java
just one dependency to LGPL-library
no Runtime.exec() needed
disadvantages:
needs [bouncycastle][3] for AES which is a bit larger than openssl
less performant than solution #1 (but maybe fast enough)
advantages:
most performant
no resampling at higher level
disadvantages:
I am relative new to C
Is it possible to use libsamplerate or libresample in kernel-space?!
I'm a java-guy in heart, but this task (especially on a cpu constrained device, like a handheld) is crying for C. I would suggest simply using the libsamplerate. It has a simple API, and even if you're new to C you'll find plenty of examples by just googling around.
of course the java based solution could and would work, it just doesn't seem polite to the users to eat up their batteries just because your new to C :)
EDIT: I might contradict myself a bit, but even though performance is a serious issue, I would avoid doing anything in kernel-space, unless I know the kernel and the hardware really well. In light of this I would go with a user-space program linked to libsamplerate. After a bit of googling around I've found this example (note that the output is the jack interface, obviously it has to be different for you)
#include <jack/jack.h>
#include <samplerate.h>
int channels;
float data_samplerate;
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
void getDasData(float **dst,int num_frames){
/* Provide sound data here, and only here. */
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
long getDasResampledData_callback(void *cb_data, float **data){
static float ret[1024];
static float ret3[1024];
static float *ret2[2]={&ret[0],&ret[512]};
getDasData(ret2,512);
for(int i=0;i<512;i++){
ret3[i*2]=ret2[0][i];
ret3[i*2+1]=ret2[1][i];
}
*data=&ret3[0];
return 512;
}
void getDasResampledData(float **dst,int num_frames){
double ratio=samplerate/getSourceRate();
float outsound[num_frames*2];
long read=src_callback_read(dassrc_state,ratio,num_frames,outsound);
//fprintf(stderr,"read: %d, num_frames: %d\n",read,num_frames);
for(int i=0;i<read;i++){
dst[0][i]=outsound[i*2];
dst[1][i]=outsound[i*2+1];
}
if(read<num_frames){
float *newdst[2]={dst[0]+read,dst[1]+read};
getDasResampledData(newdst,num_frames-read);
}
}
static int process (jack_nframes_t nframes, void *arg){
int ch;
sample_t *out[channels];
for(ch=0;ch<channels;ch++){
out[ch]=(sample_t*)jack_port_get_buffer(ports[ch],nframes);
}
if( (fabs(data_samplerate - jack_samplerate)) > 0.1)
getDasResampledData(out,numSamples);
else
getDasData(outputChannelData,numSamples);
return;
audioCallback(NULL,0,out,channels,nframes);
}
int main(){
dassrc_state=src_callback_new(getDasResampledData_callback,SRC_QUALITY,2,NULL,NULL);
jack_set_process_callback(client, process,NULL);
}
from http://old.nabble.com/Example-of-using-libresample-with-jack-td8795847.html
This example seems pretty straightforward, I hope you can use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With