Fixed unable to open simultaneous sound streams in MacOS
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@353 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
8482783fff
commit
a8df654b33
2 changed files with 86 additions and 32 deletions
|
@ -7,8 +7,11 @@
|
||||||
# (the library) for this specific operating system. Object files common
|
# (the library) for this specific operating system. Object files common
|
||||||
# to all operating systems should go in Makefile instead.
|
# to all operating systems should go in Makefile instead.
|
||||||
#
|
#
|
||||||
export PJMEDIA_OBJS += $(PA_DIR)/pa_mac_core.o $(PA_DIR)/pa_mac_hostapis.o \
|
export PJMEDIA_OBJS += $(PA_DIR)/pa_mac_hostapis.o \
|
||||||
$(PA_DIR)/pa_unix_util.o
|
$(PA_DIR)/pa_unix_util.o \
|
||||||
|
$(PA_DIR)/pa_mac_core.o
|
||||||
|
|
||||||
|
# $(PA_DIR)/pa_mac_alt.o
|
||||||
# $(PA_DIR)/ringbuffer.o
|
# $(PA_DIR)/ringbuffer.o
|
||||||
|
|
||||||
export OS_CFLAGS += $(CC_DEF)PA_USE_COREAUDIO=1 $(CC_DEF)PA_BIG_ENDIAN=1
|
export OS_CFLAGS += $(CC_DEF)PA_USE_COREAUDIO=1 $(CC_DEF)PA_BIG_ENDIAN=1
|
||||||
|
|
|
@ -24,7 +24,7 @@ static const char *desc =
|
||||||
" Print sound device info and test open device. \n"
|
" Print sound device info and test open device. \n"
|
||||||
" \n"
|
" \n"
|
||||||
" USAGE: \n"
|
" USAGE: \n"
|
||||||
" sndinfo [id r/p clockrate nchan bits] \n"
|
" sndinfo [id rec/play/both clockrate nchan bits] \n"
|
||||||
" \n"
|
" \n"
|
||||||
" DESCRIPTION: \n"
|
" DESCRIPTION: \n"
|
||||||
" When invoked without any arguments, it displays information about all \n"
|
" When invoked without any arguments, it displays information about all \n"
|
||||||
|
@ -33,7 +33,7 @@ static const char *desc =
|
||||||
" When invoked with arguments, the program tests if device can be opened \n"
|
" When invoked with arguments, the program tests if device can be opened \n"
|
||||||
" with the specified arguments. All these arguments must be specified: \n"
|
" with the specified arguments. All these arguments must be specified: \n"
|
||||||
" - id The device ID (-1 for the first capable device) \n"
|
" - id The device ID (-1 for the first capable device) \n"
|
||||||
" - r/p Specify r for recording/capture, p for playing. \n"
|
" - rec/play/both Specify which streams to open. \n"
|
||||||
" - clockrate Specify clock rate (e.g. 8000, 11025, etc.) \n"
|
" - clockrate Specify clock rate (e.g. 8000, 11025, etc.) \n"
|
||||||
" - nchan Number of channels (1=mono, 2=stereo). \n"
|
" - nchan Number of channels (1=mono, 2=stereo). \n"
|
||||||
" - bits Number of bits per sample (normally 16). \n";
|
" - bits Number of bits per sample (normally 16). \n";
|
||||||
|
@ -69,58 +69,102 @@ static void enum_devices(void)
|
||||||
i, info->name, info->input_count, info->output_count,
|
i, info->name, info->input_count, info->output_count,
|
||||||
info->default_samples_per_sec);
|
info->default_samples_per_sec);
|
||||||
}
|
}
|
||||||
|
puts("");
|
||||||
|
puts("Run with -h to get more options");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int play_counter;
|
||||||
|
static int rec_counter;
|
||||||
|
|
||||||
static pj_status_t play_cb(void *user_data, pj_uint32_t timestamp,
|
static pj_status_t play_cb(void *user_data, pj_uint32_t timestamp,
|
||||||
void *output, unsigned size)
|
void *output, unsigned size)
|
||||||
{
|
{
|
||||||
|
++play_counter;
|
||||||
return PJ_SUCCESS;
|
return PJ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pj_status_t rec_cb(void *user_data, pj_uint32_t timestamp,
|
static pj_status_t rec_cb(void *user_data, pj_uint32_t timestamp,
|
||||||
const void *input, unsigned size)
|
const void *input, unsigned size)
|
||||||
{
|
{
|
||||||
|
++rec_counter;
|
||||||
return PJ_SUCCESS;
|
return PJ_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_device(int dev_id, int capturing, int clock_rate,
|
static void app_perror(const char *title, pj_status_t status)
|
||||||
int nchannel, int bits)
|
|
||||||
{
|
{
|
||||||
pj_status_t status;
|
char errmsg[PJ_ERR_MSG_SIZE];
|
||||||
|
|
||||||
|
pj_strerror(status, errmsg, sizeof(errmsg));
|
||||||
|
printf( "%s: %s (err=%d)\n",
|
||||||
|
title, errmsg, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_device(int dev_id, pjmedia_dir dir,
|
||||||
|
int clock_rate, int nchannel, int bits)
|
||||||
|
{
|
||||||
|
pj_status_t status = PJ_SUCCESS;
|
||||||
unsigned nsamples;
|
unsigned nsamples;
|
||||||
pjmedia_snd_stream *strm;
|
pjmedia_snd_stream *strm;
|
||||||
|
const char *dirtype;
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case PJMEDIA_DIR_CAPTURE:
|
||||||
|
dirtype = "capture"; break;
|
||||||
|
case PJMEDIA_DIR_PLAYBACK:
|
||||||
|
dirtype = "playback"; break;
|
||||||
|
case PJMEDIA_DIR_CAPTURE_PLAYBACK:
|
||||||
|
dirtype = "capture/playback"; break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
nsamples = clock_rate * 20 / 1000;
|
nsamples = clock_rate * 20 / 1000;
|
||||||
|
|
||||||
printf( "Opening device %d: clockrate=%d, nchannel=%d, bits=%d, "
|
printf( "Opening device %d for %s: clockrate=%d, nchannel=%d, "
|
||||||
"nsamples=%d..\n",
|
"bits=%d, nsamples=%d..\n",
|
||||||
dev_id, clock_rate, nchannel, bits, nsamples);
|
dev_id, dirtype, clock_rate, nchannel, bits, nsamples);
|
||||||
|
|
||||||
if (capturing) {
|
if (dir == PJMEDIA_DIR_CAPTURE) {
|
||||||
status = pjmedia_snd_open_recorder( dev_id, clock_rate, nchannel,
|
status = pjmedia_snd_open_rec( dev_id, clock_rate, nchannel,
|
||||||
nsamples, bits, &rec_cb, NULL,
|
nsamples, bits, &rec_cb, NULL,
|
||||||
&strm);
|
&strm);
|
||||||
} else {
|
} else if (dir == PJMEDIA_DIR_PLAYBACK) {
|
||||||
status = pjmedia_snd_open_player( dev_id, clock_rate, nchannel,
|
status = pjmedia_snd_open_player( dev_id, clock_rate, nchannel,
|
||||||
nsamples, bits, &play_cb, NULL,
|
nsamples, bits, &play_cb, NULL,
|
||||||
&strm);
|
&strm);
|
||||||
|
} else {
|
||||||
|
status = pjmedia_snd_open( dev_id, dev_id, clock_rate, nchannel,
|
||||||
|
nsamples, bits, &rec_cb, &play_cb, NULL,
|
||||||
|
&strm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != PJ_SUCCESS) {
|
if (status != PJ_SUCCESS) {
|
||||||
char errmsg[PJ_ERR_MSG_SIZE];
|
app_perror("Unable to open device for capture", status);
|
||||||
|
|
||||||
pj_strerror(status, errmsg, sizeof(errmsg));
|
|
||||||
printf( "Error: unable to open device %d for %s: %s (err=%d)\n",
|
|
||||||
dev_id, (capturing ? "capture" : "playback"),
|
|
||||||
errmsg, status);
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else {
|
|
||||||
puts("Device opened successfully");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = pjmedia_snd_stream_start(strm);
|
||||||
|
if (status != PJ_SUCCESS) {
|
||||||
|
app_perror("Unable to start capture stream", status);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let playback/capture runs for a while */
|
||||||
|
pj_thread_sleep(1000);
|
||||||
|
|
||||||
pjmedia_snd_stream_close(strm);
|
pjmedia_snd_stream_close(strm);
|
||||||
|
|
||||||
|
if ((dir & PJMEDIA_DIR_CAPTURE) && rec_counter==0) {
|
||||||
|
printf("Error: capture stream was not running\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dir & PJMEDIA_DIR_PLAYBACK) && play_counter==0) {
|
||||||
|
printf("Error: playback stream was not running\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Success.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,18 +196,25 @@ int main(int argc, char *argv[])
|
||||||
} else if (argc == 6) {
|
} else if (argc == 6) {
|
||||||
|
|
||||||
int dev_id;
|
int dev_id;
|
||||||
int capturing;
|
pjmedia_dir dir;
|
||||||
int clock_rate;
|
int clock_rate;
|
||||||
int nchannel;
|
int nchannel;
|
||||||
int bits;
|
int bits;
|
||||||
|
|
||||||
dev_id = atoi(argv[1]);
|
dev_id = atoi(argv[1]);
|
||||||
capturing = (strcmp(argv[2], "r") == 0);
|
|
||||||
|
if (strcmp(argv[2], "rec")==0)
|
||||||
|
dir = PJMEDIA_DIR_CAPTURE;
|
||||||
|
else if (strcmp(argv[2], "play")==0)
|
||||||
|
dir = PJMEDIA_DIR_PLAYBACK;
|
||||||
|
else if (strcmp(argv[2], "both")==0)
|
||||||
|
dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
|
||||||
|
|
||||||
clock_rate = atoi(argv[3]);
|
clock_rate = atoi(argv[3]);
|
||||||
nchannel = atoi(argv[4]);
|
nchannel = atoi(argv[4]);
|
||||||
bits = atoi(argv[5]);
|
bits = atoi(argv[5]);
|
||||||
|
|
||||||
return open_device(dev_id, capturing, clock_rate, nchannel, bits);
|
return open_device(dev_id, dir, clock_rate, nchannel, bits);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
puts("Error: invalid arguments");
|
puts("Error: invalid arguments");
|
||||||
|
|
Loading…
Reference in a new issue