working on getting short-circuit audio working.

This commit is contained in:
gardners 2012-05-11 12:06:19 +09:30
parent e746557a08
commit 81c2a926a3
2 changed files with 122 additions and 27 deletions

View File

@ -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;
}
} }

View File

@ -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();