aboutsummaryrefslogtreecommitdiffstats
path: root/src/native
diff options
context:
space:
mode:
authorJean Lorchat <jean.lorchat@gmail.com>2007-06-21 02:55:43 +0000
committerJean Lorchat <jean.lorchat@gmail.com>2007-06-21 02:55:43 +0000
commite8492425c35c78423355c95c308d3c67be8ed265 (patch)
tree2b840ada5ee8b5b86e2781544f2d7faca7d1d06e /src/native
parenta3c946c2e3130cc39d7489fbb0221d127f2d8d9d (diff)
downloadjitsi-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')
-rw-r--r--src/native/linux/libjmf_alsa/Makefile25
-rw-r--r--src/native/linux/libjmf_alsa/build.sh10
-rw-r--r--src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.c157
-rw-r--r--src/native/linux/libjmf_alsa/net_java_sip_communicator_impl_media_protocol_alsa_AlsaStream.h37
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