summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia-audiodev
diff options
context:
space:
mode:
Diffstat (limited to 'pjmedia/src/pjmedia-audiodev')
-rw-r--r--pjmedia/src/pjmedia-audiodev/alsa_dev.c4
-rw-r--r--pjmedia/src/pjmedia-audiodev/bb10_dev.c364
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp58
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp62
4 files changed, 342 insertions, 146 deletions
diff --git a/pjmedia/src/pjmedia-audiodev/alsa_dev.c b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
index 72b995e..31b3b06 100644
--- a/pjmedia/src/pjmedia-audiodev/alsa_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
@@ -1,4 +1,4 @@
-/* $Id: alsa_dev.c 4130 2012-05-17 08:35:51Z nanang $ */
+/* $Id: alsa_dev.c 4283 2012-10-12 06:19:32Z ming $ */
/*
* Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2007-2009 Keystream AB and Konftel AB, All rights reserved.
@@ -232,7 +232,7 @@ static pj_status_t add_dev (struct alsa_factory *af, const char *dev_name)
pj_bzero(adi, sizeof(*adi));
/* Set device name */
- strcpy(adi->name, dev_name);
+ strncpy(adi->name, dev_name, sizeof(adi->name));
/* Check the number of playback channels */
adi->output_count = (pb_result>=0) ? 1 : 0;
diff --git a/pjmedia/src/pjmedia-audiodev/bb10_dev.c b/pjmedia/src/pjmedia-audiodev/bb10_dev.c
index 418256d..f920080 100644
--- a/pjmedia/src/pjmedia-audiodev/bb10_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/bb10_dev.c
@@ -1,4 +1,4 @@
-/* $Id: bb10_dev.c 4151 2012-06-01 04:49:57Z ming $ */
+/* $Id: bb10_dev.c 4340 2013-02-05 05:15:01Z bennylp $ */
/*
* Copyright (C) 2008-2012 Teluu Inc. (http://www.teluu.com)
*
@@ -33,6 +33,11 @@
#if defined(PJMEDIA_AUDIO_DEV_HAS_BB10) && PJMEDIA_AUDIO_DEV_HAS_BB10 != 0
+#ifndef PJ_BBSDK_VER
+ /* Format: 0xMMNNRR: MM: major, NN: minor, RR: revision */
+# define PJ_BBSDK_VER 0x100006
+#endif
+
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
@@ -40,6 +45,9 @@
#include <pthread.h>
#include <errno.h>
#include <sys/asoundlib.h>
+#if PJ_BBSDK_VER >= 0x100006
+#include <audio/audio_manager_routing.h>
+#endif
#define THIS_FILE "bb10_dev.c"
@@ -114,8 +122,9 @@ struct bb10_stream
int quit;
/* Playback */
+ unsigned int pb_ctrl_audio_manager_handle;
snd_pcm_t *pb_pcm;
- snd_mixer_t *pb_mixer;
+ unsigned int pb_audio_manager_handle;
unsigned long pb_frames; /* samples_per_frame */
pjmedia_aud_play_cb pb_cb;
unsigned pb_buf_size;
@@ -124,7 +133,7 @@ struct bb10_stream
/* Capture */
snd_pcm_t *ca_pcm;
- snd_mixer_t *ca_mixer;
+ unsigned int ca_audio_manager_handle;
unsigned long ca_frames; /* samples_per_frame */
pjmedia_aud_rec_cb ca_cb;
unsigned ca_buf_size;
@@ -160,8 +169,7 @@ static pj_status_t bb10_add_dev (struct bb10_factory *af)
{
pjmedia_aud_dev_info *adi;
int pb_result, ca_result;
- int card = -1;
- int dev = 0;
+ unsigned int handle;
snd_pcm_t *pcm_handle;
if (af->dev_cnt >= PJ_ARRAY_SIZE(af->devs))
@@ -171,20 +179,29 @@ static pj_status_t bb10_add_dev (struct bb10_factory *af)
TRACE_((THIS_FILE, "bb10_add_dev Enter"));
- if ((pb_result = snd_pcm_open_preferred (&pcm_handle, &card, &dev,
- SND_PCM_OPEN_PLAYBACK)) >= 0)
+ if ((pb_result = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT,
+ &pcm_handle,
+ &handle,
+ (char*)"voice",
+ SND_PCM_OPEN_PLAYBACK))
+ >= 0)
{
- TRACE_((THIS_FILE, "Try to open the device for playback - success"));
snd_pcm_close (pcm_handle);
+ audio_manager_free_handle(handle);
} else {
TRACE_((THIS_FILE, "Try to open the device for playback - failure"));
}
- if ((ca_result = snd_pcm_open_preferred (&pcm_handle, &card, &dev,
- SND_PCM_OPEN_CAPTURE)) >=0)
+ if ((ca_result = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT,
+ &pcm_handle,
+ &handle,
+ (char*)"voice",
+ SND_PCM_OPEN_CAPTURE))
+ >= 0)
{
- TRACE_((THIS_FILE, "Try to open the device for capture - success"));
- snd_pcm_close (pcm_handle);
+ snd_pcm_close (pcm_handle);
+ audio_manager_free_handle(handle);
+
} else {
TRACE_((THIS_FILE, "Try to open the device for capture - failure"));
}
@@ -239,7 +256,7 @@ pjmedia_aud_dev_factory* pjmedia_bb10_factory(pj_pool_factory *pf)
static pj_status_t bb10_factory_init(pjmedia_aud_dev_factory *f)
{
pj_status_t status;
-
+
status = bb10_factory_refresh(f);
if (status != PJ_SUCCESS)
return status;
@@ -314,7 +331,7 @@ static pj_status_t bb10_factory_get_dev_info(pjmedia_aud_dev_factory *f,
pj_memcpy(info, &af->devs[index], sizeof(*info));
info->caps = PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |
PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY;
-
+
return PJ_SUCCESS;
}
@@ -358,7 +375,7 @@ static pj_status_t bb10_factory_default_param(pjmedia_aud_dev_factory *f,
TRACE_((THIS_FILE, "bb10_factory_default_param clock = %d flags = %d"
" spf = %d", param->clock_rate, param->flags,
param->samples_per_frame));
-
+
return PJ_SUCCESS;
}
@@ -368,14 +385,16 @@ static void close_play_pcm(struct bb10_stream *stream)
if (stream != NULL && stream->pb_pcm != NULL) {
snd_pcm_close(stream->pb_pcm);
stream->pb_pcm = NULL;
- }
-}
-static void close_play_mixer(struct bb10_stream *stream)
-{
- if (stream != NULL && stream->pb_mixer != NULL) {
- snd_mixer_close(stream->pb_mixer);
- stream->pb_mixer = NULL;
+ if (stream->pb_audio_manager_handle != 0) {
+ audio_manager_free_handle(stream->pb_audio_manager_handle);
+ stream->pb_audio_manager_handle = 0;
+ }
+
+ if (stream->pb_ctrl_audio_manager_handle != 0) {
+ audio_manager_free_handle(stream->pb_ctrl_audio_manager_handle);
+ stream->pb_ctrl_audio_manager_handle = 0;
+ }
}
}
@@ -391,14 +410,11 @@ static void close_capture_pcm(struct bb10_stream *stream)
if (stream != NULL && stream->ca_pcm != NULL) {
snd_pcm_close(stream->ca_pcm);
stream->ca_pcm = NULL;
- }
-}
-static void close_capture_mixer(struct bb10_stream *stream)
-{
- if (stream != NULL && stream->ca_mixer != NULL) {
- snd_mixer_close(stream->ca_mixer);
- stream->ca_mixer = NULL;
+ if (stream->ca_audio_manager_handle != 0) {
+ audio_manager_free_handle(stream->ca_audio_manager_handle);
+ stream->ca_audio_manager_handle = 0;
+ }
}
}
@@ -435,10 +451,9 @@ static int pb_thread_func (void *arg)
if ((result = snd_pcm_plugin_prepare(stream->pb_pcm,
SND_PCM_CHANNEL_PLAYBACK)) < 0)
{
- close_play_mixer(stream);
close_play_pcm(stream);
TRACE_((THIS_FILE, "pb_thread_func failed prepare = %d", result));
- return PJ_SUCCESS;
+ return PJ_SUCCESS;
}
while (!stream->quit) {
@@ -451,6 +466,7 @@ static int pb_thread_func (void *arg)
frame.timestamp.u64 = tstamp.u64;
frame.bit_info = 0;
+ /* Read the audio from pjmedia */
result = stream->pb_cb (user_data, &frame);
if (result != PJ_SUCCESS || stream->quit)
break;
@@ -460,18 +476,45 @@ static int pb_thread_func (void *arg)
/* Write 640 to play unit */
result = snd_pcm_plugin_write(stream->pb_pcm,buf,size);
- if (result != size) {
- TRACE_((THIS_FILE, "pb_thread_func failed write = %d", result));
+ if (result != size || result < 0) {
+ /* either the write to output device has failed or not the
+ * full amount of bytes have been written. This usually happens
+ * when audio routing is being changed by another thread
+ * Use a status variable for reading the error
+ */
+ snd_pcm_channel_status_t status;
+ status.channel = SND_PCM_CHANNEL_PLAYBACK;
+ if (snd_pcm_plugin_status (stream->pb_pcm, &status) < 0) {
+ /* Call has failed nothing we can do except log and
+ * continue */
+ PJ_LOG(4,(THIS_FILE,
+ "underrun: playback channel status error"));
+ } else {
+ /* The status of the error has been read
+ * RIM say these are expected so we can "re-prepare" the stream
+ */
+ PJ_LOG(4,(THIS_FILE,"PLAY thread ERROR status = %d",
+ status.status));
+ if (status.status == SND_PCM_STATUS_READY ||
+ status.status == SND_PCM_STATUS_UNDERRUN ||
+ status.status == SND_PCM_STATUS_ERROR )
+ {
+ if (snd_pcm_plugin_prepare (stream->pb_pcm,
+ SND_PCM_CHANNEL_PLAYBACK) < 0)
+ {
+ PJ_LOG(4,(THIS_FILE,
+ "underrun: playback channel prepare error"));
+ }
+ }
+ }
}
-
tstamp.u64 += nframes;
}
flush_play(stream);
- close_play_mixer(stream);
close_play_pcm(stream);
TRACE_((THIS_FILE, "pb_thread_func: Stopped"));
-
+
return PJ_SUCCESS;
}
@@ -513,29 +556,58 @@ static int ca_thread_func (void *arg)
if ((result = snd_pcm_plugin_prepare (stream->ca_pcm,
SND_PCM_CHANNEL_CAPTURE)) < 0)
{
- close_capture_mixer(stream);
close_capture_pcm(stream);
TRACE_((THIS_FILE, "ca_thread_func failed prepare = %d", result));
- return PJ_SUCCESS;
+ return PJ_SUCCESS;
}
while (!stream->quit) {
pjmedia_frame frame;
pj_bzero (buf, size);
-
+
+ /* read the input device */
result = snd_pcm_plugin_read(stream->ca_pcm, buf,size);
- if (result == -EPIPE) {
- PJ_LOG (4,(THIS_FILE, "ca_thread_func: overrun!"));
- snd_pcm_plugin_prepare (stream->ca_pcm, SND_PCM_CHANNEL_CAPTURE);
- continue;
- } else if (result < 0) {
- PJ_LOG (4,(THIS_FILE, "ca_thread_func: error reading data!"));
+ if(result <0 || result != size) {
+ /* We expect result to be size (640)
+ * It's not so we have to read the status error and "prepare"
+ * the channel. This usually happens when output audio routing
+ * has been changed by another thread.
+ * We won't "continue", instead just do what we can and leave
+ * the end of the loop to write what's in the buffer. Not entirely
+ * correct but saves a potential underrun in PJMEDIA
+ */
+ PJ_LOG (4,(THIS_FILE,
+ "snd_pcm_plugin_read ERROR read = %d required = %d",
+ result,size));
+ snd_pcm_channel_status_t status;
+ status.channel = SND_PCM_CHANNEL_CAPTURE;
+ if ((result = snd_pcm_plugin_status (stream->ca_pcm, &status)) < 0)
+ {
+ /* Should not fail but all we can do is continue */
+ PJ_LOG(4,(THIS_FILE, "capture: snd_pcm_plugin_status ret = %d",
+ result));
+ } else {
+ /* RIM say these are the errors that we should "prepare"
+ * after */
+ if (status.status == SND_PCM_STATUS_READY ||
+ status.status == SND_PCM_STATUS_OVERRUN ||
+ status.status == SND_PCM_STATUS_ERROR)
+ {
+ if (snd_pcm_plugin_prepare (stream->ca_pcm,
+ SND_PCM_CHANNEL_CAPTURE) < 0)
+ {
+ PJ_LOG (4,(THIS_FILE,
+ "overrun: capture channel prepare error"));
+ }
+ }
+ }
}
if (stream->quit)
break;
+ /* Write the capture audio data to PJMEDIA */
frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
frame.buf = (void *) buf;
frame.size = size;
@@ -550,19 +622,68 @@ static int ca_thread_func (void *arg)
}
flush_capture(stream);
- close_capture_mixer(stream);
close_capture_pcm(stream);
TRACE_((THIS_FILE, "ca_thread_func: Stopped"));
return PJ_SUCCESS;
}
+/* Audio routing, speaker/headset */
+static pj_status_t bb10_initialize_playback_ctrl(struct bb10_stream *stream,
+ bool speaker)
+{
+ /* Although the play and capture have audio manager handles, audio routing
+ * requires a separate handle
+ */
+ int ret = PJ_SUCCESS;
+
+ if (stream->pb_ctrl_audio_manager_handle == 0) {
+ /* lazy init an audio manager handle */
+ ret = audio_manager_get_handle(AUDIO_TYPE_VIDEO_CHAT, 0, false,
+ &stream->pb_ctrl_audio_manager_handle);
+ if (ret != 0) {
+ TRACE_((THIS_FILE, "audio_manager_get_handle ret = %d",ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+ }
+
+ /* Set for either speaker or earpiece */
+ if (speaker) {
+ ret = audio_manager_set_handle_type(
+ stream->pb_ctrl_audio_manager_handle,
+ AUDIO_TYPE_VIDEO_CHAT,
+ AUDIO_DEVICE_SPEAKER,
+ AUDIO_DEVICE_DEFAULT);
+ } else {
+ ret = audio_manager_set_handle_type(
+ stream->pb_ctrl_audio_manager_handle,
+ AUDIO_TYPE_VIDEO_CHAT,
+ AUDIO_DEVICE_HANDSET,
+ AUDIO_DEVICE_DEFAULT);
+ }
+
+ if (ret == 0) {
+ /* RIM recommend this call */
+ ret = audio_manager_set_handle_routing_conditions(
+ stream->pb_ctrl_audio_manager_handle,
+ SETTINGS_RESET_ON_DEVICE_CONNECTION);
+ if (ret != 0) {
+ TRACE_((THIS_FILE,
+ "audio_manager_set_handle_routing_conditions ret = %d",
+ ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+ } else {
+ TRACE_((THIS_FILE, "audio_manager_set_handle_type ret = %d", ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+
+ return PJ_SUCCESS;
+}
static pj_status_t bb10_open_playback (struct bb10_stream *stream,
const pjmedia_aud_param *param)
{
- int card = -1;
- int dev = 0;
int ret = 0;
snd_pcm_channel_info_t pi;
snd_pcm_channel_setup_t setup;
@@ -575,34 +696,54 @@ static pj_status_t bb10_open_playback (struct bb10_stream *stream,
return PJMEDIA_EAUD_INVDEV;
}
- if ((ret = snd_pcm_open_preferred (&stream->pb_pcm, &card, &dev,
- SND_PCM_OPEN_PLAYBACK)) < 0)
+ /* Use the bb10 audio manager API to open as opposed to QNX core audio
+ * Echo cancellation built in
+ */
+ if ((ret = audio_manager_snd_pcm_open_name(
+ AUDIO_TYPE_VIDEO_CHAT,
+ &stream->pb_pcm, &stream->pb_audio_manager_handle,
+ (char*)"voice",
+ SND_PCM_OPEN_PLAYBACK)) < 0)
{
- TRACE_((THIS_FILE, "snd_pcm_open_preferred ret = %d", ret));
+ TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
return PJMEDIA_EAUD_SYSERR;
}
+ /* Required call from January 2013 gold OS release */
+ if ((ret = snd_pcm_plugin_set_disable(stream->pb_pcm,
+ PLUGIN_DISABLE_MMAP)) < 0)
+ {
+ TRACE_((THIS_FILE, "snd_pcm_plugin_set_disable ret = %d", ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+
+ /* Required call from January 2013 gold OS release */
+ if ((ret = snd_pcm_plugin_set_enable(stream->pb_pcm,
+ PLUGIN_ROUTING)) < 0)
+ {
+ TRACE_((THIS_FILE, "snd_pcm_plugin_set_enable ret = %d", ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+
/* TODO PJ_ZERO */
memset (&pi, 0, sizeof (pi));
pi.channel = SND_PCM_CHANNEL_PLAYBACK;
if ((ret = snd_pcm_plugin_info (stream->pb_pcm, &pi)) < 0) {
- TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
- return PJMEDIA_EAUD_SYSERR;
+ TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
+ return PJMEDIA_EAUD_SYSERR;
}
memset (&pp, 0, sizeof (pp));
- /* Request VoIP compatible capabilities
- * On simulator frag_size is always negotiated to 170
- */
+ /* Request VoIP compatible capabilities */
pp.mode = SND_PCM_MODE_BLOCK;
pp.channel = SND_PCM_CHANNEL_PLAYBACK;
pp.start_mode = SND_PCM_START_DATA;
pp.stop_mode = SND_PCM_STOP_ROLLOVER;
/* HARD CODE for the time being PJMEDIA expects 640 for 16khz */
pp.buf.block.frag_size = PREFERRED_FRAME_SIZE*2;
- /* Increasing this internal buffer count delays write failure in the loop */
- pp.buf.block.frags_max = 4;
+ /* RIM recommends maximum of 3 */
+ pp.buf.block.frags_max = 3;
pp.buf.block.frags_min = 1;
pp.format.interleave = 1;
/* HARD CODE for the time being PJMEDIA expects 16khz */
@@ -622,7 +763,7 @@ static pj_status_t bb10_open_playback (struct bb10_stream *stream,
memset (&group, 0, sizeof (group));
setup.channel = SND_PCM_CHANNEL_PLAYBACK;
setup.mixer_gid = &group.gid;
-
+
if ((ret = snd_pcm_plugin_setup (stream->pb_pcm, &setup)) < 0) {
TRACE_((THIS_FILE, "snd_pcm_plugin_setup ret = %d", ret));
return PJMEDIA_EAUD_SYSERR;
@@ -631,14 +772,6 @@ static pj_status_t bb10_open_playback (struct bb10_stream *stream,
if (group.gid.name[0] == 0) {
return PJMEDIA_EAUD_SYSERR;
}
-
- if ((ret = snd_mixer_open (&stream->pb_mixer, card,
- setup.mixer_device)) < 0)
- {
- TRACE_((THIS_FILE, "snd_mixer_open ret = %d", ret));
- return PJMEDIA_EAUD_SYSERR;
- }
-
rate = param->clock_rate;
/* Set the sound device buffer size and latency */
@@ -658,7 +791,7 @@ static pj_status_t bb10_open_playback (struct bb10_stream *stream,
TRACE_((THIS_FILE, "bb10_open_playback: pb_frames = %d clock = %d",
stream->pb_frames, param->clock_rate));
-
+
return PJ_SUCCESS;
}
@@ -668,8 +801,6 @@ static pj_status_t bb10_open_capture (struct bb10_stream *stream,
int ret = 0;
unsigned int rate;
unsigned long tmp_buf_size;
- int card = -1;
- int dev = 0;
int frame_size;
snd_pcm_channel_info_t pi;
snd_mixer_group_t group;
@@ -679,11 +810,27 @@ static pj_status_t bb10_open_capture (struct bb10_stream *stream,
if (param->rec_id < 0 || param->rec_id >= stream->af->dev_cnt)
return PJMEDIA_EAUD_INVDEV;
- /* BB10 Audio init here (not prepare) */
- if ((ret = snd_pcm_open_preferred (&stream->ca_pcm, &card, &dev,
- SND_PCM_OPEN_CAPTURE)) < 0)
+ if ((ret=audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT,
+ &stream->ca_pcm,
+ &stream->ca_audio_manager_handle,
+ (char*)"voice",
+ SND_PCM_OPEN_CAPTURE)) < 0)
+ {
+ TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+ /* Required call from January 2013 gold OS release */
+ if ((ret = snd_pcm_plugin_set_disable (stream->ca_pcm,
+ PLUGIN_DISABLE_MMAP)) < 0)
{
- TRACE_((THIS_FILE, "snd_pcm_open_preferred ret = %d", ret));
+ TRACE_(("snd_pcm_plugin_set_disable failed: %d",ret));
+ return PJMEDIA_EAUD_SYSERR;
+ }
+ /* Required call from January 2013 gold OS release */
+ if ((ret = snd_pcm_plugin_set_enable(stream->ca_pcm,
+ PLUGIN_ROUTING)) < 0)
+ {
+ TRACE_(("snd_pcm_plugin_set_enable failed: %d",ret));
return PJMEDIA_EAUD_SYSERR;
}
@@ -707,8 +854,8 @@ static pj_status_t bb10_open_capture (struct bb10_stream *stream,
pp.stop_mode = SND_PCM_STOP_ROLLOVER;
/* HARD CODE for the time being PJMEDIA expects 640 for 16khz */
pp.buf.block.frag_size = PREFERRED_FRAME_SIZE*2;
- /* Not applicable for capture hence -1 */
- pp.buf.block.frags_max = -1;
+ /* From January 2013 gold OS release. RIM recommend these for capture */
+ pp.buf.block.frags_max = 1;
pp.buf.block.frags_min = 1;
pp.format.interleave = 1;
/* HARD CODE for the time being PJMEDIA expects 16khz */
@@ -740,18 +887,8 @@ static pj_status_t bb10_open_capture (struct bb10_stream *stream,
} else {
}
- if ((ret = snd_mixer_open (&stream->ca_mixer, card,
- setup.mixer_device)) < 0)
- {
- TRACE_((THIS_FILE,"snd_mixer_open ret = %d",ret));
- return PJMEDIA_EAUD_SYSERR;
- }
-
- /* frag_size should be 160 */
frame_size = setup.buf.block.frag_size;
- /* END BB10 init */
-
/* Set clock rate */
rate = param->clock_rate;
stream->ca_frames = (unsigned long) param->samples_per_frame /
@@ -820,7 +957,6 @@ static pj_status_t bb10_factory_create_stream(pjmedia_aud_dev_factory *f,
status = bb10_open_capture (stream, param);
if (status != PJ_SUCCESS) {
if (param->dir & PJMEDIA_DIR_PLAYBACK) {
- close_play_mixer(stream);
close_play_pcm(stream);
}
pj_pool_release (pool);
@@ -828,12 +964,24 @@ static pj_status_t bb10_factory_create_stream(pjmedia_aud_dev_factory *f,
}
}
+ /* Part of the play functionality but the RIM/Truphone loopback sample
+ * initialializes after the play and capture
+ * "false" is default/earpiece for output
+ */
+ status = bb10_initialize_playback_ctrl(stream,false);
+ if (status != PJ_SUCCESS) {
+ return PJMEDIA_EAUD_SYSERR;
+ }
+
*p_strm = &stream->base;
return PJ_SUCCESS;
}
-/* API: get running parameter */
+/*
+ * API: get running parameter
+ * based on ALSA template
+ */
static pj_status_t bb10_stream_get_param(pjmedia_aud_stream *s,
pjmedia_aud_param *pi)
{
@@ -847,7 +995,10 @@ static pj_status_t bb10_stream_get_param(pjmedia_aud_stream *s,
}
-/* API: get capability */
+/*
+ * API: get capability
+ * based on ALSA template
+*/
static pj_status_t bb10_stream_get_cap(pjmedia_aud_stream *s,
pjmedia_aud_dev_cap cap,
void *pval)
@@ -862,28 +1013,51 @@ static pj_status_t bb10_stream_get_cap(pjmedia_aud_stream *s,
/* Recording latency */
*(unsigned*)pval = stream->param.input_latency_ms;
return PJ_SUCCESS;
+
} else if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY &&
(stream->param.dir & PJMEDIA_DIR_PLAYBACK))
{
/* Playback latency */
*(unsigned*)pval = stream->param.output_latency_ms;
return PJ_SUCCESS;
+
} else {
return PJMEDIA_EAUD_INVCAP;
}
}
-/* API: set capability */
+/*
+ * API: set capability
+ * Currently just supporting toggle between speaker and earpiece
+ */
static pj_status_t bb10_stream_set_cap(pjmedia_aud_stream *strm,
pjmedia_aud_dev_cap cap,
const void *value)
{
- PJ_UNUSED_ARG(strm);
- PJ_UNUSED_ARG(cap);
- PJ_UNUSED_ARG(value);
+ pj_status_t ret = PJ_SUCCESS;
+ struct bb10_stream *stream = (struct bb10_stream*)strm;
+
+ if (cap != PJMEDIA_AUD_DEV_CAP_OUTPUT_ROUTE || value == NULL) {
+ TRACE_((THIS_FILE,"bb10_stream_set_cap() = PJMEDIA_EAUD_INVCAP"));
+ return PJMEDIA_EAUD_INVCAP;
+
+ } else {
+ pjmedia_aud_dev_route route = *((pjmedia_aud_dev_route*)value);
+ /* Use the initialization function which lazy-inits the
+ * handle for routing
+ */
+ if (route == PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER) {
+ ret = bb10_initialize_playback_ctrl(stream,true);
+ } else {
+ ret = bb10_initialize_playback_ctrl(stream,false);
+ }
+ }
- return PJMEDIA_EAUD_INVCAP;
+ if (ret != PJ_SUCCESS) {
+ TRACE_((THIS_FILE,"bb10_stream_set_cap() = %d",ret));
+ }
+ return ret;
}
@@ -952,7 +1126,7 @@ static pj_status_t bb10_stream_stop (pjmedia_aud_stream *s)
static pj_status_t bb10_stream_destroy (pjmedia_aud_stream *s)
{
struct bb10_stream *stream = (struct bb10_stream*)s;
-
+
TRACE_((THIS_FILE,"bb10_stream_destroy()"));
bb10_stream_stop (s);
diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
index d2c6564..9b60ae1 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
@@ -1,4 +1,4 @@
-/* $Id: symb_aps_dev.cpp 3841 2011-10-24 09:28:13Z ming $ */
+/* $Id: symb_aps_dev.cpp 4243 2012-08-31 11:42:17Z nanang $ */
/*
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
@@ -973,7 +973,8 @@ static void RecCb(TAPSCommBuffer &buf, void *user_data)
{
unsigned samples_got;
- samples_got = strm->param.ext_fmt.bitrate == 15200? 160 : 240;
+ samples_got =
+ strm->param.ext_fmt.det.aud.avg_bps == 15200? 160 : 240;
/* Check if we got a normal frame. */
if (buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0) {
@@ -1171,9 +1172,9 @@ static void PlayCb(TAPSCommBuffer &buf, void *user_data)
sf = pjmedia_frame_ext_get_subframe(frame, 0);
samples_cnt = frame->samples_cnt / frame->subframe_cnt;
- pj_assert((strm->param.ext_fmt.bitrate == 15200 &&
+ pj_assert((strm->param.ext_fmt.det.aud.avg_bps == 15200 &&
samples_cnt == 160) ||
- (strm->param.ext_fmt.bitrate != 15200 &&
+ (strm->param.ext_fmt.det.aud.avg_bps != 15200 &&
samples_cnt == 240));
if (sf->data && sf->bitlen) {
@@ -1391,34 +1392,41 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
}
if (supported) {
+ pjmedia_format ext_fmt;
+
switch(i) {
case 0: /* AMRNB */
- af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_AMR;
- af->dev_info.ext_fmt[fmt_cnt].bitrate = 7400;
- af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_AMR,
+ 8000, 1, 16, 20, 7400, 12200);
+ af->dev_info.ext_fmt[fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE;
++fmt_cnt;
break;
case 1: /* G.711 */
- af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_PCMU;
- af->dev_info.ext_fmt[fmt_cnt].bitrate = 64000;
- af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_PCMU,
+ 8000, 1, 16, 20, 64000, 64000);
+ af->dev_info.ext_fmt[fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
++fmt_cnt;
- af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_PCMA;
- af->dev_info.ext_fmt[fmt_cnt].bitrate = 64000;
- af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_PCMA,
+ 8000, 1, 16, 20, 64000, 64000);
+ af->dev_info.ext_fmt[fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
++fmt_cnt;
g711_supported = PJ_TRUE;
break;
case 2: /* G.729 */
- af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_G729;
- af->dev_info.ext_fmt[fmt_cnt].bitrate = 8000;
- af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_G729,
+ 8000, 1, 16, 20, 8000, 8000);
+ af->dev_info.ext_fmt[fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[fmt_cnt].vad = PJ_FALSE;
++fmt_cnt;
break;
case 3: /* iLBC */
- af->dev_info.ext_fmt[fmt_cnt].id = PJMEDIA_FORMAT_ILBC;
- af->dev_info.ext_fmt[fmt_cnt].bitrate = 13333;
- af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_ILBC,
+ 8000, 1, 16, 30, 13333, 15200);
+ af->dev_info.ext_fmt[fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[fmt_cnt].vad = PJ_TRUE;
++fmt_cnt;
break;
}
@@ -1570,18 +1578,18 @@ static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
/* Set audio engine mode. */
if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_AMR)
{
- aps_setting.mode = (TAPSCodecMode)strm->param.ext_fmt.bitrate;
+ aps_setting.mode = (TAPSCodecMode)strm->param.ext_fmt.det.aud.avg_bps;
}
else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMU ||
strm->param.ext_fmt.id == PJMEDIA_FORMAT_L16 ||
(strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC &&
- strm->param.ext_fmt.bitrate != 15200))
+ strm->param.ext_fmt.det.aud.avg_bps != 15200))
{
aps_setting.mode = EULawOr30ms;
}
else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMA ||
(strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC &&
- strm->param.ext_fmt.bitrate == 15200))
+ strm->param.ext_fmt.det.aud.avg_bps == 15200))
{
aps_setting.mode = EALawOr20ms;
}
@@ -1596,11 +1604,13 @@ static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
{
aps_setting.vad = EFalse;
} else {
- aps_setting.vad = strm->param.ext_fmt.vad;
+ aps_setting.vad = (strm->param.flags & PJMEDIA_AUD_DEV_CAP_VAD) &&
+ strm->param.vad_enabled;
}
/* Set other audio engine attributes. */
- aps_setting.plc = strm->param.plc_enabled;
+ aps_setting.plc = (strm->param.flags & PJMEDIA_AUD_DEV_CAP_PLC) &&
+ strm->param.plc_enabled;
aps_setting.cng = aps_setting.vad;
aps_setting.loudspk =
strm->param.output_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;
diff --git a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
index 5b94903..70fe3b3 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
@@ -1,4 +1,4 @@
-/* $Id: symb_vas_dev.cpp 3841 2011-10-24 09:28:13Z ming $ */
+/* $Id: symb_vas_dev.cpp 4243 2012-08-31 11:42:17Z nanang $ */
/*
* Copyright (C) 2009-2011 Teluu Inc. (http://www.teluu.com)
*
@@ -1015,7 +1015,8 @@ static void RecCb(CVoIPDataBuffer *buf, void *user_data)
{
unsigned samples_got;
- samples_got = strm->param.ext_fmt.bitrate == 15200? 160 : 240;
+ samples_got =
+ strm->param.ext_fmt.det.aud.avg_bps == 15200? 160 : 240;
/* Check if we got a normal or SID frame. */
if (buffer[0] != 0) {
@@ -1214,9 +1215,9 @@ static void PlayCb(CVoIPDataBuffer *buf, void *user_data)
sf = pjmedia_frame_ext_get_subframe(frame, 0);
samples_cnt = frame->samples_cnt / frame->subframe_cnt;
- pj_assert((strm->param.ext_fmt.bitrate == 15200 &&
+ pj_assert((strm->param.ext_fmt.det.aud.avg_bps == 15200 &&
samples_cnt == 160) ||
- (strm->param.ext_fmt.bitrate != 15200 &&
+ (strm->param.ext_fmt.det.aud.avg_bps != 15200 &&
samples_cnt == 240));
if (sf->data && sf->bitlen) {
@@ -1230,7 +1231,8 @@ static void PlayCb(CVoIPDataBuffer *buf, void *user_data)
buffer.Append(0);
/* VAS iLBC frame is 20ms or 30ms */
- frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
+ frame_len =
+ strm->param.ext_fmt.det.aud.avg_bps == 15200? 38 : 50;
buffer.AppendFill(0, frame_len);
}
@@ -1244,7 +1246,8 @@ static void PlayCb(CVoIPDataBuffer *buf, void *user_data)
buffer.Append(0);
/* VAS iLBC frame is 20ms or 30ms */
- frame_len = strm->param.ext_fmt.bitrate == 15200? 38 : 50;
+ frame_len =
+ strm->param.ext_fmt.det.aud.avg_bps == 15200? 38 : 50;
buffer.AppendFill(0, frame_len);
}
@@ -1408,40 +1411,47 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
vas_factory_ = NULL;
for (TInt i = 0; i < dnlink_formats.Count(); i++) {
+ pjmedia_format ext_fmt;
+
/* Format must be supported by both downlink & uplink. */
if (uplink_formats.Find(dnlink_formats[i]) == KErrNotFound)
continue;
switch (dnlink_formats[i]) {
case EAMR_NB:
- af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_AMR;
- af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 7400;
- af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_AMR,
+ 8000, 1, 16, 20, 7400, 12200);
+ af->dev_info.ext_fmt[ext_fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
break;
case EG729:
- af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_G729;
- af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 8000;
- af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_G729,
+ 8000, 1, 16, 20, 8000, 8000);
+ af->dev_info.ext_fmt[ext_fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
break;
case EILBC:
- af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_ILBC;
- af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 13333;
- af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_ILBC,
+ 8000, 1, 16, 30, 13333, 15200);
+ af->dev_info.ext_fmt[ext_fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_TRUE;
break;
case EG711:
#if PJMEDIA_AUDIO_DEV_SYMB_VAS_VERSION==2
case EG711_10MS:
#endif
- af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMU;
- af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
- af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_PCMU,
+ 8000, 1, 16, 20, 64000, 64000);
+ af->dev_info.ext_fmt[ext_fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
++ext_fmt_cnt;
- af->dev_info.ext_fmt[ext_fmt_cnt].id = PJMEDIA_FORMAT_PCMA;
- af->dev_info.ext_fmt[ext_fmt_cnt].bitrate = 64000;
- af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
+ pjmedia_format_init_audio(&ext_fmt, PJMEDIA_FORMAT_PCMA,
+ 8000, 1, 16, 20, 64000, 64000);
+ af->dev_info.ext_fmt[ext_fmt_cnt] = ext_fmt;
+ //af->dev_info.ext_fmt[ext_fmt_cnt].vad = PJ_FALSE;
break;
default:
@@ -1616,7 +1626,7 @@ static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
}
else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_AMR)
{
- vas_setting.mode = strm->param.ext_fmt.bitrate;
+ vas_setting.mode = strm->param.ext_fmt.det.aud.avg_bps;
}
else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_PCMU)
{
@@ -1628,7 +1638,7 @@ static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
}
else if (strm->param.ext_fmt.id == PJMEDIA_FORMAT_ILBC)
{
- if (strm->param.ext_fmt.bitrate == 15200)
+ if (strm->param.ext_fmt.det.aud.avg_bps == 15200)
vas_setting.mode = CVoIPFormatIntfc::EiLBC20mSecFrame;
else
vas_setting.mode = CVoIPFormatIntfc::EiLBC30mSecFrame;
@@ -1647,11 +1657,13 @@ static pj_status_t factory_create_stream(pjmedia_aud_dev_factory *f,
{
vas_setting.vad = EFalse;
} else {
- vas_setting.vad = strm->param.ext_fmt.vad;
+ vas_setting.vad = (strm->param.flags & PJMEDIA_AUD_DEV_CAP_VAD) &&
+ strm->param.vad_enabled;
}
/* Set other audio engine attributes. */
- vas_setting.plc = strm->param.plc_enabled;
+ vas_setting.plc = (strm->param.flags & PJMEDIA_AUD_DEV_CAP_PLC) &&
+ strm->param.plc_enabled;
vas_setting.cng = vas_setting.vad;
vas_setting.loudspk =
strm->param.output_route==PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER;