summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-03-19 00:48:43 +0000
committerBenny Prijono <bennylp@teluu.com>2006-03-19 00:48:43 +0000
commit431b82df08e0061f6676122c731d40915fb747df (patch)
treea33965163cd3f5d2b84655feeaf3b48cb1dd1ebb /pjmedia
parent4d6e1b4cf1cbdec88bd4c4915fb27a16ee89acb4 (diff)
Tested and fixed stereo audio support
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@334 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/include/pjmedia/errno.h26
-rw-r--r--pjmedia/src/pjmedia/errno.c6
-rw-r--r--pjmedia/src/pjmedia/file_port.c13
-rw-r--r--pjmedia/src/pjmedia/pasound.c36
4 files changed, 65 insertions, 16 deletions
diff --git a/pjmedia/include/pjmedia/errno.h b/pjmedia/include/pjmedia/errno.h
index 3d95c44a..67c4d011 100644
--- a/pjmedia/include/pjmedia/errno.h
+++ b/pjmedia/include/pjmedia/errno.h
@@ -442,6 +442,32 @@ PJ_BEGIN_DECL
#define PJMEDIA_EWAVETOOSHORT (PJMEDIA_ERRNO_START+182) /* 220182 */
+/************************************************************
+ * SOUND DEVICE ERRORS
+ ***********************************************************/
+/**
+ * @hideinitializer
+ * No suitable audio capture device.
+ */
+#define PJMEDIA_ENOSNDREC (PJMEDIA_ERRNO_START+200) /* 220200 */
+/**
+ * @hideinitializer
+ * No suitable audio playback device.
+ */
+#define PJMEDIA_ENOSNDPLAY (PJMEDIA_ERRNO_START+201) /* 220201 */
+/**
+ * @hideinitializer
+ * Invalid sound device ID.
+ */
+#define PJMEDIA_ESNDINDEVID (PJMEDIA_ERRNO_START+202) /* 220202 */
+/**
+ * @hideinitializer
+ * Invalid sample format for sound device.
+ */
+#define PJMEDIA_ESNDINSAMPLEFMT (PJMEDIA_ERRNO_START+203) /* 220203 */
+
+
+
PJ_END_DECL
#endif /* __PJMEDIA_ERRNO_H__ */
diff --git a/pjmedia/src/pjmedia/errno.c b/pjmedia/src/pjmedia/errno.c
index 5a63e07e..7ea7af8c 100644
--- a/pjmedia/src/pjmedia/errno.c
+++ b/pjmedia/src/pjmedia/errno.c
@@ -122,6 +122,12 @@ static const struct
{ PJMEDIA_ENOTVALIDWAVE, "Not a valid WAVE file" },
{ PJMEDIA_EWAVEUNSUPP, "Unsupported WAVE file format" },
{ PJMEDIA_EWAVETOOSHORT, "WAVE file too short" },
+
+ /* Sound device errors: */
+ { PJMEDIA_ENOSNDREC, "No suitable sound capture device" },
+ { PJMEDIA_ENOSNDPLAY, "No suitable sound playback device" },
+ { PJMEDIA_ESNDINDEVID, "Invalid sound device ID" },
+ { PJMEDIA_ESNDINSAMPLEFMT, "Invalid sample format for sound device" },
};
#endif /* PJ_HAS_ERROR_STRING */
diff --git a/pjmedia/src/pjmedia/file_port.c b/pjmedia/src/pjmedia/file_port.c
index 573637be..11e59eec 100644
--- a/pjmedia/src/pjmedia/file_port.c
+++ b/pjmedia/src/pjmedia/file_port.c
@@ -199,14 +199,20 @@ PJ_DEF(pj_status_t) pjmedia_file_player_port_create( pj_pool_t *pool,
return PJMEDIA_ENOTVALIDWAVE;
}
+ /* Must be PCM with 16bits per sample */
if (wave_hdr.fmt_hdr.fmt_tag != 1 ||
- wave_hdr.fmt_hdr.bits_per_sample != 16 ||
- wave_hdr.fmt_hdr.block_align != 2)
+ wave_hdr.fmt_hdr.bits_per_sample != 16)
{
pj_file_close(fport->fd);
return PJMEDIA_EWAVEUNSUPP;
}
+ /* Block align must be 2*nchannels */
+ if (wave_hdr.fmt_hdr.block_align != wave_hdr.fmt_hdr.nchan*2) {
+ pj_file_close(fport->fd);
+ return PJMEDIA_EWAVEUNSUPP;
+ }
+
/* Validate length. */
if (wave_hdr.data_hdr.len != fport->fsize-sizeof(pjmedia_wave_hdr)) {
pj_file_close(fport->fd);
@@ -227,7 +233,8 @@ PJ_DEF(pj_status_t) pjmedia_file_player_port_create( pj_pool_t *pool,
fport->base.info.sample_rate = wave_hdr.fmt_hdr.sample_rate;
fport->base.info.bits_per_sample = wave_hdr.fmt_hdr.bits_per_sample;
fport->base.info.samples_per_frame = fport->base.info.sample_rate *
- 20 / 1000;
+ wave_hdr.fmt_hdr.nchan *
+ 20 / 1000;
fport->base.info.bytes_per_frame =
fport->base.info.samples_per_frame *
fport->base.info.bits_per_sample / 8;
diff --git a/pjmedia/src/pjmedia/pasound.c b/pjmedia/src/pjmedia/pasound.c
index ffac434c..cb36b927 100644
--- a/pjmedia/src/pjmedia/pasound.c
+++ b/pjmedia/src/pjmedia/pasound.c
@@ -85,7 +85,8 @@ static int PaRecorderCallback(const void *input,
stream->timestamp += frameCount;
status = (*stream->rec_cb)(stream->user_data, stream->timestamp,
- input, frameCount * stream->bytes_per_sample);
+ input, frameCount * stream->bytes_per_sample *
+ stream->channel_count);
if (status==0)
return paContinue;
@@ -104,7 +105,8 @@ static int PaPlayerCallback( const void *input,
{
pjmedia_snd_stream *stream = userData;
pj_status_t status;
- unsigned size = frameCount * stream->bytes_per_sample;
+ unsigned size = frameCount * stream->bytes_per_sample *
+ stream->channel_count;
PJ_UNUSED_ARG(input);
PJ_UNUSED_ARG(timeInfo);
@@ -206,6 +208,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
PaStreamParameters inputParam;
int sampleFormat;
const PaDeviceInfo *paDevInfo = NULL;
+ unsigned paFrames;
PaError err;
if (index == -1) {
@@ -217,13 +220,13 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
}
if (index == count) {
/* No such device. */
- return PJ_ENOTFOUND;
+ return PJMEDIA_ENOSNDREC;
}
} else {
paDevInfo = Pa_GetDeviceInfo(index);
if (!paDevInfo) {
/* Assumed it is "No such device" error. */
- return PJ_ENOTFOUND;
+ return PJMEDIA_ESNDINDEVID;
}
}
@@ -234,7 +237,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
else if (bits_per_sample == 32)
sampleFormat = paInt32;
else
- return PJ_ENOTSUP;
+ return PJMEDIA_ESNDINSAMPLEFMT;
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
if (!pool)
@@ -257,9 +260,12 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_recorder( int index,
inputParam.sampleFormat = sampleFormat;
inputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
+ /* Frames in PortAudio is number of samples in a single channel */
+ paFrames = samples_per_frame / channel_count;
+
err = Pa_OpenStream( &stream->stream, &inputParam, NULL,
- clock_rate, samples_per_frame,
- 0, &PaRecorderCallback, stream );
+ clock_rate, paFrames,
+ paClipOff, &PaRecorderCallback, stream );
if (err != paNoError) {
pj_pool_release(pool);
return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
@@ -291,6 +297,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
PaStreamParameters outputParam;
int sampleFormat;
const PaDeviceInfo *paDevInfo = NULL;
+ unsigned paFrames;
PaError err;
if (index == -1) {
@@ -302,13 +309,13 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
}
if (index == count) {
/* No such device. */
- return PJ_ENOTFOUND;
+ return PJMEDIA_ENOSNDPLAY;
}
} else {
paDevInfo = Pa_GetDeviceInfo(index);
if (!paDevInfo) {
/* Assumed it is "No such device" error. */
- return PJ_ENOTFOUND;
+ return PJMEDIA_ESNDINDEVID;
}
}
@@ -319,7 +326,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
else if (bits_per_sample == 32)
sampleFormat = paInt32;
else
- return PJ_ENOTSUP;
+ return PJMEDIA_ESNDINSAMPLEFMT;
pool = pj_pool_create( snd_mgr.factory, "sndstream", 1024, 1024, NULL);
if (!pool)
@@ -342,9 +349,12 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
outputParam.sampleFormat = sampleFormat;
outputParam.suggestedLatency = paDevInfo->defaultLowInputLatency;
+ /* Frames in PortAudio is number of samples in a single channel */
+ paFrames = samples_per_frame / channel_count;
+
err = Pa_OpenStream( &stream->stream, NULL, &outputParam,
- clock_rate, samples_per_frame,
- 0, &PaPlayerCallback, stream );
+ clock_rate, paFrames,
+ paClipOff, &PaPlayerCallback, stream );
if (err != paNoError) {
pj_pool_release(pool);
return PJMEDIA_ERRNO_FROM_PORTAUDIO(err);
@@ -352,7 +362,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_open_player( int index,
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 frame",
(err==0 ? "Success" : "Error"),
paDevInfo->name, clock_rate, channel_count,
bits_per_sample, samples_per_frame));