提交 739ff9d3 authored 作者: Moises Silva's avatar Moises Silva

mod_portaudio: implement endpoint writes and multiplex read/writes in pablio streams

上级 fbce9061
...@@ -389,7 +389,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session) ...@@ -389,7 +389,7 @@ static switch_status_t channel_on_routing(switch_core_session_t *session)
if (globals.ring_stream && (! switch_test_flag(globals.call_list, TFLAG_MASTER) || if (globals.ring_stream && (! switch_test_flag(globals.call_list, TFLAG_MASTER) ||
( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream ( !globals.no_ring_during_call && globals.main_stream != globals.ring_stream)) ) { //if there is a ring stream and not an active call or if there is an active call and we are allowed to ring during it AND the ring stream is not the main stream
WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, &globals.ring_stream->write_timer); WriteAudioStream(globals.ring_stream->stream, abuf, (long) olen, 0, &globals.ring_stream->write_timer);
} }
} else { } else {
switch_yield(10000); switch_yield(10000);
...@@ -814,7 +814,7 @@ static switch_status_t channel_endpoint_read(audio_endpoint_t *endpoint, switch_ ...@@ -814,7 +814,7 @@ static switch_status_t channel_endpoint_read(audio_endpoint_t *endpoint, switch_
samples = ReadAudioStream(endpoint->in_stream->stream, samples = ReadAudioStream(endpoint->in_stream->stream,
endpoint->read_frame.data, STREAM_SAMPLES_PER_PACKET(endpoint->in_stream), endpoint->read_frame.data, STREAM_SAMPLES_PER_PACKET(endpoint->in_stream),
&endpoint->read_timer); endpoint->inchan, &endpoint->read_timer);
if (!samples) { if (!samples) {
*frame = &globals.cng_frame; *frame = &globals.cng_frame;
...@@ -900,7 +900,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch ...@@ -900,7 +900,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} }
switch_mutex_lock(globals.device_lock); switch_mutex_lock(globals.device_lock);
samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer); samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, 0, &globals.read_timer);
switch_mutex_unlock(globals.device_lock); switch_mutex_unlock(globals.device_lock);
if (samples) { if (samples) {
...@@ -931,12 +931,28 @@ normal_return: ...@@ -931,12 +931,28 @@ normal_return:
} }
static switch_status_t channel_endpoint_write(audio_endpoint_t *endpoint, switch_frame_t *frame)
{
if (!endpoint->out_stream) {
switch_core_timer_next(&endpoint->write_timer);
return SWITCH_STATUS_SUCCESS;
}
WriteAudioStream(endpoint->out_stream->stream, (short *)frame->data,
(int)(frame->datalen / sizeof(SAMPLE)),
endpoint->outchan, &(endpoint->write_timer));
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
{ {
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
private_t *tech_pvt = switch_core_session_get_private(session); private_t *tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL); switch_assert(tech_pvt != NULL);
if (tech_pvt->audio_endpoint) {
return channel_endpoint_write(tech_pvt->audio_endpoint, frame);
}
if (!globals.main_stream) { if (!globals.main_stream) {
return SWITCH_STATUS_FALSE; return SWITCH_STATUS_FALSE;
} }
...@@ -951,7 +967,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc ...@@ -951,7 +967,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
if (globals.main_stream) { if (globals.main_stream) {
if (switch_test_flag((&globals), GFLAG_EAR)) { if (switch_test_flag((&globals), GFLAG_EAR)) {
WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), &(globals.main_stream->write_timer)); WriteAudioStream(globals.main_stream->stream, (short *) frame->data, (int) (frame->datalen / sizeof(SAMPLE)), 0, &(globals.main_stream->write_timer));
} }
status = SWITCH_STATUS_SUCCESS; status = SWITCH_STATUS_SUCCESS;
} }
...@@ -1876,7 +1892,7 @@ static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char ...@@ -1876,7 +1892,7 @@ static switch_status_t play_dev(switch_stream_handle_t *stream, int outdev, char
break; break;
} }
WriteAudioStream(audio_stream->stream, abuf, (long) olen, &(audio_stream->write_timer)); WriteAudioStream(audio_stream->stream, abuf, (long) olen, 0, &(audio_stream->write_timer));
wrote += (int) olen; wrote += (int) olen;
if (samples) { if (samples) {
samples -= (int) olen; samples -= (int) olen;
...@@ -2555,8 +2571,8 @@ static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *s ...@@ -2555,8 +2571,8 @@ static switch_status_t looptest(char **argv, int argc, switch_stream_handle_t *s
if (globals.destroying_streams || ! globals.main_stream->stream) { if (globals.destroying_streams || ! globals.main_stream->stream) {
break; break;
} }
if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, &globals.read_timer))) { if ((samples = ReadAudioStream(globals.main_stream->stream, globals.read_frame.data, globals.read_codec.implementation->samples_per_packet, 0, &globals.read_timer))) {
WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, &(globals.main_stream->write_timer)); WriteAudioStream(globals.main_stream->stream, globals.read_frame.data, (long) samples, 0, &(globals.main_stream->write_timer));
success = 1; success = 1;
} }
switch_yield(10000); switch_yield(10000);
......
...@@ -143,7 +143,7 @@ static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf) ...@@ -143,7 +143,7 @@ static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf)
* Write data to ring buffer. * Write data to ring buffer.
* Will not return until all the data has been written. * Will not return until all the data has been written.
*/ */
long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer) long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer)
{ {
long bytesWritten; long bytesWritten;
char *p = (char *) data; char *p = (char *) data;
...@@ -151,12 +151,12 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc ...@@ -151,12 +151,12 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc
switch_core_timer_next(timer); switch_core_timer_next(timer);
bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFOs[0], p, numBytes); bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFOs[chan], p, numBytes);
numBytes -= bytesWritten; numBytes -= bytesWritten;
p += bytesWritten; p += bytesWritten;
if (numBytes > 0) { if (numBytes > 0) {
PaUtil_FlushRingBuffer(&aStream->outFIFOs[0]); PaUtil_FlushRingBuffer(&aStream->outFIFOs[chan]);
return 0; return 0;
} }
return numFrames; return numFrames;
...@@ -166,7 +166,7 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc ...@@ -166,7 +166,7 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc
* Read data from ring buffer. * Read data from ring buffer.
* Will not return until all the data has been read. * Will not return until all the data has been read.
*/ */
long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer) long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer)
{ {
long bytesRead = 0; long bytesRead = 0;
char *p = (char *) data; char *p = (char *) data;
...@@ -177,17 +177,17 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch ...@@ -177,17 +177,17 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
while (totalBytes < neededBytes && --max > 0) { while (totalBytes < neededBytes && --max > 0) {
avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[0]); avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]);
//printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max); //printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max);
if (avail >= neededBytes * 6) { if (avail >= neededBytes * 6) {
PaUtil_FlushRingBuffer(&aStream->inFIFOs[0]); PaUtil_FlushRingBuffer(&aStream->inFIFOs[chan]);
avail = 0; avail = 0;
} else { } else {
bytesRead = 0; bytesRead = 0;
if (totalBytes < neededBytes && avail >= neededBytes) { if (totalBytes < neededBytes && avail >= neededBytes) {
bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFOs[0], p, neededBytes); bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFOs[chan], p, neededBytes);
totalBytes += bytesRead; totalBytes += bytesRead;
} }
...@@ -206,9 +206,9 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch ...@@ -206,9 +206,9 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
* Return the number of frames that could be written to the stream without * Return the number of frames that could be written to the stream without
* having to wait. * having to wait.
*/ */
long GetAudioStreamWriteable(PABLIO_Stream * aStream) long GetAudioStreamWriteable(PABLIO_Stream * aStream, int chan)
{ {
int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[0]); int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[chan]);
return bytesEmpty / aStream->bytesPerFrame; return bytesEmpty / aStream->bytesPerFrame;
} }
...@@ -216,9 +216,9 @@ long GetAudioStreamWriteable(PABLIO_Stream * aStream) ...@@ -216,9 +216,9 @@ long GetAudioStreamWriteable(PABLIO_Stream * aStream)
* Return the number of frames that are available to be read from the * Return the number of frames that are available to be read from the
* stream without having to wait. * stream without having to wait.
*/ */
long GetAudioStreamReadable(PABLIO_Stream * aStream) long GetAudioStreamReadable(PABLIO_Stream * aStream, int chan)
{ {
int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[0]); int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[chan]);
return bytesFull / aStream->bytesPerFrame; return bytesFull / aStream->bytesPerFrame;
} }
......
...@@ -81,25 +81,25 @@ typedef struct { ...@@ -81,25 +81,25 @@ typedef struct {
* Write data to ring buffer. * Write data to ring buffer.
* Will not return until all the data has been written. * Will not return until all the data has been written.
*/ */
long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer); long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer);
/************************************************************ /************************************************************
* Read data from ring buffer. * Read data from ring buffer.
* Will not return until all the data has been read. * Will not return until all the data has been read.
*/ */
long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch_timer_t *timer); long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, int chan, switch_timer_t *timer);
/************************************************************ /************************************************************
* Return the number of frames that could be written to the stream without * Return the number of frames that could be written to the stream without
* having to wait. * having to wait.
*/ */
long GetAudioStreamWriteable(PABLIO_Stream * aStream); long GetAudioStreamWriteable(PABLIO_Stream * aStream, int chan);
/************************************************************ /************************************************************
* Return the number of frames that are available to be read from the * Return the number of frames that are available to be read from the
* stream without having to wait. * stream without having to wait.
*/ */
long GetAudioStreamReadable(PABLIO_Stream * aStream); long GetAudioStreamReadable(PABLIO_Stream * aStream, int chan);
/************************************************************ /************************************************************
* Opens a PortAudio stream with default characteristics. * Opens a PortAudio stream with default characteristics.
...@@ -109,12 +109,12 @@ typedef struct { ...@@ -109,12 +109,12 @@ typedef struct {
* PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE, * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
* and either PABLIO_MONO or PABLIO_STEREO * and either PABLIO_MONO or PABLIO_STEREO
*/ */
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
const PaStreamParameters * inputParameters, const PaStreamParameters * inputParameters,
const PaStreamParameters * outputParameters, const PaStreamParameters * outputParameters,
double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet, int do_dual); double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet, int do_dual);
PaError CloseAudioStream(PABLIO_Stream * aStream); PaError CloseAudioStream(PABLIO_Stream * aStream);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论