From c448eab720b5953c1f68585d3d38aa8602e6d0fc Mon Sep 17 00:00:00 2001 From: gardners Date: Fri, 11 May 2012 14:11:58 +0930 Subject: [PATCH] fixed audio handling for the most part. aliasing noise and/or buffer underrun noise is present. --- audio_msm_g1.c | 163 +++++++++++++++++++++++++++---------------------- 1 file changed, 89 insertions(+), 74 deletions(-) diff --git a/audio_msm_g1.c b/audio_msm_g1.c index fcab5bd1..61a9fb70 100644 --- a/audio_msm_g1.c +++ b/audio_msm_g1.c @@ -31,12 +31,16 @@ We may need to introduce a low-pass filter to prevent aliasing, assuming that the microphone and ACD in these phones responds to requencies above 4KHz. + + Added fun with this device is that we must read/write exactly one buffer full + at a time. */ #define DESIRED_BUFFER_SIZE 256 #define DESIRED_SAMPLE_RATE 32000 #define RESAMPLE_FACTOR (DESIRED_SAMPLE_RATE/8000) int resamplingBufferSize=0; -unsigned char *resamplingBuffer=0; +unsigned char *playMarshallBuffer=0; +unsigned char *recordMarshallBuffer=0; extern int playFd; extern int recordFd; @@ -259,13 +263,6 @@ int audio_msm_g1_start_play() { if (playFd>-1) return 0; - /* Largest possible resampling buffer required for this chipset. - (we resample so that we can use 8KHz audio for transport, - but 32KHz sample rate on the audio hardware so that buffers - correspond to a shorter period of time */ - resamplingBufferSize=2*RESAMPLE_FACTOR*8192; - resamplingBuffer=malloc(resamplingBufferSize); - /* Get audio control device */ int fd = open ("/dev/msm_snd", O_RDWR); if (fd<0) return -1; @@ -324,6 +321,8 @@ int audio_msm_g1_start_play() float bufferTime=playBufferSize/2*1.0/config.sample_rate; WHYF("PLAY buf=%.3fsecs.",bufferTime); + playMarshallBuffer=malloc(playBufferSize); + /* tell hardware to start playing */ ioctl(playFd,AUDIO_START,0); @@ -336,7 +335,8 @@ int audio_msm_g1_stop_play() { WHY("stopping audio play"); if (playFd>-1) close(playFd); - playFd=-1; + if (playMarshallBuffer) free(playMarshallBuffer); + playFd=-1; playMarshallBuffer=NULL; return 0; } @@ -371,6 +371,9 @@ int audio_msm_g1_start_record() float bufferTime=recordBufferSize/2*1.0/config.sample_rate; WHYF("REC buf=%.3fsecs.",bufferTime); + if (!recordMarshallBuffer) + recordMarshallBuffer=malloc(recordBufferSize); + fcntl(recordFd,F_SETFL, fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK); @@ -385,6 +388,8 @@ int audio_msm_g1_stop_record() { WHY("stopping recording"); if (recordFd>-1) close(recordFd); + if (recordMarshallBuffer) free(recordMarshallBuffer); + recordMarshallBuffer=NULL; recordFd=-1; return 0; } @@ -417,50 +422,50 @@ int audio_msm_g1_poll_fds(struct pollfd *fds,int slots) return count; } +int recordMarshallBufferOffset=0; int audio_msm_g1_read(unsigned char *buffer,int maximum_count) { if (recordFd==-1) return 0; - if (!resamplingBuffer) return 0; + if (!recordMarshallBuffer) return 0; - int maxRawBytes=maximum_count*RESAMPLE_FACTOR; - if (maxRawBytes>resamplingBufferSize) - maxRawBytes=resamplingBufferSize; - if (maxRawBytes>recordBufferSize) - maxRawBytes=recordBufferSize; + int supplied=0; - fcntl(recordFd,F_SETFL,fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK); - ioctl(recordFd,AUDIO_START,0); - WHY("calling read()"); + /* read new samples if we don't have any lingering around */ + if (!recordMarshallBufferOffset) { + fcntl(recordFd,F_SETFL,fcntl(recordFd, F_GETFL, NULL)|O_NONBLOCK); + ioctl(recordFd,AUDIO_START,0); + WHY("calling read()"); + int b=read(recordFd,&recordMarshallBuffer[0],recordBufferSize); + if (b<1) + WHYF("read failed: b=%d, err=%s",b,strerror(errno)); + if (errno==EBADF) recordFd=-1; + WHYF("read %d raw (upsampled) bytes",b); + recordMarshallBufferOffset=b; + } - /* read raw samples */ - int b=read(recordFd,&resamplingBuffer[0],maxRawBytes); - if (b<1) - WHYF("read failed: b=%d, err=%s",b,strerror(errno)); - if (errno==EBADF) recordFd=-1; - WHYF("read %d raw (upsampled) bytes",b); - - /* downsample to output buffer */ - { - int i; - /* copy every RESAMPLE_FACTOR-th sample (each being 16 bits) - to output buffer */ - int outpos=0; - for(i=0;iresamplingBufferSize) - maxBytes=resamplingBufferSize/RESAMPLE_FACTOR; + int i,played=0; - /* upsample ready for play back. - XXX This is a really crude approach, and it could be done much better. */ - int i,j,outpos=0; - for(i=0;i