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
107
audio_msm_g1.c
107
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()
|
||||
{
|
||||
if (playFd>-1) return 0;
|
||||
|
||||
/* Get audio control device */
|
||||
int fd = open ("/dev/msm_snd", O_RDWR);
|
||||
if (fd<0) return -1;
|
||||
@ -272,6 +274,7 @@ int audio_msm_g1_start_play()
|
||||
if (ioctl(playFd, AUDIO_GET_CONFIG,&config))
|
||||
{
|
||||
close(playFd);
|
||||
playFd=-1;
|
||||
return WHY("Could not read audio device configuration");
|
||||
}
|
||||
config.channel_count=1;
|
||||
@ -280,18 +283,49 @@ int audio_msm_g1_start_play()
|
||||
if (ioctl(playFd, AUDIO_SET_CONFIG,&config))
|
||||
{
|
||||
close(playFd);
|
||||
playFd=-1;
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
int audio_msm_g1_stop_play()
|
||||
{
|
||||
WHY("stopping audio play");
|
||||
if (playFd>-1) close(playFd);
|
||||
playFd=-1;
|
||||
return 0;
|
||||
@ -299,11 +333,14 @@ int audio_msm_g1_stop_play()
|
||||
|
||||
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;
|
||||
if (ioctl(recordFd, AUDIO_GET_CONFIG,&config))
|
||||
{
|
||||
close(recordFd);
|
||||
recordFd=-1;
|
||||
return WHY("Could not read audio device configuration");
|
||||
}
|
||||
config.channel_count=1;
|
||||
@ -311,6 +348,7 @@ int audio_msm_g1_start_record()
|
||||
if (ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
||||
{
|
||||
close(recordFd);
|
||||
recordFd=-1;
|
||||
return WHY("Could not set audio device configuration");
|
||||
}
|
||||
|
||||
@ -321,19 +359,22 @@ int audio_msm_g1_start_record()
|
||||
recordBufferSize=config.buffer_size;
|
||||
float bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
||||
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 */
|
||||
config.buffer_size=64;
|
||||
config.buffer_size=64*8;
|
||||
config.buffer_count=2;
|
||||
if (!ioctl(recordFd, AUDIO_SET_CONFIG,&config))
|
||||
{
|
||||
if (!ioctl(playFd, AUDIO_GET_CONFIG,&config)) {
|
||||
recordBufferSize=config.buffer_size;
|
||||
bufferTime=recordBufferSize/2*1.0/config.sample_rate;
|
||||
WHYF("Succeeded in reducing record buffer to %d bytes (%.3fsecs)",
|
||||
recordBufferSize,bufferTime);
|
||||
goto fixedBufferSize;
|
||||
}
|
||||
recordBufferSize=64;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Ask for 2x speed and 2x channels, to divide effective buffer size by 4.
|
||||
@ -344,6 +385,9 @@ int audio_msm_g1_start_record()
|
||||
}
|
||||
fixedBufferSize:
|
||||
|
||||
fcntl(recordFd,F_SETFL,
|
||||
fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK);
|
||||
|
||||
/* tell hardware to start playing */
|
||||
ioctl(recordFd,AUDIO_START,0);
|
||||
|
||||
@ -353,6 +397,7 @@ int audio_msm_g1_start_record()
|
||||
|
||||
int audio_msm_g1_stop_record()
|
||||
{
|
||||
WHY("stopping recording");
|
||||
if (recordFd>-1) close(recordFd);
|
||||
recordFd=-1;
|
||||
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)
|
||||
{
|
||||
if (recordFd==-1) return 0;
|
||||
|
||||
/* Regardless of the maximum, we must read exactly buffer sized pieces
|
||||
on this audio device */
|
||||
if (maximum_count<recordBufferSize) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -401,21 +454,45 @@ int playBufferBytes=0;
|
||||
unsigned char playBuffer[65536];
|
||||
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)
|
||||
{ WHY("Play marshalling buffer full");
|
||||
return 0; }
|
||||
bcopy(&data[0],&playBuffer[playBufferBytes],bytes);
|
||||
playBufferBytes+=bytes;
|
||||
int i;
|
||||
for(i=0;i<playBufferBytes;i+=playBufferSize)
|
||||
for(i=0;i<playBufferBytes;)
|
||||
{
|
||||
if (write(playFd,&playBuffer[i],playBufferSize)<
|
||||
playBufferSize)
|
||||
struct msm_audio_stats stats;
|
||||
if (ioctl (playFd, AUDIO_GET_STATS, &stats) == 0)
|
||||
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);
|
||||
playBufferBytes-=i;
|
||||
|
||||
WHY("done writing");
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@ -425,11 +502,14 @@ int audio_msm_g1_write(unsigned char *data,int bytes)
|
||||
monitor_audio *audio_msm_g1_detect()
|
||||
{
|
||||
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 rc =ioctl(fd,SND_GET_NUM_ENDPOINTS,&endpoints);
|
||||
ioctl(fd,SND_GET_NUM_ENDPOINTS,&endpoints);
|
||||
close(fd);
|
||||
if (rc>0) {
|
||||
if (endpoints>0) {
|
||||
monitor_audio *au=calloc(sizeof(monitor_audio),1);
|
||||
strcpy(au->name,"G1/IDEOS style MSM audio");
|
||||
au->start=audio_msm_g1_start;
|
||||
@ -438,5 +518,8 @@ monitor_audio *audio_msm_g1_detect()
|
||||
au->read=audio_msm_g1_read;
|
||||
au->write=audio_msm_g1_write;
|
||||
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 reflectAudio=0;
|
||||
int syntheticAudio=0;
|
||||
int showReceived=1;
|
||||
int showReceived=0;
|
||||
int interactiveP=1;
|
||||
int recordCodec=VOMP_CODEC_PCM;
|
||||
int recordCodecBlockSamples=320;
|
||||
int recordCodecTimespan=20;
|
||||
int callSessionToken=0;
|
||||
int fast_audio=0;
|
||||
|
||||
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;
|
||||
while(1) {
|
||||
WHY("pollloop");
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
WHY("about to read");
|
||||
int bytesRead=audev->read(&audioRecordBuffer[audioRecordBufferBytes],
|
||||
audioRecordBufferSize-audioRecordBufferBytes);
|
||||
WHY("read");
|
||||
if (bytesRead>0) audioRecordBufferBytes+=bytesRead;
|
||||
|
||||
/* 8KHz 16 bit samples = 16000 bytes per second.
|
||||
@ -172,6 +176,7 @@ int app_monitor_cli(int argc, const char *const *argv, struct command_line_optio
|
||||
encodeAndDispatchRecordedAudio(fd,callSessionToken,recordCodec,
|
||||
&audioRecordBuffer[audioRecordBufferOffset],
|
||||
recordCodecTimespan*16);
|
||||
WHY("sample block sent");
|
||||
/* skip over the samples we have already processed */
|
||||
audioRecordBufferOffset+=recordCodecTimespan*16;
|
||||
}
|
||||
@ -222,21 +227,28 @@ int processLine(char *cmd,unsigned char *data,int dataLen)
|
||||
&l_id,&r_id,&l_state,&r_state,
|
||||
&codec,&start_time,&end_time)==7)
|
||||
{
|
||||
if (pipeAudio&&audev) {
|
||||
if (pipeAudio&&audev&&fast_audio) {
|
||||
bufferAudioForPlayback(codec,start_time,end_time,data,dataLen);
|
||||
}
|
||||
}
|
||||
if (sscanf(cmd,"CALLSTATUS:%x:%x:%d:%d",
|
||||
&l_id,&r_id,&l_state,&r_state)==4)
|
||||
char msg[1024];
|
||||
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) {
|
||||
// We are ringing, so pickup
|
||||
char msg[1024];
|
||||
sprintf(msg,"pickup %x\n",l_id);
|
||||
writeLine(msg);
|
||||
}
|
||||
if (l_state==5) {
|
||||
if (fast_audio) {
|
||||
startAudio();
|
||||
}
|
||||
callSessionToken=l_id;
|
||||
} else {
|
||||
stopAudio();
|
||||
|
Loading…
Reference in New Issue
Block a user