mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-24 07:16:43 +00:00
working on getting short-circuit audio working.
This commit is contained in:
parent
e746557a08
commit
81c2a926a3
119
audio_msm_g1.c
119
audio_msm_g1.c
@ -239,6 +239,8 @@ set_volume_rpc (uint32_t device, uint32_t method, uint32_t volume)
|
|||||||
*/
|
*/
|
||||||
int audio_msm_g1_start_play()
|
int audio_msm_g1_start_play()
|
||||||
{
|
{
|
||||||
|
if (playFd>-1) return 0;
|
||||||
|
|
||||||
/* Get audio control device */
|
/* Get audio control device */
|
||||||
int fd = open ("/dev/msm_snd", O_RDWR);
|
int fd = open ("/dev/msm_snd", O_RDWR);
|
||||||
if (fd<0) return -1;
|
if (fd<0) return -1;
|
||||||
@ -272,6 +274,7 @@ int audio_msm_g1_start_play()
|
|||||||
if (ioctl(playFd, AUDIO_GET_CONFIG,&config))
|
if (ioctl(playFd, AUDIO_GET_CONFIG,&config))
|
||||||
{
|
{
|
||||||
close(playFd);
|
close(playFd);
|
||||||
|
playFd=-1;
|
||||||
return WHY("Could not read audio device configuration");
|
return WHY("Could not read audio device configuration");
|
||||||
}
|
}
|
||||||
config.channel_count=1;
|
config.channel_count=1;
|
||||||
@ -280,18 +283,49 @@ int audio_msm_g1_start_play()
|
|||||||
if (ioctl(playFd, AUDIO_SET_CONFIG,&config))
|
if (ioctl(playFd, AUDIO_SET_CONFIG,&config))
|
||||||
{
|
{
|
||||||
close(playFd);
|
close(playFd);
|
||||||
|
playFd=-1;
|
||||||
return WHY("Could not set audio device configuration");
|
return WHY("Could not set audio device configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fcntl(playFd,F_SETFL,
|
||||||
|
fcntl(playFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If playBufferSize equates to too long an interval,
|
||||||
|
then try to reduce it in various ways.
|
||||||
|
*/
|
||||||
|
float bufferTime=playBufferSize/2*1.0/config.sample_rate;
|
||||||
|
if (bufferTime>0.02) {
|
||||||
|
WHYF("PLAY buf=%.3fsecs, which is too long. Trying to reduce it.",
|
||||||
|
bufferTime);
|
||||||
|
|
||||||
|
/* 64 bytes = 32 samples = ~4ms */
|
||||||
|
config.buffer_size=64*8;
|
||||||
|
config.buffer_count=2;
|
||||||
|
if (!ioctl(playFd, AUDIO_SET_CONFIG,&config))
|
||||||
|
{
|
||||||
|
if (!ioctl(playFd, AUDIO_GET_CONFIG,&config)) {
|
||||||
|
playBufferSize=config.buffer_size;
|
||||||
|
bufferTime=playBufferSize/2*1.0/config.sample_rate;
|
||||||
|
WHYF("Succeeded in reducing play buffer to %d bytes (%.3fsecs)",
|
||||||
|
playBufferSize,bufferTime);
|
||||||
|
goto fixedBufferSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixedBufferSize:
|
||||||
|
|
||||||
/* tell hardware to start playing */
|
/* tell hardware to start playing */
|
||||||
ioctl(playFd,AUDIO_START,0);
|
ioctl(playFd,AUDIO_START,0);
|
||||||
|
|
||||||
WHY("G1/IDEOS style MSM audio device initialised and ready to play");
|
WHYF("G1/IDEOS style MSM audio device initialised and ready to play");
|
||||||
|
WHYF("Play buffer size = %d bytes",playBufferSize);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int audio_msm_g1_stop_play()
|
int audio_msm_g1_stop_play()
|
||||||
{
|
{
|
||||||
|
WHY("stopping audio play");
|
||||||
if (playFd>-1) close(playFd);
|
if (playFd>-1) close(playFd);
|
||||||
playFd=-1;
|
playFd=-1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -299,11 +333,14 @@ int audio_msm_g1_stop_play()
|
|||||||
|
|
||||||
int audio_msm_g1_start_record()
|
int audio_msm_g1_start_record()
|
||||||
{
|
{
|
||||||
recordFd=open("/dev/msm_pcm_out",O_RDWR);
|
if (recordFd>-1) return 0;
|
||||||
|
|
||||||
|
recordFd=open("/dev/msm_pcm_in",O_RDWR);
|
||||||
struct msm_audio_config config;
|
struct msm_audio_config config;
|
||||||
if (ioctl(recordFd, AUDIO_GET_CONFIG,&config))
|
if (ioctl(recordFd, AUDIO_GET_CONFIG,&config))
|
||||||
{
|
{
|
||||||
close(recordFd);
|
close(recordFd);
|
||||||
|
recordFd=-1;
|
||||||
return WHY("Could not read audio device configuration");
|
return WHY("Could not read audio device configuration");
|
||||||
}
|
}
|
||||||
config.channel_count=1;
|
config.channel_count=1;
|
||||||
@ -311,6 +348,7 @@ int audio_msm_g1_start_record()
|
|||||||
if (ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
if (ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
||||||
{
|
{
|
||||||
close(recordFd);
|
close(recordFd);
|
||||||
|
recordFd=-1;
|
||||||
return WHY("Could not set audio device configuration");
|
return WHY("Could not set audio device configuration");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,19 +359,22 @@ int audio_msm_g1_start_record()
|
|||||||
recordBufferSize=config.buffer_size;
|
recordBufferSize=config.buffer_size;
|
||||||
float bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
float bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
||||||
if (bufferTime>0.02) {
|
if (bufferTime>0.02) {
|
||||||
WHYF("REC buf=%.3fsecs, which is too long. Trying to reduce it.");
|
WHYF("REC buf=%.3fsecs, which is too long. Trying to reduce it.",
|
||||||
|
bufferTime);
|
||||||
|
|
||||||
/* 64 bytes = 32 samples = ~4ms */
|
/* 64 bytes = 32 samples = ~4ms */
|
||||||
config.buffer_size=64;
|
config.buffer_size=64*8;
|
||||||
|
config.buffer_count=2;
|
||||||
if (!ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
if (!ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
||||||
{
|
{
|
||||||
recordBufferSize=config.buffer_size;
|
if (!ioctl(playFd, AUDIO_GET_CONFIG,&config)) {
|
||||||
bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
recordBufferSize=config.buffer_size;
|
||||||
WHYF("Succeeded in reducing record buffer to %d bytes (%.3fsecs)",
|
bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
||||||
recordBufferSize,bufferTime);
|
WHYF("Succeeded in reducing record buffer to %d bytes (%.3fsecs)",
|
||||||
goto fixedBufferSize;
|
recordBufferSize,bufferTime);
|
||||||
|
goto fixedBufferSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
recordBufferSize=64;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Ask for 2x speed and 2x channels, to divide effective buffer size by 4.
|
/* Ask for 2x speed and 2x channels, to divide effective buffer size by 4.
|
||||||
@ -343,6 +384,9 @@ int audio_msm_g1_start_record()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fixedBufferSize:
|
fixedBufferSize:
|
||||||
|
|
||||||
|
fcntl(recordFd,F_SETFL,
|
||||||
|
fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||||
|
|
||||||
/* tell hardware to start playing */
|
/* tell hardware to start playing */
|
||||||
ioctl(recordFd,AUDIO_START,0);
|
ioctl(recordFd,AUDIO_START,0);
|
||||||
@ -353,6 +397,7 @@ int audio_msm_g1_start_record()
|
|||||||
|
|
||||||
int audio_msm_g1_stop_record()
|
int audio_msm_g1_stop_record()
|
||||||
{
|
{
|
||||||
|
WHY("stopping recording");
|
||||||
if (recordFd>-1) close(recordFd);
|
if (recordFd>-1) close(recordFd);
|
||||||
recordFd=-1;
|
recordFd=-1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -388,12 +433,20 @@ int audio_msm_g1_poll_fds(struct pollfd *fds,int slots)
|
|||||||
|
|
||||||
int audio_msm_g1_read(unsigned char *buffer,int maximum_count)
|
int audio_msm_g1_read(unsigned char *buffer,int maximum_count)
|
||||||
{
|
{
|
||||||
|
if (recordFd==-1) return 0;
|
||||||
|
|
||||||
/* Regardless of the maximum, we must read exactly buffer sized pieces
|
/* Regardless of the maximum, we must read exactly buffer sized pieces
|
||||||
on this audio device */
|
on this audio device */
|
||||||
if (maximum_count<recordBufferSize) {
|
if (maximum_count<recordBufferSize) {
|
||||||
return WHY("Supplied buffer has no space for sample quanta");
|
return WHY("Supplied buffer has no space for sample quanta");
|
||||||
}
|
}
|
||||||
|
fcntl(recordFd,F_SETFL,fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||||
int b=read(recordFd,&buffer[0],recordBufferSize);
|
int b=read(recordFd,&buffer[0],recordBufferSize);
|
||||||
|
if (b<1)
|
||||||
|
WHYF("read failed: b=%d, err=%s",b,strerror(errno));
|
||||||
|
else
|
||||||
|
WHYF("read %d bytes",b);
|
||||||
|
if (errno=EBADF) recordFd=-1;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,21 +454,45 @@ int playBufferBytes=0;
|
|||||||
unsigned char playBuffer[65536];
|
unsigned char playBuffer[65536];
|
||||||
int audio_msm_g1_write(unsigned char *data,int bytes)
|
int audio_msm_g1_write(unsigned char *data,int bytes)
|
||||||
{
|
{
|
||||||
|
if (playFd==-1) return 0;
|
||||||
|
fcntl(playFd,F_SETFL,fcntl(playFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||||
if (bytes+playBufferBytes>65536)
|
if (bytes+playBufferBytes>65536)
|
||||||
{ WHY("Play marshalling buffer full");
|
{ WHY("Play marshalling buffer full");
|
||||||
return 0; }
|
return 0; }
|
||||||
bcopy(&data[0],&playBuffer[playBufferBytes],bytes);
|
bcopy(&data[0],&playBuffer[playBufferBytes],bytes);
|
||||||
playBufferBytes+=bytes;
|
playBufferBytes+=bytes;
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<playBufferBytes;i+=playBufferSize)
|
for(i=0;i<playBufferBytes;)
|
||||||
{
|
{
|
||||||
if (write(playFd,&playBuffer[i],playBufferSize)<
|
struct msm_audio_stats stats;
|
||||||
playBufferSize)
|
if (ioctl (playFd, AUDIO_GET_STATS, &stats) == 0)
|
||||||
break;
|
WHYF("stats.out_bytes = %10d", stats.out_bytes);
|
||||||
|
|
||||||
|
int bytes=playBufferSize;
|
||||||
|
if (i+bytes>playBufferBytes) bytes=playBufferBytes-i;
|
||||||
|
WHYF("Trying to write %d bytes of audio",bytes);
|
||||||
|
ioctl(playFd,AUDIO_START,0);
|
||||||
|
fcntl(playFd,F_SETFL,fcntl(playFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||||
|
int w=0;
|
||||||
|
WHYF("write(%d,&pb[%d],%d) (playBufferBytes=%d)",
|
||||||
|
playFd,i,bytes,playBufferBytes);
|
||||||
|
if ((w=write(playFd,&playBuffer[i],bytes))<
|
||||||
|
1)
|
||||||
|
{
|
||||||
|
WHYF("Failed to write, returned %d (errno=%s)",
|
||||||
|
w,strerror(errno));
|
||||||
|
if (errno==EBADF) playFd=-1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
WHYF("Wrote %d bytes of audio",w);
|
||||||
|
i+=w;
|
||||||
|
}
|
||||||
|
WHY("after write");
|
||||||
}
|
}
|
||||||
bcopy(&playBuffer[i],&playBuffer[0],playBufferBytes-i);
|
bcopy(&playBuffer[i],&playBuffer[0],playBufferBytes-i);
|
||||||
playBufferBytes-=i;
|
playBufferBytes-=i;
|
||||||
|
|
||||||
|
WHY("done writing");
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,11 +502,14 @@ int audio_msm_g1_write(unsigned char *data,int bytes)
|
|||||||
monitor_audio *audio_msm_g1_detect()
|
monitor_audio *audio_msm_g1_detect()
|
||||||
{
|
{
|
||||||
int fd = open ("/dev/msm_snd", O_RDWR);
|
int fd = open ("/dev/msm_snd", O_RDWR);
|
||||||
if (fd<0) return NULL;
|
if (fd<0) {
|
||||||
|
WHYF("Could not open /dev/msm_snd (err=%s)",strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
int endpoints=0;
|
int endpoints=0;
|
||||||
int rc =ioctl(fd,SND_GET_NUM_ENDPOINTS,&endpoints);
|
ioctl(fd,SND_GET_NUM_ENDPOINTS,&endpoints);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (rc>0) {
|
if (endpoints>0) {
|
||||||
monitor_audio *au=calloc(sizeof(monitor_audio),1);
|
monitor_audio *au=calloc(sizeof(monitor_audio),1);
|
||||||
strcpy(au->name,"G1/IDEOS style MSM audio");
|
strcpy(au->name,"G1/IDEOS style MSM audio");
|
||||||
au->start=audio_msm_g1_start;
|
au->start=audio_msm_g1_start;
|
||||||
@ -438,5 +518,8 @@ monitor_audio *audio_msm_g1_detect()
|
|||||||
au->read=audio_msm_g1_read;
|
au->read=audio_msm_g1_read;
|
||||||
au->write=audio_msm_g1_write;
|
au->write=audio_msm_g1_write;
|
||||||
return au;
|
return au;
|
||||||
} else return NULL;
|
} else {
|
||||||
|
WHY("zero end points, so assuming not compatibile audio device");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,13 @@ int autoAnswerP=1;
|
|||||||
int pipeAudio=1;
|
int pipeAudio=1;
|
||||||
int reflectAudio=0;
|
int reflectAudio=0;
|
||||||
int syntheticAudio=0;
|
int syntheticAudio=0;
|
||||||
int showReceived=1;
|
int showReceived=0;
|
||||||
int interactiveP=1;
|
int interactiveP=1;
|
||||||
int recordCodec=VOMP_CODEC_PCM;
|
int recordCodec=VOMP_CODEC_PCM;
|
||||||
int recordCodecBlockSamples=320;
|
int recordCodecBlockSamples=320;
|
||||||
int recordCodecTimespan=20;
|
int recordCodecTimespan=20;
|
||||||
int callSessionToken=0;
|
int callSessionToken=0;
|
||||||
|
int fast_audio=0;
|
||||||
|
|
||||||
int app_monitor_cli(int argc, const char *const *argv, struct command_line_option *o)
|
int app_monitor_cli(int argc, const char *const *argv, struct command_line_option *o)
|
||||||
{
|
{
|
||||||
@ -132,8 +133,9 @@ int app_monitor_cli(int argc, const char *const *argv, struct command_line_optio
|
|||||||
|
|
||||||
int base_fd_count=fdcount;
|
int base_fd_count=fdcount;
|
||||||
while(1) {
|
while(1) {
|
||||||
|
WHY("pollloop");
|
||||||
fdcount=base_fd_count;
|
fdcount=base_fd_count;
|
||||||
fdcount+=audev->poll_fds(&fds[fdcount],128-fdcount);
|
if (audev&&audev->poll_fds) fdcount+=audev->poll_fds(&fds[fdcount],128-fdcount);
|
||||||
poll(fds,fdcount,1000);
|
poll(fds,fdcount,1000);
|
||||||
|
|
||||||
fcntl(fd,F_SETFL,
|
fcntl(fd,F_SETFL,
|
||||||
@ -159,8 +161,10 @@ int app_monitor_cli(int argc, const char *const *argv, struct command_line_optio
|
|||||||
|
|
||||||
if (audev&&audev->read)
|
if (audev&&audev->read)
|
||||||
{
|
{
|
||||||
|
WHY("about to read");
|
||||||
int bytesRead=audev->read(&audioRecordBuffer[audioRecordBufferBytes],
|
int bytesRead=audev->read(&audioRecordBuffer[audioRecordBufferBytes],
|
||||||
audioRecordBufferSize-audioRecordBufferBytes);
|
audioRecordBufferSize-audioRecordBufferBytes);
|
||||||
|
WHY("read");
|
||||||
if (bytesRead>0) audioRecordBufferBytes+=bytesRead;
|
if (bytesRead>0) audioRecordBufferBytes+=bytesRead;
|
||||||
|
|
||||||
/* 8KHz 16 bit samples = 16000 bytes per second.
|
/* 8KHz 16 bit samples = 16000 bytes per second.
|
||||||
@ -171,7 +175,8 @@ int app_monitor_cli(int argc, const char *const *argv, struct command_line_optio
|
|||||||
/* encode and deliver audio block to servald via monitor interface */
|
/* encode and deliver audio block to servald via monitor interface */
|
||||||
encodeAndDispatchRecordedAudio(fd,callSessionToken,recordCodec,
|
encodeAndDispatchRecordedAudio(fd,callSessionToken,recordCodec,
|
||||||
&audioRecordBuffer[audioRecordBufferOffset],
|
&audioRecordBuffer[audioRecordBufferOffset],
|
||||||
recordCodecTimespan*16);
|
recordCodecTimespan*16);
|
||||||
|
WHY("sample block sent");
|
||||||
/* skip over the samples we have already processed */
|
/* skip over the samples we have already processed */
|
||||||
audioRecordBufferOffset+=recordCodecTimespan*16;
|
audioRecordBufferOffset+=recordCodecTimespan*16;
|
||||||
}
|
}
|
||||||
@ -222,21 +227,28 @@ int processLine(char *cmd,unsigned char *data,int dataLen)
|
|||||||
&l_id,&r_id,&l_state,&r_state,
|
&l_id,&r_id,&l_state,&r_state,
|
||||||
&codec,&start_time,&end_time)==7)
|
&codec,&start_time,&end_time)==7)
|
||||||
{
|
{
|
||||||
if (pipeAudio&&audev) {
|
if (pipeAudio&&audev&&fast_audio) {
|
||||||
bufferAudioForPlayback(codec,start_time,end_time,data,dataLen);
|
bufferAudioForPlayback(codec,start_time,end_time,data,dataLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sscanf(cmd,"CALLSTATUS:%x:%x:%d:%d",
|
char msg[1024];
|
||||||
&l_id,&r_id,&l_state,&r_state)==4)
|
if (sscanf(cmd,"CALLSTATUS:%x:%x:%d:%d:%d",
|
||||||
|
&l_id,&r_id,&l_state,&r_state,&fast_audio)==5)
|
||||||
{
|
{
|
||||||
|
if (l_state<5&&l_id&&pipeAudio) {
|
||||||
|
// Take control of audio for this call, and let the java side know
|
||||||
|
snprintf(msg,1024,"FASTAUDIO:%x:1\n",l_id);
|
||||||
|
writeLine(msg);
|
||||||
|
}
|
||||||
if (l_state==4&&autoAnswerP) {
|
if (l_state==4&&autoAnswerP) {
|
||||||
// We are ringing, so pickup
|
// We are ringing, so pickup
|
||||||
char msg[1024];
|
|
||||||
sprintf(msg,"pickup %x\n",l_id);
|
sprintf(msg,"pickup %x\n",l_id);
|
||||||
writeLine(msg);
|
writeLine(msg);
|
||||||
}
|
}
|
||||||
if (l_state==5) {
|
if (l_state==5) {
|
||||||
startAudio();
|
if (fast_audio) {
|
||||||
|
startAudio();
|
||||||
|
}
|
||||||
callSessionToken=l_id;
|
callSessionToken=l_id;
|
||||||
} else {
|
} else {
|
||||||
stopAudio();
|
stopAudio();
|
||||||
|
Loading…
Reference in New Issue
Block a user