summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pjmedia/include/pjmedia/errno.h11
-rw-r--r--pjmedia/include/pjmedia/sound.h37
-rw-r--r--pjmedia/src/pjmedia/conference.c34
-rw-r--r--pjmedia/src/pjmedia/errno.c20
-rw-r--r--pjmedia/src/pjmedia/pasound.c125
-rw-r--r--pjmedia/src/pjmedia/portaudio/portaudio.h2
-rw-r--r--pjmedia/src/pjmedia/stream.c38
7 files changed, 133 insertions, 134 deletions
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index 354383b2..7537744a 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -30,6 +30,17 @@ PJ_BEGIN_DECL
#define PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
+/*
+ * Mapping from PortAudio error codes to pjmedia error space.
+ */
+#define PJMEDIA_PORTAUDIO_ERRNO_START (PJMEDIA_ERRNO_START+PJ_ERRNO_SPACE_SIZE-1000)
+
+/*
+ * Convert PortAudio error code to PJMEDIA error code.
+ */
+#define PJMEDIA_ERRNO_FROM_PORTAUDIO(err) (err+PJMEDIA_PORTAUDIO_ERRNO_START)
+
+
/************************************************************
* GENERIC/GENERAL PJMEDIA ERRORS
***********************************************************/
diff --git a/pjmedia/include/pjmedia/sound.h b/pjmedia/include/pjmedia/sound.h
index 53c0907d..ec7564fa 100644
--- a/pjmedia/include/pjmedia/sound.h
+++ b/pjmedia/include/pjmedia/sound.h
@@ -49,19 +49,6 @@ typedef struct pj_snd_dev_info
unsigned default_samples_per_sec;/**< Default sampling rate. */
} pj_snd_dev_info;
-/**
- * Sound device parameter, to be specified when calling #pj_snd_open_recorder
- * or #pj_snd_open_player.
- */
-typedef struct pj_snd_stream_info
-{
- unsigned samples_per_sec; /**< Sampling rate. */
- unsigned bits_per_sample; /**< No of bits per sample. */
- unsigned samples_per_frame; /**< No of samples per frame. */
- unsigned bytes_per_frame; /**< No of bytes per frame. */
- unsigned frames_per_packet; /**< No of frames per packet. */
-} pj_snd_stream_info;
-
/**
* This callback is called by player stream when it needs additional data
* to be played by the device. Application must fill in the whole of output
@@ -134,10 +121,14 @@ PJ_DECL(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index);
*
* @return Audio stream, or NULL if failed.
*/
-PJ_DECL(pj_snd_stream*) pj_snd_open_recorder(int index,
- const pj_snd_stream_info *param,
- pj_snd_rec_cb rec_cb,
- void *user_data);
+PJ_DECL(pj_status_t) pj_snd_open_recorder( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pj_snd_rec_cb rec_cb,
+ void *user_data,
+ pj_snd_stream **p_snd_strm);
/**
* Create a new audio stream for playing audio samples.
@@ -150,10 +141,14 @@ PJ_DECL(pj_snd_stream*) pj_snd_open_recorder(int index,
*
* @return Audio stream, or NULL if failed.
*/
-PJ_DECL(pj_snd_stream*) pj_snd_open_player(int index,
- const pj_snd_stream_info *param,
- pj_snd_play_cb play_cb,
- void *user_data);
+PJ_DECL(pj_status_t) pj_snd_open_player( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pj_snd_play_cb play_cb,
+ void *user_data,
+ pj_snd_stream **p_snd_strm );
/**
* Start the stream.
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index 90c24e63..3dbe7c5a 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -139,7 +139,6 @@ struct pjmedia_conf
unsigned clock_rate; /**< Sampling rate. */
unsigned samples_per_frame; /**< Samples per frame. */
unsigned bits_per_sample; /**< Bits per sample. */
- pj_snd_stream_info snd_info; /**< Sound device parameter. */
};
@@ -286,15 +285,6 @@ static pj_status_t create_sound_port( pj_pool_t *pool,
pj_status_t status;
- /* Init default sound device parameters. */
- pj_memset(&conf->snd_info, 0, sizeof(conf->snd_info));
- conf->snd_info.samples_per_sec = conf->clock_rate;
- conf->snd_info.bits_per_sample = conf->bits_per_sample;
- conf->snd_info.samples_per_frame = conf->samples_per_frame;
- conf->snd_info.bytes_per_frame = conf->samples_per_frame *
- conf->bits_per_sample / 8;
- conf->snd_info.frames_per_packet = 1;
-
/* Create port */
status = create_conf_port(pool, conf, NULL, &name, &conf_port);
@@ -388,22 +378,32 @@ PJ_DEF(pj_status_t) pjmedia_conf_create( pj_pool_t *pool,
*/
static pj_status_t create_sound( pjmedia_conf *conf )
{
+ pj_status_t status;
+
/* Open recorder only if mic is not disabled. */
if ((conf->options & PJMEDIA_CONF_NO_MIC) == 0) {
- conf->snd_rec = pj_snd_open_recorder(-1 ,&conf->snd_info,
- &rec_cb, conf);
- if (conf->snd_rec == NULL) {
- return -1;
+ status = pj_snd_open_recorder(-1, conf->clock_rate, 1,
+ conf->samples_per_frame,
+ conf->bits_per_sample,
+ &rec_cb, conf, &conf->snd_rec);
+ if (status != PJ_SUCCESS) {
+ conf->snd_rec = NULL;
+ return status;
}
}
/* Open player */
- conf->snd_player = pj_snd_open_player(-1, &conf->snd_info, &play_cb, conf);
- if (conf->snd_player == NULL) {
+ status = pj_snd_open_player(-1, conf->clock_rate, 1,
+ conf->samples_per_frame,
+ conf->bits_per_sample,
+ &play_cb, conf, &conf->snd_player);
+ if (status != PJ_SUCCESS) {
if (conf->snd_rec) {
pj_snd_stream_close(conf->snd_rec);
+ conf->snd_rec = NULL;
}
- return -1;
+ conf->snd_player = NULL;
+ return status;
}
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c
index 6fb71e0a..b9886796 100644
--- a/pjmedia/src/pjmedia/errno.c
+++ b/pjmedia/src/pjmedia/errno.c
@@ -18,6 +18,7 @@
*/
#include <pjmedia/errno.h>
#include <pj/string.h>
+#include <portaudio.h>
@@ -129,8 +130,23 @@ PJ_DEF(pj_str_t) pjmedia_strerror( pj_status_t statcode,
{
pj_str_t errstr;
- if (statcode >= PJMEDIA_ERRNO_START &&
- statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
+ /* See if the error comes from PortAudio. */
+ if (statcode >= PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized) &&
+ statcode < PJMEDIA_ERRNO_FROM_PORTAUDIO(paNotInitialized + 10000))
+ {
+
+ int pa_err = statcode - PJMEDIA_ERRNO_FROM_PORTAUDIO(0);
+ pj_str_t msg;
+
+ msg.ptr = (char*)Pa_GetErrorText(pa_err);
+ msg.slen = pj_ansi_strlen(msg.ptr);
+
+ errstr.ptr = buf;
+ pj_strncpy_with_null(&errstr, &msg, bufsize);
+ return errstr;
+
+ } else if (statcode >= PJMEDIA_ERRNO_START &&
+ statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
{
/* Find the error in the table.
* Use binary search!
diff --git a/pjmedia/src/pjmedia/pasound.c b/pjmedia/src/pjmedia/pasound.c
index 69a3c892..176f98ed 100644
--- a/pjmedia/src/pjmedia/pasound.c
+++ b/pjmedia/src/pjmedia/pasound.c
@@ -17,9 +17,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pjmedia/sound.h>
-#include <pj/string.h>
-#include <pj/os.h>
+#include <pjmedia/errno.h>
#include <pj/log.h>
+#include <pj/os.h>
+#include <pj/string.h>
#include <portaudio.h>
#define THIS_FILE "pasound.c"
@@ -37,6 +38,7 @@ struct pj_snd_stream
int dev_index;
int bytes_per_sample;
pj_uint32_t samples_per_sec;
+ int channel_count;
pj_uint32_t timestamp;
pj_uint32_t underflow;
pj_uint32_t overflow;
@@ -188,10 +190,14 @@ PJ_DEF(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index)
/*
* Open stream.
*/
-PJ_DEF(pj_snd_stream*) pj_snd_open_recorder( int index,
- const pj_snd_stream_info *param,
- pj_snd_rec_cb rec_cb,
- void *user_data)
+PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pj_snd_rec_cb rec_cb,
+ void *user_data,
+ pj_snd_stream **p_snd_strm)
{
pj_pool_t *pool;
pj_snd_stream *stream;
@@ -208,70 +214,75 @@ PJ_DEF(pj_snd_stream*) pj_snd_open_recorder( int index,
break;
}
if (index == count) {
- PJ_LOG(2,(THIS_FILE, "Error: unable to find recorder device"));
- return NULL;
+ /* No such device. */
+ return PJ_ENOTFOUND;
}
} else {
paDevInfo = Pa_GetDeviceInfo(index);
- if (!paDevInfo)
- return NULL;
+ if (!paDevInfo) {
+ /* Assumed it is "No such device" error. */
+ return PJ_ENOTFOUND;
+ }
}
- if (param->bits_per_sample == 8)
+ if (bits_per_sample == 8)
sampleFormat = paUInt8;
- else if (param->bits_per_sample == 16)
+ else if (bits_per_sample == 16)
sampleFormat = paInt16;
- else if (param->bits_per_sample == 32)
+ else if (bits_per_sample == 32)
sampleFormat = paInt32;
else
- return NULL;
+ return PJ_ENOTSUP;
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
if (!pool)
- return NULL;
+ return PJ_ENOMEM;
- stream = pj_pool_calloc(pool, 1, sizeof(*stream));
+ stream = pj_pool_zalloc(pool, sizeof(*stream));
stream->pool = pool;
- stream->name = pj_str("recorder");
+ stream->name = pj_str("snd-rec");
stream->user_data = user_data;
stream->dev_index = index;
- stream->samples_per_sec = param->samples_per_frame;
- stream->bytes_per_sample = param->bits_per_sample / 8;
+ stream->samples_per_sec = samples_per_frame;
+ stream->bytes_per_sample = bits_per_sample / 8;
+ stream->channel_count = channel_count;
stream->rec_cb = rec_cb;
pj_memset(&inputParam, 0, sizeof(inputParam));
inputParam.device = index;
- inputParam.channelCount = 1;
+ inputParam.channelCount = channel_count;
inputParam.hostApiSpecificStreamInfo = NULL;
inputParam.sampleFormat = sampleFormat;
inputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
err = Pa_OpenStream( &stream->stream, &inputParam, NULL,
- param->samples_per_sec,
- param->samples_per_frame * param->frames_per_packet,
- 0,
- &PaRecorderCallback, stream );
+ clock_rate, samples_per_frame,
+ 0, &PaRecorderCallback, stream );
if (err != paNoError) {
pj_pool_release(pool);
- PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err)));
- return NULL;
+ return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
}
PJ_LOG(5,(THIS_FILE, "%s opening device %s for recording, sample rate=%d, "
+ "channel count=%d, "
"%d bits per sample, %d samples per buffer",
(err==0 ? "Success" : "Error"),
- paDevInfo->name, param->samples_per_sec,
- param->bits_per_sample,
- param->samples_per_frame * param->frames_per_packet));
+ paDevInfo->name, clock_rate, channel_count,
+ bits_per_sample, samples_per_frame));
- return stream;
+ *p_snd_strm = stream;
+ return PJ_SUCCESS;
}
-PJ_DEF(pj_snd_stream*) pj_snd_open_player(int index,
- const pj_snd_stream_info *param,
- pj_snd_play_cb play_cb,
- void *user_data)
+PJ_DEF(pj_status_t) pj_snd_open_player( int index,
+ unsigned clock_rate,
+ unsigned channel_count,
+ unsigned samples_per_frame,
+ unsigned bits_per_sample,
+ pj_snd_play_cb play_cb,
+ void *user_data,
+ pj_snd_stream **p_snd_strm)
{
pj_pool_t *pool;
pj_snd_stream *stream;
@@ -288,63 +299,65 @@ PJ_DEF(pj_snd_stream*) pj_snd_open_player(int index,
break;
}
if (index == count) {
- PJ_LOG(2,(THIS_FILE, "Error: unable to find player device"));
- return NULL;
+ /* No such device. */
+ return PJ_ENOTFOUND;
}
} else {
paDevInfo = Pa_GetDeviceInfo(index);
- if (!paDevInfo)
- return NULL;
+ if (!paDevInfo) {
+ /* Assumed it is "No such device" error. */
+ return PJ_ENOTFOUND;
+ }
}
- if (param->bits_per_sample == 8)
+ if (bits_per_sample == 8)
sampleFormat = paUInt8;
- else if (param->bits_per_sample == 16)
+ else if (bits_per_sample == 16)
sampleFormat = paInt16;
- else if (param->bits_per_sample == 32)
+ else if (bits_per_sample == 32)
sampleFormat = paInt32;
else
- return NULL;
+ return PJ_ENOTSUP;
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
if (!pool)
- return NULL;
+ return PJ_ENOMEM;
stream = pj_pool_calloc(pool, 1, sizeof(*stream));
stream->pool = pool;
stream->name = pj_str("player");
stream->user_data = user_data;
- stream->samples_per_sec = param->samples_per_frame;
- stream->bytes_per_sample = param->bits_per_sample / 8;
+ stream->samples_per_sec = samples_per_frame;
+ stream->bytes_per_sample = bits_per_sample / 8;
+ stream->channel_count = channel_count;
stream->dev_index = index;
stream->play_cb = play_cb;
pj_memset(&outputParam, 0, sizeof(outputParam));
outputParam.device = index;
- outputParam.channelCount = 1;
+ outputParam.channelCount = channel_count;
outputParam.hostApiSpecificStreamInfo = NULL;
outputParam.sampleFormat = sampleFormat;
outputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
err = Pa_OpenStream( &stream->stream, NULL, &outputParam,
- param->samples_per_sec,
- param->samples_per_frame * param->frames_per_packet,
- 0,
- &PaPlayerCallback, stream );
+ clock_rate, samples_per_frame,
+ 0, &PaPlayerCallback, stream );
if (err != paNoError) {
pj_pool_release(pool);
- PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err)));
- return NULL;
+ return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
}
PJ_LOG(5,(THIS_FILE, "%s opening device %s for playing, sample rate=%d, "
+ "channel count=%d, "
"%d bits per sample, %d samples per buffer",
(err==0 ? "Success" : "Error"),
- paDevInfo->name, param->samples_per_sec,
- param->bits_per_sample,
- param->samples_per_frame * param->frames_per_packet));
+ paDevInfo->name, clock_rate, channel_count,
+ bits_per_sample, samples_per_frame));
+
+ *p_snd_strm = stream;
- return stream;
+ return PJ_SUCCESS;
}
diff --git a/pjmedia/src/pjmedia/portaudio/portaudio.h b/pjmedia/src/pjmedia/portaudio/portaudio.h
index 5d4a97ef..981dd0ac 100644
--- a/pjmedia/src/pjmedia/portaudio/portaudio.h
+++ b/pjmedia/src/pjmedia/portaudio/portaudio.h
@@ -64,7 +64,7 @@ typedef enum PaErrorCode
{
paNoError = 0,
- paNotInitialized = -10000,
+ paNotInitialized = 1, /* blp: changed from -10000 */
paUnanticipatedHostError,
paInvalidChannelCount,
paInvalidSampleRate,
diff --git a/pjmedia/src/pjmedia/stream.c b/pjmedia/src/pjmedia/stream.c
index 8b41a948..c2624b20 100644
--- a/pjmedia/src/pjmedia/stream.c
+++ b/pjmedia/src/pjmedia/stream.c
@@ -53,8 +53,6 @@ struct pjmedia_channel
pjmedia_dir dir; /**< Channel direction. */
unsigned pt; /**< Payload type. */
pj_bool_t paused; /**< Paused?. */
- pj_snd_stream_info snd_info; /**< Sound stream param. */
- //pj_snd_stream *snd_stream; /**< Sound stream. */
unsigned in_pkt_size; /**< Size of input buffer. */
void *in_pkt; /**< Input buffer. */
unsigned out_pkt_size; /**< Size of output buffer. */
@@ -278,7 +276,7 @@ static pj_status_t put_frame( pjmedia_port *port,
return -1;
/* Number of samples in the frame */
- ts_len = frame->size / (channel->snd_info.bits_per_sample / 8);
+ ts_len = frame->size / 2;
/* Init frame_out buffer. */
frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
@@ -564,24 +562,6 @@ static int PJ_THREAD_FUNC jitter_buffer_thread (void*arg)
/*
- * Create sound stream parameter from codec attributes.
- */
-static void init_snd_param( pj_snd_stream_info *snd_param,
- const pjmedia_codec_param *codec_param)
-{
- pj_memset(snd_param, 0, sizeof(*snd_param));
-
- snd_param->bits_per_sample = codec_param->pcm_bits_per_sample;
- snd_param->bytes_per_frame = 2;
- snd_param->frames_per_packet = codec_param->sample_rate *
- codec_param->ptime /
- 1000;
- snd_param->samples_per_frame = 1;
- snd_param->samples_per_sec = codec_param->sample_rate;
-}
-
-
-/*
* Create media channel.
*/
static pj_status_t create_channel( pj_pool_t *pool,
@@ -643,22 +623,6 @@ static pj_status_t create_channel( pj_pool_t *pool,
if (status != PJ_SUCCESS)
return status;
- /* Create and initialize sound device */
-
- init_snd_param(&channel->snd_info, codec_param);
-
- /*
- if (dir == PJMEDIA_DIR_ENCODING)
- channel->snd_stream = pj_snd_open_recorder(-1, &channel->snd_info,
- &rec_callback, channel);
- else
- channel->snd_stream = pj_snd_open_player(-1, &channel->snd_info,
- &play_callback, channel);
-
- if (!channel->snd_stream)
- return -1;
- */
-
/* Done. */
*p_channel = channel;
return PJ_SUCCESS;