diff options
author | Jean Lorchat <jean.lorchat@gmail.com> | 2007-06-21 02:55:43 +0000 |
---|---|---|
committer | Jean Lorchat <jean.lorchat@gmail.com> | 2007-06-21 02:55:43 +0000 |
commit | e8492425c35c78423355c95c308d3c67be8ed265 (patch) | |
tree | 2b840ada5ee8b5b86e2781544f2d7faca7d1d06e /src/native | |
parent | a3c946c2e3130cc39d7489fbb0221d127f2d8d9d (diff) | |
download | jitsi-e8492425c35c78423355c95c308d3c67be8ed265.zip jitsi-e8492425c35c78423355c95c308d3c67be8ed265.tar.gz jitsi-e8492425c35c78423355c95c308d3c67be8ed265.tar.bz2 |
Issue number:
Obtained from:
Submitted by:
Reviewed by:
This adds the source of JNI library for direct alsa capture, bypassing
javasound and JMF transformation. Instead, everything is handled by the
low-level alsa libraries.
Currently, support is very poor because device name is hardcoded as well
as buffer size and stream format. Still, it works ok ;-)
Diffstat (limited to 'src/native')
4 files changed, 229 insertions, 0 deletions
diff --git a/src/native/linux/libjmf_alsa/Makefile b/src/native/linux/libjmf_alsa/Makefile new file mode 100644 index 0000000..9f0fe7e --- /dev/null +++ b/src/native/linux/libjmf_alsa/Makefile @@ -0,0 +1,25 @@ +### Makefile --- + +## Author: lorchat@vaio.home.net +## Version: $Id$ +## Keywords: +## X-URL: + +TARGET=libjmf_alsa.so +CFLAGS=-I$(JNI_INCLUDE_PATH) -I$(JNI_INCLUDE_PATH)/linux +JNI_INCLUDE_PATH=/usr/lib/jvm/java-6-sun-1.6.0.00/include +LIBS=-lasound +OBJS=net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.o + +all:$(TARGET) + +clean: + rm -rf $(TARGET) $(OBJS) *~ + +install:$(TARGET) + cp $(TARGET) ../../../../lib/native/linux/ + +libjmf_alsa.so:$(OBJS) + $(CC) -shared -o $(TARGET) $(LIBS) $(CFLAGS) $< + +### Makefile ends here diff --git a/src/native/linux/libjmf_alsa/build.sh b/src/native/linux/libjmf_alsa/build.sh new file mode 100644 index 0000000..8e6230f --- /dev/null +++ b/src/native/linux/libjmf_alsa/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +#set the path to your jvm/jni includes here + +JNI_INCLUDE_PATH=/usr/lib/jvm/java-6-sun-1.6.0.00/include +LIBS=-lasound + +rm -f libjmf_alsa.so + +gcc -shared -o libjmf_alsa.so $LIBS -I$JNI_INCLUDE_PATH -I$JNI_INCLUDE_PATH/linux net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c diff --git a/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c b/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c new file mode 100644 index 0000000..d97b54e --- /dev/null +++ b/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c @@ -0,0 +1,157 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +/* @(#)net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c + + Author: lorchat + Created : 21 Nov 2006 + + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <alsa/asoundlib.h> + +#include "net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.h" + +snd_pcm_t *capture; +snd_pcm_uframes_t buffersize = 160; +snd_pcm_uframes_t periodsize = 80; + +/** + Init the alsa sub-system + + TODO: add support for on-demand sample size adjustment and different bitrates + + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1init + (JNIEnv *env, jobject obj) +{ + int err; + + snd_pcm_hw_params_t *capture_params; + + char *device = "plughw:0,0"; + + int rate = 8000; + int exact_rate; + + printf("init called\n"); + + if ((err = snd_pcm_open(&capture, device, SND_PCM_STREAM_CAPTURE, 0)) < 0) { + fprintf(stderr, "alsa: can not open device %s for capture\n", device); + return; + } + + snd_pcm_hw_params_alloca(&capture_params); + + /* Init hwparams with full configuration space */ + if (snd_pcm_hw_params_any(capture, capture_params) < 0) { + fprintf(stderr, "Can not configure this PCM device.\n"); + return; + } + + if (snd_pcm_hw_params_set_access(capture, capture_params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + fprintf(stderr, "Error setting access.\n"); + return; + } + + /* Set sample format */ + if (snd_pcm_hw_params_set_format(capture, capture_params, SND_PCM_FORMAT_S16_LE) < 0) { + fprintf(stderr, "Error setting format.\n"); + return; + } + + /* Set sample rate. If the exact rate is not supported */ + /* by the hardware, use nearest possible rate. */ + exact_rate = rate; + if (snd_pcm_hw_params_set_rate_near(capture, capture_params, &exact_rate, 0) < 0) { + fprintf(stderr, "Error setting rate.\n"); + snd_pcm_close(capture); + return; + } + if (rate != exact_rate) { + fprintf(stderr, "alsa: The rate %d Hz is not supported by your hardware.\n", rate); + snd_pcm_close(capture); + return; + } + + /* Set number of channels */ + if (snd_pcm_hw_params_set_channels(capture, capture_params, 1) < 0) { + fprintf(stderr, "Error setting channels.\n"); + snd_pcm_close(capture); + return; + } + + /* Set number of periods. Periods used to be called fragments. */ + if (snd_pcm_hw_params_set_buffer_size_near(capture, capture_params, &buffersize) < 0) { + fprintf(stderr, "Error setting buffer_size\n"); + snd_pcm_close(capture); + return; + } + + periodsize = buffersize / 2; + if (snd_pcm_hw_params_set_period_size_near(capture, capture_params, &periodsize, 0) < 0) { + fprintf(stderr, "Error setting period size\n"); + snd_pcm_close(capture); + return; + } + + if (snd_pcm_hw_params(capture, capture_params) < 0) { + fprintf(stderr, "can not commit hw parameters\n"); + snd_pcm_close(capture); + return; + } + + printf("Rate is %d, buffer size is %d and period size is %d\n", rate, buffersize, periodsize); + + return; +} + +/** + * Read data from the ALSA device. This is a blocking call. + * + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_read + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1read + (JNIEnv *env, jobject obj, jbyteArray arr) +{ + int err; + signed short capture_data[80]; + + while ((err = snd_pcm_readi(capture, (void *) capture_data, periodsize)) < 0) { + printf("prepare(%d), ", snd_pcm_prepare(capture)); + fprintf(stderr, "%d.", err); + } + + printf("."); fflush(stdout); + + // printf("[%d]", (*env)->GetArrayLength(env, arr)); + (*env)->SetByteArrayRegion(env, arr, 0, 160, (const jbyte *) capture_data); + + return; +} + +/** + * Free the ALSA-related stuff and close the devices, to be implemented + * + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_delete + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1delete + (JNIEnv *env, jobject obj) +{ + printf("killing buffer\n"); + return; +} diff --git a/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.h b/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.h new file mode 100644 index 0000000..b423dbd --- /dev/null +++ b/src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream */ + +#ifndef _Included_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream +#define _Included_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1init + (JNIEnv *, jobject); + +/* + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_read + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1read + (JNIEnv *, jobject, jbyteArray); + +/* + * Class: net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream + * Method: jni_alsa_delete + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream_jni_1alsa_1delete + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif |