Production Test Program (PTP) for the LPC4088 Experiment Base Board

Dependencies:   EALib I2S LM75B SDFileSystem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TestAudio.cpp Source File

TestAudio.cpp

00001 /*
00002  *  Copyright 2013 Embedded Artists AB
00003  *
00004  *  Licensed under the Apache License, Version 2.0 (the "License");
00005  *  you may not use this file except in compliance with the License.
00006  *  You may obtain a copy of the License at
00007  *
00008  *    http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  *  Unless required by applicable law or agreed to in writing, software
00011  *  distributed under the License is distributed on an "AS IS" BASIS,
00012  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *  See the License for the specific language governing permissions and
00014  *  limitations under the License.
00015  */
00016 
00017 /******************************************************************************
00018  * Includes
00019  *****************************************************************************/
00020 //#define SOUND_8KHZ
00021 
00022 #include "mbed.h"
00023 #include "TestAudio.h"
00024 #include "WM8731.h"
00025 #include "I2S.h"
00026 #include "sound.h"
00027 
00028 /******************************************************************************
00029  * Defines and typedefs
00030  *****************************************************************************/
00031 
00032 #define SAMPLERATE 32000
00033 
00034 /******************************************************************************
00035  * Private Functions
00036  *****************************************************************************/
00037 
00038 void TestAudio::echo(void) {
00039     int to_read = _i2sRx.fifo_points();  //Find out how many stereo samples to read
00040     
00041     //Read 'to_read' number of stereo samples.
00042     _i2sRx.read(_rxBuf, to_read);
00043     
00044     //Loop through all stereo samples
00045     for(int i = 0; i < to_read; i+=2) {
00046         // Check if wave-file shall be output
00047         if (_waveIdx > 0)
00048         {
00049 #if SOUND_8KHZ
00050             int sample = sound_8k[_waveIdx/4] << 5
00051             _txBuf[i]             = sample;
00052             _txBuf[i+1]           = sample;
00053             _echoBuf[_echoBufPtr] = _rxBuf[i];
00054 
00055             //Increment wave samples pointer and check if all samples have been read, if so, set pointer to zero
00056             _waveIdx++;
00057             if (_waveIdx/4 > sound_sz)
00058             {
00059                 _waveIdx = 0;
00060             }
00061 #else
00062             int sample = (unsigned int)sound_32k[_waveIdx] | (((unsigned int)sound_32k[_waveIdx+1]) << 8);
00063             _txBuf[i]             = sample;
00064             _txBuf[i+1]           = sample;
00065             _echoBuf[_echoBufPtr] = _rxBuf[i];
00066 
00067             //Increment wave samples pointer and check if all samples have been read, if so, set pointer to zero
00068             _waveIdx += 2;
00069             if (_waveIdx > sound_sz)
00070             {
00071                 _waveIdx = 0;
00072             }
00073 #endif
00074         }
00075         //Output delayed version of audio input
00076         else
00077         {
00078             //Echo buffer only contains right side samples (since MIC is used as input, which is a mono input)
00079             //Output is however stereo, so just copy echo bugger to both right and left side for output samples
00080             _txBuf[i]   = _echoBuf[_echoBufPtr];
00081             _txBuf[i+1] = _echoBuf[_echoBufPtr];
00082 
00083             //Only fill echo buffer with right side samples, i.e., ignore rxBuf[i+1] content
00084             _echoBuf[_echoBufPtr]   = _rxBuf[i];
00085         }
00086 
00087         //Increment echo buffer write pointer and check for wrap-around
00088         _echoBufPtr++;
00089         if (_echoBufPtr >= ECHOLENGTH)
00090         {
00091             _echoBufPtr = 0;
00092         }
00093     }
00094     
00095     //Write samples to output/codec
00096     _i2sTx.write(_txBuf, to_read);
00097 }
00098 
00099 /******************************************************************************
00100  * Public Functions
00101  *****************************************************************************/
00102 
00103 /*
00104    Prerequisites:
00105  
00106    - For this test to work jumpers JP8 and JP9 on the LPC4088 Experiment Base Board
00107      must both be in positions 1-2
00108      
00109    - MIC cable, Line OUT, Headphone...
00110 */
00111 
00112 TestAudio::TestAudio() : _codec(P0_27, P0_28), _i2sTx(I2S_TRANSMIT, p11, p12, p13),
00113     _i2sRx(I2S_RECEIVE, p14, p33, p34),_aIn(p15),_waveIdx(0),_echoBufPtr(0) {
00114 }
00115 
00116 bool TestAudio::runTest() {
00117     printf("Testing audio... Exit by pressing joystick up\n");
00118     printf("Joystick down = play short wave-file. Joystick right/left = turn microphone boost on/off\n");
00119 
00120     // joystick used for audio selection    
00121     DigitalIn up(p32);
00122     DigitalIn down(p38);
00123     DigitalIn left(p39);
00124     DigitalIn right(p37);
00125     
00126     for(int i=0; i<ECHOLENGTH; i++)
00127       _echoBuf[i] = 0;
00128     
00129     _codec.power(true);
00130     _codec.frequency(SAMPLERATE);
00131     _codec.wordsize(16);  
00132     _codec.master(true);
00133     _codec.headphone_volume(0.1);
00134     _codec.input_select(WM8731_MIC);
00135     _codec.microphone_boost(true);
00136     _codec.input_mute(false);
00137     _codec.output_mute(false);
00138     _codec.input_power(true);
00139     _codec.output_power(true);
00140     _codec.linein_volume(0.7);
00141     _codec.bypass(true);
00142     _codec.start();
00143 
00144     _i2sRx.frequency(SAMPLERATE);
00145     _i2sRx.wordsize(16);
00146     _i2sRx.stereomono(I2S_STEREO);
00147     _i2sRx.masterslave(I2S_SLAVE);
00148     _i2sRx.attach(this, &TestAudio::echo);
00149     _i2sRx.set_interrupt_fifo_level(1);
00150     _echoBufPtr = 0;
00151     _waveIdx = 0;
00152     _i2sRx.start();
00153 
00154     _i2sTx.frequency(SAMPLERATE);
00155     _i2sTx.wordsize(16);
00156     _i2sTx.stereomono(I2S_STEREO);
00157     _i2sTx.masterslave(I2S_SLAVE);
00158     _i2sTx.start();
00159 
00160     int lastVol = -1000; // value not important
00161     do
00162     {
00163         //check if joystick-down pressed = play wave-file
00164         if ((down.read() == 0) && (_waveIdx == 0))
00165             _waveIdx = 2;
00166 
00167         //check if joystick-left pressed = turn off microphone boost
00168         if (left.read() == 0)
00169         {
00170             _codec.input_mute(true);
00171             wait(0.2);
00172             _codec.microphone_boost(false);
00173             wait(0.2);
00174             _codec.input_mute(false);
00175         }
00176 
00177         //check if joystick-right pressed = turn on microphone boost
00178         if (right.read() == 0)
00179         {
00180             _codec.input_mute(true);
00181             wait(0.2);
00182             _codec.microphone_boost(true);
00183             wait(0.2);
00184             _codec.input_mute(false);
00185         }
00186 
00187         //attempt to filter out the small variations in analog values and
00188         //only update volume when a "large enough" change is detected.
00189         float v = _aIn;
00190         int val = ((int)(v*1000))>>2;
00191         if (val != lastVol) {
00192             _codec.headphone_volume(v);
00193             lastVol = val;
00194         }
00195         //_codec.headphone_volume(_aIn);
00196         wait(0.25);
00197     } while (up.read() != 0);
00198 
00199     _codec.power(false);
00200     return true;
00201 }
00202 
00203