This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LP-CC1352P7: Unable to get Audio output from I2S echo example.

Part Number: LP-CC1352P7
Other Parts Discussed in Thread: CC3200AUDBOOST, CC3200, CC1352P7, CC2652R7, CC2642R

Hi,

   I was trying to run I2S echo example shared by TI resource .

The example recommends the CC3200AUDBOOST, which i purchased and followed the steps as below:

CC3200 Audio BoosterPack

  • The BoostPack’s DIN signal pin is not compatible with this LaunchPad. Use one of the following modification(s) to enable the CC3200 Audio BoosterPack’s usage with the i2secho example.
  • Bend down the two pins below DIO30. Additionally bend down DIO28-30. Be sure that the bent pin(s) do not make contact with the IC or any other component, bend them enough to make sure they don’t connect to the CC3200 Audio BoosterPack.
  • Attach the CC3200 Audio BoosterPack to the LP_CC1352P7_4
  • Run jumper wires between the following pins on the CC3200 Audio BoosterPack:
    • DIN: P3.3 and P3.9
    • DOUT: P3.4 and P3.10
    • BCLK: P3.5 and P3.8
    • FSYNC/WCLK: P4.9 and P3.7
I Did the first 3 steps and checked if i need to do step 4. Then i saw that connections should lead to "NC"(No connection, which i ensured by bending pins.
I ensured the 3.3V pin pointer matching to Launchpad pointer as well, as you can see in image attached.
With this setup, when i flash I2S example, i can see driver initialization LED glowing on CC1352P7 launchpad, but the audio feedback i am not getting.
What other way i can debug this ?
Attaching the photo of my setup.
  • Hi,

    As you mentioned, you do need to run the jumper wires, and I do not see them on your pictures.

    Can you try with those and then tell us whether it functions or not?

    Regards,

    Arthur

  • Thanks Arthur.  I tried connecting jumper wires as well, as per the last step. But still no luck.

  • Do i need to connect seperate USB power to this CC3200 AUDBOOST ?, i thought it will take from launch pad .

    please correct me, if my understanding is wrong.

  • Dear Vinay,

    No, you do not need to connect the USB power. However, I see that you forgot to bend the following pin (blue circle, DIO14):

    DIO14 Pin not bent

    Let me know whether it works or not after that modification.

    Regards,

    Arthur

  • Board.html

    I am attaching Board.html, which does not talk about bending DI014.  Is it that this info is missed, so i should try your recommendation of bending DI014.

  • I did bend the pin now , as shown below.

    Now i am getting very noisy sound in stereo out , still not echoing the sound from Stereo In.

  • By default, the i2secho outputs to the Speaker terminals (in black)

    Please change the defines to the output you wish to use.

    Regards,

    Arthur

  • Tried this : 

    #define INPUT_OPTION AudioCodec_MIC_MONO //AudioCodec_MIC_LINE_IN
    #define OUTPUT_OPTION AudioCodec_SPEAKER_LO //AudioCodec_SPEAKER_HP

    Still very noisy , cant hear echoing sounds.

  • Should DIO16 also to be bent , as i see P3.7 connected to P4.9, which maps to DIO16.

    Can you please let me know, Arthur .

  • Hi Vinay,

    I would recommend to follow the guidance provided in the section "Hardware Setup" (especially under CC13x2) to properly set up the jumper wires https://dev.ti.com/tirex/content/simplelink_audio_plugin_3_30_00_06/docs/Quick_Start_Guide.html
    Among others, DIO14 does not need to be bend.

    For the configuration of the defines for the audio input / output, I would recommend the following:

    #define INPUT_OPTION                    AudioCodec_MIC_LINE_IN
    #define OUTPUT_OPTION                   AudioCodec_SPEAKER_LO

    This will enable the green connector as input/output.

    To finish, I would recommend to use a phone as audio source and not a computer. Actually, because of the noise created by the power source, the sound coming out of most of the computers is extremely noisy and not usable with this example.

    I hope this will help,

    Best regards,

  • Yes Clement, I followed the hardware setup and ensured jumper wires before following instruction from Arthur to bend the DIO14.

    Also the link you provided seem to talk about audioechoHAL, which is different from example that i am following I2Secho example provided in SDK.

    When i try to search AudioechoHAL in sdk, i dont see those examples.

    Also tried one of the latest Simlink sdk , even there i dont see your example quoted.

    Can you please guide me with respect to I2Secho example given , whose details are provided in this question earlier.

  • Hi Vinay,

    The document I have pointed you to should only be used for the hardware configuration (i.e. set-up the jumper wires).

    The rest of my message applies to the example you are using (i.e. i2secho example).

    Best regards,

  • Additionally in Resource explorer, the I2Secho example is given , not the one you referred audioHAL.
    Please see the screen shot below : 

    Regarding Noise part : The noise is such that i cant hear any echo , so certainly it looks incorrect. I am also trying to connect the Mobile some music to Mic in and confirm this. 

    I started getting Noise only after i bent DIO14 , which was suggested by Arthur . Otheriwse i was not getting anything in stero out.

  • Hi,

    As mentioned in my previous message, the document I have pointed you to should only be used for the hardware configuration (i.e. set-up the jumper wires). The rest of my message applies to the example you are using (i.e. i2secho example).

    DIO14 should not be bend. The values set for the symbols INPUT_OPTION and OUTPUT_OPTION should be as mentioned in my previous message. Audio should be input using a phone not connected to a power source.

    To help the debug, please use a logic analyzer to verify if the clocks (WCLK and BCLK) and the data lines show the expected signals.

    Best regards, 

  • I misunderstood that you are pointing to different example.

    Now i understood, let me reverify and also bent pin DIO14 to be brought back.

    I will try and come back 

  • Just now tried and i am still getting noise but very mildly i can hear songs played in mobile.

    The setup looks like this now.

  • Hi,

    Thank you for the update.

    Could you try to use a different headset as well? I have seen some noise coming from the headset before (especially the ones with volume control integrated). 

    If it does not help, for a test, could you please remove the jumper-wires arriving on P3.10 and P3.9. Then, short P3.10 and P3.9 together. This will bypass the CC1352 and help asssessing the source of the noise.

    Best regards,

  • Changed Headset, no luck.
    As you said, shorting P3.9 and P3.10 gave very clean and smooth audio.
    Which means passing through Launchpad CC1352P7-4 is problem ?

    Can we dump some PCM samples in I2s read or do you suggest something else ?

  • while trying to debug , i tried tapping i2sReadlist.head buffer and when i open up the memory of this pointer and tried saving memory to eventually convert in to .wav format. I see the memory as shown below 

    Here it shows I2sTransactions 1...10 ....and also very consitant values are seen when i run and stop.

    Basically i want to dump from buffer the 16bit PCM values and convert it to .wav format and play it out.

    Is this my memory checking and exporting is correct or not.

  • I am trying to tap i2sBufList buffer , but not getting why there are 10 bufferes and first half is used as readlist and 2nd half as writelist.

    I wanted to basically dump the audio and see if the noise is already in buffer or when we pass via DAC .

  • Hi,

    Thank you for the additional tests you have run.

    The audio data (PCM) is stored in the buffers named buf1...buf10.

    All the buffers are sequentially passing by the read and the write list.

    Best regards,

  • Hi Clement,

        Tried dumping buf1 to buf4  of size 1024(256*4). But .dat or bin files are not getting converted in to wav file using online converter.

    As i see the values are close to 255 when seen as uint8, but what we wanted was 16bit PCM samples. So is there a way i can dump 16bit PCM directly from these bufs and convert it to wav file to listen.

    Snapshot as below : 

  • Hi Vinay,

    Please change the display format to match the format of the data you are looking at.

    To do so, please use the menu I have highlighted in red:

    Best regards,

  • Yes Clement, i tried 8 bit unsigned and 16bit signed ...but nothing seem to work for wave conversion. 

    Can you try one and let me know the procedure to dump and convert to wave file.

  • Hi,

    To be clear, given the configuration of the I2S driver, and unless you have modify it, the data collected should be interpreted as signed 16-bit data.

    I'll work on verifying if the memory dump can be interpreted as wave file.

    Best regards,

  • I have not made any changes, so expecting 16bit PCM samples to be available.

    It would be great if you can verify and let me know the procedure.

  • Hi Vinay,

    Here is such a procedure:

    Prerequisites

    Procedure

    This procedure assumes that we are running some sort of SimpleLink Audio Plugin example (i2secho, for instance).

    Step 1: Capture audio

    Using the microphone, the mono input or the standard Line-In.

    Step 2: Pause execution of the program

    Do that step at any point, as long as the program as been capturing audio for at least 10 seconds.

    Step 3: Dump buffers to a binary file.

    Look for the buf1 variable in the eclipse Memory Browser. It should give out its address (0x20004518 in my case). Take note of its address, you will need it later.

    Check that the buffers are contiguous in the memory, as they should be. Then, right click in the memory browser, and select "Save Memory".

    You will then see the following screen. Pick a path to save your dump file as a RAW binary file.

    Now, in "Start Address", enter the buf1 address that you took note of previously. In "Length in Words", enter 640. ((10 * 256 bytes long buffers) / 4 (32 bit word)).

    Then click on finish to dump the memory file.

    Step 4: Waveform inspection using Audacity.

    Launch the "Audacity" software that you previously downloaded. Click on File → Import → Raw Data. Select your memory file you created during the last step.

    You now encounter the following window. Select "Signed 32-bit PCM", pick "Little Endian" in Byte order, and select the number of channels according to the input source you have choosen in your example program.

    I personally used the "Mono" input source, so I selected "1 Channel (Mono). Then, pick the sample rate you configured your program to capture at. Again, I personally picked 8000 Hz in my source code, and Audacity.

    You should now be able to see the waveform, and export the data to any format of your choosing (WAV, for instance).

  • Thanks Arthur. I tried , but getting very small beep (guessing it is do with only 10buffers of 256 bytes size.). Still not convincing enough to make out whether audio is clean or not.

    In between, why 32bit PCM ?...I thought we are getting 16bit PCM , right?.

  • Hi,

    The reason is that we still consider the audio as stereo even when using the Mono input.

    You can also import the track with those settings. It will sound the same.

  • I did this too ...but my audio is not coming so good. 

    Is it that i am only tapping 256*10 = 2560bytes = 1280 -16bit samples = 1280/8000 =  0.16 sec , is my understanding correct ?

    I am getting it as below. i am playing songs , but hardly getting any portion of songs.

  • Another observation : When i check memory you are expecting buf1 to buf10 to be in contiguous locations, but i see that buf10 is on top of buf1 making it discontinuous.

  • rawdata_8k_wave.zip

    I see my audio is only upto 0.08sec, whereas i am expecting 0.16sec worth of data ....

    Also audio is noisy.

    Can you please let me know what is it that i am missing.

  • Hi Vinay,

    Just to be sure, have you modified the out-of-the-box example to use 8kHz sampling rate or have you kept it to 44.1kHz?

    If the noise is confirmed to be present in the data stored in RAM, please verify the following:

    - use a logic analyzer to analyze the I2S data arriving in the CC1352 input ==> is the noise already present / is the saturation already there?

    - if yes, try to reduce the volume used by the phone ==> is the noise already present / is the saturation still happens?

    - if yes, try to solder short and tight jumper wires.

    I hope this will help,

    Best regards,

  • Hi Clement,

        Yes, i have changed sampling rate to 8KHz and these are the following in code.

    #define SAMPLE_RATE 8000 //44100 /* Supported values: 8kHz, 16kHz, 32kHz and 44.1kHz */
    #define INPUT_OPTION AudioCodec_MIC_MONO //AudioCodec_MIC_LINE_IN
    #define OUTPUT_OPTION AudioCodec_SPEAKER_HP

    With these dumped values are hardly around 0.16sec, hence i am unable to confirm in memory these samples are noisy or not.

    I was thinking to accumulate till 1sec , which would be 8000 samples = 16KBytes.

    Regarding hardware debug, I am operating out of home, so no access to logic analyzer and solder guns.

    I am also suspecting the bent pins could cause problem in terms of Noise, possible ?

    Can you please try on your side and let me know, as i don't have second board to try setups.

  • Could these create saturation level problems : 

    /* Volume control */
    AudioCodec_speakerVolCtrl(AudioCodec_TI_3254, AudioCodec_SPEAKER_HP, 75);
    AudioCodec_micVolCtrl(AudioCodec_TI_3254, AudioCodec_MIC_ONBOARD, 75);

    ?

  • Please see the amount of Noise , i am getting.

  • Hi Vinay,

    Regarding hardware debug, I am operating out of home, so no access to logic analyzer and solder guns.

    I understand, it would have been a great help to debug though.

    Would you happen to have access to a CC2642R device or CC2652R7 device? In that case, you could run the code on this platform to eliminate the need of the jumper wires.

    Can you please try on your side and let me know, as i don't have second board to try setups.

    Arthur have successfully tested the example several times. At the software level, everything looks ok.

    I am also suspecting the bent pins could cause problem in terms of Noise, possible ?

    Bend pins should not have much effect there. In all the cases, this is the only approach possible as non-bending them would create other larger problems.

    Best regards,

  • Ok, i am resetting again and doing recheck of all H/w connections and code.

    But if i want to tap 1 sec worth of samples from buffers, can you please help me how i can tap from memory.

    I tried dumping buf address but not getting data worth of 1sec (after changing buffer size to 16Kbytes). Additionally can you help me understand the i2sTransactions ranging from 1 to 10 distributed between Read and write . 

  • I Just now did a complete reset and started again from beginning .
    To my luck, i found problem. one of the bent pin was touching the CC3200AUDBOOST, hence was causing noise.
    @clement, Would help if you can give above information of tapping the buffers.
  • Hi,

    Well done, thank you for telling us.

    Additionally can you help me understand the i2sTransactions ranging from 1 to 10 distributed between Read and write . 

    Please refer to the example README, especially the section "Application Design Details"

    Would help if you can give above information of tapping the buffers

    Do you mean you want to dump the content of the buffers? Would it be sufficient to use I2S to do so? I mean, the example is already configured to send out over I2S the content of the buffers. If you chose this approach, make sure to comment out the small treatment/filtering implemented in the application code.

    A different approach could consist in increasing the number of buffers (or their size) to have more data kept. Then you can follow the technique suggested by Arthur.

    Best regards,

  • Thanks Clement.
    Let me clarify my question : I basically want to tap the 1second worth of samples. 

    Take 8KHz sampling rate and 1 sec worth of data = 8000*2bytes = 16Kytes of data , i want to dump. (2bytes as we are considering 16bit PCM).

    What arthur showed was such short time glimpse that you cant make out whther audio existed or not. In fact in his snapshot also i can point out towards end there are impulses which are giving very high noise. 

    So taking memory from buf1 looks correct, but buf10 is not in contiguous allocation, hence arthur is also seeing impulses.

    Can you please help me to modify this code to take 1sec worth of audio samples.

  • Hi,

    In that case, I would recommend the following:

    - instead of the buf1, buf2, ..., buf10, declare only one buffer (called BUF) as large as you want (plan to have some margin as it may be difficult to read the very end of the buffer).

    - declare additional I2S transactions. Each transaction will hold 256 bytes (so based on the length of memory allocated before, you can decided how many of them you need). We assume you have NUMBUFS transactions.

    - initialize all the I2S transactions and store them in only one list. The buffers used to hold the data will be BUF[i*BUFSIZE] (with i the transaction number starting at 0).

    - create a ring list of I2S transaction (i.e. have the tail of the list pointing on the head)

                List_tail(&i2sReadList)->next = List_head(&i2sReadList); /* I2S buffers are queued in a ring-list */
                List_head(&i2sReadList)->prev = List_tail(&i2sReadList);

    - only enable I2S read by modifying the params passed to I2S_open. To do so modify the value of i2sParams.SD0Use as shown below.

    i2sParams.SD0Use = I2S_SD0_DISABLED;

    - do not dequeue the messages when the read operation is done (i.e. comment out the following code)

            /* The finished transaction contains data that must be treated */
            List_remove(&i2sReadList, (List_Elem*)transactionFinished);
            List_put(&treatmentList, (List_Elem*)transactionFinished);
    

    - in the readCallback, when the I2S_Transaction passed is the one corresponding to NUMBUFS-2, stop the execution. In practice, you can check the address of the transaction passed, and accessed a dummy-volatile variable with a breakpoint. (I recommend you add the breakpoint after the code has run for a few seconds)

    static void readCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
    
        if(transactionPtr == i2sTransactionList[NUMBUFS-2])
        {
            volatile uint32_t dummy = 10; // Add a break point on this line
        }
    
    }
    

    Once the code is paused, use the steps provided by Arthur to read the content of the buffer. The end of the buffer will probably have old data that should not be considered.

    I hope this will help,

    Best regards,

  • I made the changes as per your advice, and trying to tap buffer_15sec worth of 1.5sec data, by giving length in words as : 12032 (188*256/4).

    But not getting proper audio. Any thing i have missed ?

    File attached

    .

    i2secho.c
    /*
     * Copyright (c) 2015-2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== i2secho.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    #include <stdint.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2S.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    #include "AudioCodec.h"
    
    #define THREADSTACKSIZE   2048
    
    /* The higher the sampling frequency, the less time we have to process the data, but the higher the sound quality. */
    #define SAMPLE_RATE                     16000   /* Supported values: 8kHz, 16kHz, 32kHz and 44.1kHz */
    #define INPUT_OPTION                    AudioCodec_MIC_MONO //AudioCodec_MIC_LINE_IN
    #define OUTPUT_OPTION                   AudioCodec_SPEAKER_HP
    
    /* The more storage space we have, the more delay we have, but the more time we have to process the data. */
    #define DATA_15sec      SAMPLE_RATE*2*1.5 // 48Kbytes, assuming 16bit PCM and 1.5sec worth data.
    #define NUMBUFS         188      /* Total number of buffers to loop through */ /*NUMBUFS = DATA_15sec/256*/
    #define BUFSIZE         256     /* I2S buffer size */
    #define BUFFER_15sec    NUMBUFS*BUFSIZE
    
    /* Semaphore used to indicate that data must be processed */
    static sem_t semDataReadyForTreatment;
    static sem_t semErrorCallback;
    
    /* Lists containing transactions. Each transaction is in turn in these three lists */
    List_List i2sReadList;
    List_List treatmentList;
    List_List i2sWriteList;
    
    /* Buffers containing the data: written by read-interface, modified by treatment, and read by write-interface */
    # if 0
    static uint8_t buf1[BUFSIZE];
    static uint8_t buf2[BUFSIZE];
    static uint8_t buf3[BUFSIZE];
    static uint8_t buf4[BUFSIZE];
    static uint8_t buf5[BUFSIZE];
    static uint8_t buf6[BUFSIZE];
    static uint8_t buf7[BUFSIZE];
    static uint8_t buf8[BUFSIZE];
    static uint8_t buf9[BUFSIZE];
    static uint8_t buf10[BUFSIZE];
    static uint8_t* i2sBufList[NUMBUFS] = {buf1, buf2, buf3, buf4, buf5, buf6, buf7, buf8, buf9, buf10};
    
    /* Transactions will successively be part of the i2sReadList, the treatmentList and the i2sWriteList */
    I2S_Transaction i2sTransaction1;
    I2S_Transaction i2sTransaction2;
    I2S_Transaction i2sTransaction3;
    I2S_Transaction i2sTransaction4;
    I2S_Transaction i2sTransaction5;
    I2S_Transaction i2sTransaction6;
    I2S_Transaction i2sTransaction7;
    I2S_Transaction i2sTransaction8;
    I2S_Transaction i2sTransaction9;
    I2S_Transaction i2sTransaction10;
    static I2S_Transaction *i2sTransactionList[NUMBUFS] = {&i2sTransaction1,  &i2sTransaction2,  &i2sTransaction3,
                                                           &i2sTransaction4,  &i2sTransaction5,  &i2sTransaction6,
                                                           &i2sTransaction7,  &i2sTransaction8,  &i2sTransaction9,
                                                           &i2sTransaction10};
    #endif
    
    static uint8_t buffer_15sec[BUFFER_15sec]; // Buffer worth of 1.5sec with sample rate of 16KHz.
    I2S_Transaction i2sTransaction_15sec[NUMBUFS]; // hold i2sTransaction of 188 size, each worth of 256bytes
    static I2S_Transaction *i2sTransactionList[NUMBUFS];
    
    I2S_Handle i2sHandle;
    
    static void errCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
        /* The content of this callback is executed if an I2S error occurs */
        sem_post(&semErrorCallback);
    }
    
    static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
        /*
         * The content of this callback is executed every time a write-transaction is started
         */
    
        /* We must consider the previous transaction (the current one is not over)  */
        I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);
    
        if(transactionFinished != NULL){
            /*
             * Remove the finished transaction from the write queue and feed
             * the read queue (we do not need anymore the data of this transaction)
             */
            List_remove(&i2sWriteList, (List_Elem*)transactionFinished);
            List_put(&i2sReadList, (List_Elem*)transactionFinished);
    
            /*
             * We do not need to queue transaction here:
             * treatment-function takes care of this :)
             */
        }
    }
    
    static void readCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
        /*
         * The content of this callback is executed every time a read-transaction
         * is started
         */
    
        /* We must consider the previous transaction (the current one is not over) */
        I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);
    
        if(transactionFinished != NULL){
    
            /* The finished transaction contains data that must be treated */
            /*List_remove(&i2sReadList, (List_Elem*)transactionFinished);
            List_put(&treatmentList, (List_Elem*)transactionFinished);*/
    
            if(transactionPtr == i2sTransactionList[NUMBUFS-2])
            {
                    volatile uint32_t dummy = 10; // Add a break point on this line
            }
    
    
            /* Start the treatment of the data */
            sem_post(&semDataReadyForTreatment);
    
            /*
             * We do not need to queue transaction here:
             * writeCallbackFxn takes care of this :)
             */
        }
    }
    
    /*
     *  ======== echoThread ========
     */
    void *echoThread(void *arg0)
    {
        /* Initialize TLV320AIC3254 Codec on Audio BP */
        uint8_t status = AudioCodec_open();
        if( AudioCodec_STATUS_SUCCESS != status)
        {
            /* Error Initializing codec */
            while(1);
        }
    
        /* Configure Codec */
        status =  AudioCodec_config(AudioCodec_TI_3254, AudioCodec_16_BIT,
                                    SAMPLE_RATE, AudioCodec_STEREO, AudioCodec_SPEAKER_HP,
                                    AudioCodec_MIC_LINE_IN);
        if( AudioCodec_STATUS_SUCCESS != status)
        {
            /* Error Initializing codec */
            while(1);
        }
    
        /* Volume control */
        AudioCodec_speakerVolCtrl(AudioCodec_TI_3254, AudioCodec_SPEAKER_HP, 75);
        AudioCodec_micVolCtrl(AudioCodec_TI_3254, AudioCodec_MIC_ONBOARD, 75);
    
        /* Prepare the semaphore */
        int retc = sem_init(&semDataReadyForTreatment, 0, 0);
        if (retc == -1) {
            while (1);
        }
    
        /*
         *  Open the I2S driver
         */
        I2S_Params i2sParams;
        I2S_Params_init(&i2sParams);
        i2sParams.samplingFrequency =  SAMPLE_RATE;
        i2sParams.fixedBufferLength =  BUFSIZE;
        i2sParams.writeCallback     =  writeCallbackFxn ;
        i2sParams.readCallback      =  readCallbackFxn ;
        i2sParams.errorCallback     =  errCallbackFxn;
        i2sParams.SD0Use = I2S_SD0_DISABLED;
        i2sHandle = I2S_open(CONFIG_I2S_0, &i2sParams);
        if (i2sHandle == NULL) {
            /* Error Opening the I2S driver */
            while(1);
        }
    
        /* Initialize the queues and the I2S transactions */
        List_clearList(&i2sReadList);
        List_clearList(&treatmentList);
        List_clearList(&i2sWriteList);
    
        uint8_t k;
        for(k=0;k<NUMBUFS;k++){
            i2sTransactionList[k] = &(i2sTransaction_15sec[k]);
        }
        /* Half the transactions are initially stored in the read queue */
        for(k = 0; k < NUMBUFS; k++) {
            I2S_Transaction_init(i2sTransactionList[k]);
            i2sTransactionList[k]->bufPtr  = &(buffer_15sec[k*BUFSIZE]); //i2sBufList[k];
            i2sTransactionList[k]->bufSize = BUFSIZE;
            List_put(&i2sReadList, (List_Elem*)i2sTransactionList[k]);
        }
    
        /* The second half of the transactions is stored in the write queue */
    #if 0
        for(k = NUMBUFS/2; k < NUMBUFS; k++) {
            I2S_Transaction_init(i2sTransactionList[k]);
            i2sTransactionList[k]->bufPtr  = i2sBufList[k];
            i2sTransactionList[k]->bufSize = BUFSIZE;
            List_put(&i2sWriteList, (List_Elem*)i2sTransactionList[k]);
        }
    #endif
    
    
        I2S_setReadQueueHead(i2sHandle,  (I2S_Transaction*) List_head(&i2sReadList));
    //    I2S_setWriteQueueHead(i2sHandle, (I2S_Transaction*) List_head(&i2sWriteList));
        List_tail(&i2sReadList)->next = List_head(&i2sReadList); /* I2S buffers are queued in a ring-list */
        List_head(&i2sReadList)->prev = List_tail(&i2sReadList);
    
        /* Start I2S streaming */
        I2S_startClocks(i2sHandle);
        I2S_startRead(i2sHandle);
        I2S_startWrite(i2sHandle);
    
        /* Treatment */
        while(1){
    
            /* Wait for transaction ready for treatment */
            retc = sem_wait(&semDataReadyForTreatment);
            if (retc == -1) {
                while (1);
            }
    
            I2S_Transaction* transactionToTreat = (I2S_Transaction*) List_head(&treatmentList);
    
            if(transactionToTreat != NULL){
                /*
                 * Treatment:
                 *   The higher the sampling frequency,
                 *   the less time we have to process the data
                 */
                #if SAMPLE_RATE > 16000
                    /* No data processing */
                #elif SAMPLE_RATE > 8000
                    /* Data processing */
                    int16_t *buf = transactionToTreat->bufPtr;
                    /* bufSize is expressed in bytes but samples to consider are 16 bits long */
                    uint16_t numOfSamples = transactionToTreat->bufSize / sizeof(uint16_t);
                    uint16_t n;
                    /* We only modify Left channel's samples () */
                    for(n=0; n<numOfSamples-2; n=n+2) {
                        /*
                         * Here we use a very basic filter
                         * (average to reduce noise level on left channel)
                         *
                         * Note: data coming from left channel and right channel
                         * are interleaved
                         */
                        buf[n] = (buf[n] + buf[n+2]) / 2;
                    }
                #else
                    /* Data processing */
                    int16_t *buf = transactionToTreat->bufPtr;
                    uint16_t numOfSamples = transactionToTreat->bufSize / sizeof(uint16_t);
                    uint16_t n;
                    /* We modify both channel's samples */
                    for(n=0; n<numOfSamples-2; n=n+1) {
                        /*
                         * Here we use a very basic filter (average to reduce noise level)
                         *
                         * Note: data coming from left channel and right channel
                         * are interleaved
                         */
                        buf[n] = (buf[n] + buf[n+2]) / 2;
                    }
                #endif
    
                /* Place in the write-list the transaction we just treated */
                List_remove(&treatmentList, (List_Elem*)transactionToTreat);
                List_put(&i2sWriteList, (List_Elem*)transactionToTreat);
            }
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_t           thread0;
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
        int                 detachState;
    
        /* Call driver init functions */
        I2S_init();
    
    /* On CC32XX, do not enable GPIO due to an LED/I2S pin conflict */
    #if !(defined(DeviceFamily_CC3200) || defined(DeviceFamily_CC3220) || defined(DeviceFamily_CC3235))
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    #endif
    
        /* Set priority and stack size attributes */
        pthread_attr_init(&attrs);
        priParam.sched_priority = 1;
    
        detachState = PTHREAD_CREATE_DETACHED;
        retc = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0) {
            /* pthread_attr_setdetachstate() failed */
            while (1);
        }
    
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0) {
            /* pthread_attr_setstacksize() failed */
            while (1);
        }
    
        /* Create receive thread */
        retc = pthread_create(&thread0, &attrs, echoThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1);
        }
    
        retc = sem_init(&semErrorCallback, 0, 0);
        if (retc == -1) {
            /* sem_init() failed */
            while (1);
        }
    
        /* Wait forever for an error */
        sem_wait(&semErrorCallback);
    
        /* Cancel the echo thread (blocks until the thread is closed) */
        pthread_cancel(&thread0);
    
        /* Close the driver */
        I2S_stopClocks(i2sHandle);
        I2S_close(i2sHandle);
    
        /* End this task */
        return NULL;
    }
    

  • Hi Clement,

        Can you please tell me how to turn On the onboard Mic ?

    I used this macro AudioCodec_MIC_ONBOARD and intialized to INPUT_OPTIONS and also in Audiocodec_config , so that it initializes to read onboard mic.

    Do i need to use different Maco ?

  • Hi,

    Regarding tapping the audio:

    - You are still applying a dummy treatment on the audio

    - You have enabled write (and you should not)

    - Could you please explain what "not proper audio" means?

    Regarding using the onboard Micro:

    - actually I do not manage to enable it me neither. I know it only require to reconfigure the hardware codec on the booster pack but I haven't found exactly how

    Best regards,

  • By any chance this (to enable microphone)  requires audio plugin ?

  • I mean this : 

    SimpleLink Audio Plugin

  • Hi,

    No, the SimpleLink Audio Plugin is not required to enable the onboard microphone. Actually, this is a setting that needs to be enabled in the Hardware Codec.

    Looking in the code (I do not have a board at the moment to test), it looks like the onboard microphone can be enabled in the i2secho example when calling AudioCodec_config(). Please try to use AudioCodec_MIC_ONBOARD as last parameter.

    Best regards,

  • I have already tried Audio_Codec_MIC_ONBOARD  in audiocodec config, but no luck.

    infact i have tried setting 0xFF , enabling all possible microphone, but that also did not work.