Tidying up sound device, register PortAudio error codes, and initial support for stereo sound device (untested)
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@319 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
de38058342
commit
de8a259f42
|
@ -30,6 +30,17 @@ PJ_BEGIN_DECL
|
||||||
#define PJMEDIA_ERRNO_START (PJ_ERRNO_START_USER + PJ_ERRNO_SPACE_SIZE)
|
#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
|
* GENERIC/GENERAL PJMEDIA ERRORS
|
||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
|
@ -49,19 +49,6 @@ typedef struct pj_snd_dev_info
|
||||||
unsigned default_samples_per_sec;/**< Default sampling rate. */
|
unsigned default_samples_per_sec;/**< Default sampling rate. */
|
||||||
} pj_snd_dev_info;
|
} 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
|
* 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
|
* 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.
|
* @return Audio stream, or NULL if failed.
|
||||||
*/
|
*/
|
||||||
PJ_DECL(pj_snd_stream*) pj_snd_open_recorder(int index,
|
PJ_DECL(pj_status_t) pj_snd_open_recorder( int index,
|
||||||
const pj_snd_stream_info *param,
|
unsigned clock_rate,
|
||||||
|
unsigned channel_count,
|
||||||
|
unsigned samples_per_frame,
|
||||||
|
unsigned bits_per_sample,
|
||||||
pj_snd_rec_cb rec_cb,
|
pj_snd_rec_cb rec_cb,
|
||||||
void *user_data);
|
void *user_data,
|
||||||
|
pj_snd_stream **p_snd_strm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new audio stream for playing audio samples.
|
* 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.
|
* @return Audio stream, or NULL if failed.
|
||||||
*/
|
*/
|
||||||
PJ_DECL(pj_snd_stream*) pj_snd_open_player(int index,
|
PJ_DECL(pj_status_t) pj_snd_open_player( int index,
|
||||||
const pj_snd_stream_info *param,
|
unsigned clock_rate,
|
||||||
|
unsigned channel_count,
|
||||||
|
unsigned samples_per_frame,
|
||||||
|
unsigned bits_per_sample,
|
||||||
pj_snd_play_cb play_cb,
|
pj_snd_play_cb play_cb,
|
||||||
void *user_data);
|
void *user_data,
|
||||||
|
pj_snd_stream **p_snd_strm );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the stream.
|
* Start the stream.
|
||||||
|
|
|
@ -139,7 +139,6 @@ struct pjmedia_conf
|
||||||
unsigned clock_rate; /**< Sampling rate. */
|
unsigned clock_rate; /**< Sampling rate. */
|
||||||
unsigned samples_per_frame; /**< Samples per frame. */
|
unsigned samples_per_frame; /**< Samples per frame. */
|
||||||
unsigned bits_per_sample; /**< Bits per sample. */
|
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;
|
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 */
|
/* Create port */
|
||||||
status = create_conf_port(pool, conf, NULL, &name, &conf_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 )
|
static pj_status_t create_sound( pjmedia_conf *conf )
|
||||||
{
|
{
|
||||||
|
pj_status_t status;
|
||||||
|
|
||||||
/* Open recorder only if mic is not disabled. */
|
/* Open recorder only if mic is not disabled. */
|
||||||
if ((conf->options & PJMEDIA_CONF_NO_MIC) == 0) {
|
if ((conf->options & PJMEDIA_CONF_NO_MIC) == 0) {
|
||||||
conf->snd_rec = pj_snd_open_recorder(-1 ,&conf->snd_info,
|
status = pj_snd_open_recorder(-1, conf->clock_rate, 1,
|
||||||
&rec_cb, conf);
|
conf->samples_per_frame,
|
||||||
if (conf->snd_rec == NULL) {
|
conf->bits_per_sample,
|
||||||
return -1;
|
&rec_cb, conf, &conf->snd_rec);
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
|
conf->snd_rec = NULL;
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open player */
|
/* Open player */
|
||||||
conf->snd_player = pj_snd_open_player(-1, &conf->snd_info, &play_cb, conf);
|
status = pj_snd_open_player(-1, conf->clock_rate, 1,
|
||||||
if (conf->snd_player == NULL) {
|
conf->samples_per_frame,
|
||||||
|
conf->bits_per_sample,
|
||||||
|
&play_cb, conf, &conf->snd_player);
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
if (conf->snd_rec) {
|
if (conf->snd_rec) {
|
||||||
pj_snd_stream_close(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;
|
return PJ_SUCCESS;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
#include <pjmedia/errno.h>
|
#include <pjmedia/errno.h>
|
||||||
#include <pj/string.h>
|
#include <pj/string.h>
|
||||||
|
#include <portaudio.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,7 +130,22 @@ PJ_DEF(pj_str_t) pjmedia_strerror( pj_status_t statcode,
|
||||||
{
|
{
|
||||||
pj_str_t errstr;
|
pj_str_t errstr;
|
||||||
|
|
||||||
if (statcode >= PJMEDIA_ERRNO_START &&
|
/* 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)
|
statcode < PJMEDIA_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
|
||||||
{
|
{
|
||||||
/* Find the error in the table.
|
/* Find the error in the table.
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include <pjmedia/sound.h>
|
#include <pjmedia/sound.h>
|
||||||
#include <pj/string.h>
|
#include <pjmedia/errno.h>
|
||||||
#include <pj/os.h>
|
|
||||||
#include <pj/log.h>
|
#include <pj/log.h>
|
||||||
|
#include <pj/os.h>
|
||||||
|
#include <pj/string.h>
|
||||||
#include <portaudio.h>
|
#include <portaudio.h>
|
||||||
|
|
||||||
#define THIS_FILE "pasound.c"
|
#define THIS_FILE "pasound.c"
|
||||||
|
@ -37,6 +38,7 @@ struct pj_snd_stream
|
||||||
int dev_index;
|
int dev_index;
|
||||||
int bytes_per_sample;
|
int bytes_per_sample;
|
||||||
pj_uint32_t samples_per_sec;
|
pj_uint32_t samples_per_sec;
|
||||||
|
int channel_count;
|
||||||
pj_uint32_t timestamp;
|
pj_uint32_t timestamp;
|
||||||
pj_uint32_t underflow;
|
pj_uint32_t underflow;
|
||||||
pj_uint32_t overflow;
|
pj_uint32_t overflow;
|
||||||
|
@ -188,10 +190,14 @@ PJ_DEF(const pj_snd_dev_info*) pj_snd_get_dev_info(unsigned index)
|
||||||
/*
|
/*
|
||||||
* Open stream.
|
* Open stream.
|
||||||
*/
|
*/
|
||||||
PJ_DEF(pj_snd_stream*) pj_snd_open_recorder( int index,
|
PJ_DEF(pj_status_t) pj_snd_open_recorder( int index,
|
||||||
const pj_snd_stream_info *param,
|
unsigned clock_rate,
|
||||||
|
unsigned channel_count,
|
||||||
|
unsigned samples_per_frame,
|
||||||
|
unsigned bits_per_sample,
|
||||||
pj_snd_rec_cb rec_cb,
|
pj_snd_rec_cb rec_cb,
|
||||||
void *user_data)
|
void *user_data,
|
||||||
|
pj_snd_stream **p_snd_strm)
|
||||||
{
|
{
|
||||||
pj_pool_t *pool;
|
pj_pool_t *pool;
|
||||||
pj_snd_stream *stream;
|
pj_snd_stream *stream;
|
||||||
|
@ -208,70 +214,75 @@ PJ_DEF(pj_snd_stream*) pj_snd_open_recorder( int index,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index == count) {
|
if (index == count) {
|
||||||
PJ_LOG(2,(THIS_FILE, "Error: unable to find recorder device"));
|
/* No such device. */
|
||||||
return NULL;
|
return PJ_ENOTFOUND;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paDevInfo = Pa_GetDeviceInfo(index);
|
paDevInfo = Pa_GetDeviceInfo(index);
|
||||||
if (!paDevInfo)
|
if (!paDevInfo) {
|
||||||
return NULL;
|
/* Assumed it is "No such device" error. */
|
||||||
|
return PJ_ENOTFOUND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->bits_per_sample == 8)
|
if (bits_per_sample == 8)
|
||||||
sampleFormat = paUInt8;
|
sampleFormat = paUInt8;
|
||||||
else if (param->bits_per_sample == 16)
|
else if (bits_per_sample == 16)
|
||||||
sampleFormat = paInt16;
|
sampleFormat = paInt16;
|
||||||
else if (param->bits_per_sample == 32)
|
else if (bits_per_sample == 32)
|
||||||
sampleFormat = paInt32;
|
sampleFormat = paInt32;
|
||||||
else
|
else
|
||||||
return NULL;
|
return PJ_ENOTSUP;
|
||||||
|
|
||||||
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
|
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
|
||||||
if (!pool)
|
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->pool = pool;
|
||||||
stream->name = pj_str("recorder");
|
stream->name = pj_str("snd-rec");
|
||||||
stream->user_data = user_data;
|
stream->user_data = user_data;
|
||||||
stream->dev_index = index;
|
stream->dev_index = index;
|
||||||
stream->samples_per_sec = param->samples_per_frame;
|
stream->samples_per_sec = samples_per_frame;
|
||||||
stream->bytes_per_sample = param->bits_per_sample / 8;
|
stream->bytes_per_sample = bits_per_sample / 8;
|
||||||
|
stream->channel_count = channel_count;
|
||||||
stream->rec_cb = rec_cb;
|
stream->rec_cb = rec_cb;
|
||||||
|
|
||||||
pj_memset(&inputParam, 0, sizeof(inputParam));
|
pj_memset(&inputParam, 0, sizeof(inputParam));
|
||||||
inputParam.device = index;
|
inputParam.device = index;
|
||||||
inputParam.channelCount = 1;
|
inputParam.channelCount = channel_count;
|
||||||
inputParam.hostApiSpecificStreamInfo = NULL;
|
inputParam.hostApiSpecificStreamInfo = NULL;
|
||||||
inputParam.sampleFormat = sampleFormat;
|
inputParam.sampleFormat = sampleFormat;
|
||||||
inputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
|
inputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
|
||||||
|
|
||||||
err = Pa_OpenStream( &stream->stream, &inputParam, NULL,
|
err = Pa_OpenStream( &stream->stream, &inputParam, NULL,
|
||||||
param->samples_per_sec,
|
clock_rate, samples_per_frame,
|
||||||
param->samples_per_frame * param->frames_per_packet,
|
0, &PaRecorderCallback, stream );
|
||||||
0,
|
|
||||||
&PaRecorderCallback, stream );
|
|
||||||
if (err != paNoError) {
|
if (err != paNoError) {
|
||||||
pj_pool_release(pool);
|
pj_pool_release(pool);
|
||||||
PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err)));
|
return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PJ_LOG(5,(THIS_FILE, "%s opening device %s for recording, sample rate=%d, "
|
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",
|
"%d bits per sample, %d samples per buffer",
|
||||||
(err==0 ? "Success" : "Error"),
|
(err==0 ? "Success" : "Error"),
|
||||||
paDevInfo->name, param->samples_per_sec,
|
paDevInfo->name, clock_rate, channel_count,
|
||||||
param->bits_per_sample,
|
bits_per_sample, samples_per_frame));
|
||||||
param->samples_per_frame * param->frames_per_packet));
|
|
||||||
|
|
||||||
return stream;
|
*p_snd_strm = stream;
|
||||||
|
return PJ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PJ_DEF(pj_snd_stream*) pj_snd_open_player(int index,
|
PJ_DEF(pj_status_t) pj_snd_open_player( int index,
|
||||||
const pj_snd_stream_info *param,
|
unsigned clock_rate,
|
||||||
|
unsigned channel_count,
|
||||||
|
unsigned samples_per_frame,
|
||||||
|
unsigned bits_per_sample,
|
||||||
pj_snd_play_cb play_cb,
|
pj_snd_play_cb play_cb,
|
||||||
void *user_data)
|
void *user_data,
|
||||||
|
pj_snd_stream **p_snd_strm)
|
||||||
{
|
{
|
||||||
pj_pool_t *pool;
|
pj_pool_t *pool;
|
||||||
pj_snd_stream *stream;
|
pj_snd_stream *stream;
|
||||||
|
@ -288,63 +299,65 @@ PJ_DEF(pj_snd_stream*) pj_snd_open_player(int index,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index == count) {
|
if (index == count) {
|
||||||
PJ_LOG(2,(THIS_FILE, "Error: unable to find player device"));
|
/* No such device. */
|
||||||
return NULL;
|
return PJ_ENOTFOUND;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paDevInfo = Pa_GetDeviceInfo(index);
|
paDevInfo = Pa_GetDeviceInfo(index);
|
||||||
if (!paDevInfo)
|
if (!paDevInfo) {
|
||||||
return NULL;
|
/* Assumed it is "No such device" error. */
|
||||||
|
return PJ_ENOTFOUND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param->bits_per_sample == 8)
|
if (bits_per_sample == 8)
|
||||||
sampleFormat = paUInt8;
|
sampleFormat = paUInt8;
|
||||||
else if (param->bits_per_sample == 16)
|
else if (bits_per_sample == 16)
|
||||||
sampleFormat = paInt16;
|
sampleFormat = paInt16;
|
||||||
else if (param->bits_per_sample == 32)
|
else if (bits_per_sample == 32)
|
||||||
sampleFormat = paInt32;
|
sampleFormat = paInt32;
|
||||||
else
|
else
|
||||||
return NULL;
|
return PJ_ENOTSUP;
|
||||||
|
|
||||||
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
|
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
|
||||||
if (!pool)
|
if (!pool)
|
||||||
return NULL;
|
return PJ_ENOMEM;
|
||||||
|
|
||||||
stream = pj_pool_calloc(pool, 1, sizeof(*stream));
|
stream = pj_pool_calloc(pool, 1, sizeof(*stream));
|
||||||
stream->pool = pool;
|
stream->pool = pool;
|
||||||
stream->name = pj_str("player");
|
stream->name = pj_str("player");
|
||||||
stream->user_data = user_data;
|
stream->user_data = user_data;
|
||||||
stream->samples_per_sec = param->samples_per_frame;
|
stream->samples_per_sec = samples_per_frame;
|
||||||
stream->bytes_per_sample = param->bits_per_sample / 8;
|
stream->bytes_per_sample = bits_per_sample / 8;
|
||||||
|
stream->channel_count = channel_count;
|
||||||
stream->dev_index = index;
|
stream->dev_index = index;
|
||||||
stream->play_cb = play_cb;
|
stream->play_cb = play_cb;
|
||||||
|
|
||||||
pj_memset(&outputParam, 0, sizeof(outputParam));
|
pj_memset(&outputParam, 0, sizeof(outputParam));
|
||||||
outputParam.device = index;
|
outputParam.device = index;
|
||||||
outputParam.channelCount = 1;
|
outputParam.channelCount = channel_count;
|
||||||
outputParam.hostApiSpecificStreamInfo = NULL;
|
outputParam.hostApiSpecificStreamInfo = NULL;
|
||||||
outputParam.sampleFormat = sampleFormat;
|
outputParam.sampleFormat = sampleFormat;
|
||||||
outputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
|
outputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
|
||||||
|
|
||||||
err = Pa_OpenStream( &stream->stream, NULL, &outputParam,
|
err = Pa_OpenStream( &stream->stream, NULL, &outputParam,
|
||||||
param->samples_per_sec,
|
clock_rate, samples_per_frame,
|
||||||
param->samples_per_frame * param->frames_per_packet,
|
0, &PaPlayerCallback, stream );
|
||||||
0,
|
|
||||||
&PaPlayerCallback, stream );
|
|
||||||
if (err != paNoError) {
|
if (err != paNoError) {
|
||||||
pj_pool_release(pool);
|
pj_pool_release(pool);
|
||||||
PJ_LOG(2,(THIS_FILE, "Error opening player: %s", Pa_GetErrorText(err)));
|
return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PJ_LOG(5,(THIS_FILE, "%s opening device %s for playing, sample rate=%d, "
|
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",
|
"%d bits per sample, %d samples per buffer",
|
||||||
(err==0 ? "Success" : "Error"),
|
(err==0 ? "Success" : "Error"),
|
||||||
paDevInfo->name, param->samples_per_sec,
|
paDevInfo->name, clock_rate, channel_count,
|
||||||
param->bits_per_sample,
|
bits_per_sample, samples_per_frame));
|
||||||
param->samples_per_frame * param->frames_per_packet));
|
|
||||||
|
|
||||||
return stream;
|
*p_snd_strm = stream;
|
||||||
|
|
||||||
|
return PJ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ typedef enum PaErrorCode
|
||||||
{
|
{
|
||||||
paNoError = 0,
|
paNoError = 0,
|
||||||
|
|
||||||
paNotInitialized = -10000,
|
paNotInitialized = 1, /* blp: changed from -10000 */
|
||||||
paUnanticipatedHostError,
|
paUnanticipatedHostError,
|
||||||
paInvalidChannelCount,
|
paInvalidChannelCount,
|
||||||
paInvalidSampleRate,
|
paInvalidSampleRate,
|
||||||
|
|
|
@ -53,8 +53,6 @@ struct pjmedia_channel
|
||||||
pjmedia_dir dir; /**< Channel direction. */
|
pjmedia_dir dir; /**< Channel direction. */
|
||||||
unsigned pt; /**< Payload type. */
|
unsigned pt; /**< Payload type. */
|
||||||
pj_bool_t paused; /**< Paused?. */
|
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. */
|
unsigned in_pkt_size; /**< Size of input buffer. */
|
||||||
void *in_pkt; /**< Input buffer. */
|
void *in_pkt; /**< Input buffer. */
|
||||||
unsigned out_pkt_size; /**< Size of output buffer. */
|
unsigned out_pkt_size; /**< Size of output buffer. */
|
||||||
|
@ -278,7 +276,7 @@ static pj_status_t put_frame( pjmedia_port *port,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Number of samples in the frame */
|
/* 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. */
|
/* Init frame_out buffer. */
|
||||||
frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
|
frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
|
||||||
|
@ -563,24 +561,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.
|
* Create media channel.
|
||||||
*/
|
*/
|
||||||
|
@ -643,22 +623,6 @@ static pj_status_t create_channel( pj_pool_t *pool,
|
||||||
if (status != PJ_SUCCESS)
|
if (status != PJ_SUCCESS)
|
||||||
return status;
|
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. */
|
/* Done. */
|
||||||
*p_channel = channel;
|
*p_channel = channel;
|
||||||
return PJ_SUCCESS;
|
return PJ_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue