Search code examples
embeddedstm32wavcan-busadc

Audio through CAN FD into headphones


I am trying to record audio using a 12 bit resolution ADC, take the sample buffer and send it through CAN FD to another device, which takes samples of this audio and creates a .wav and plays it. The problem is that I see the data of the microphone being sent through CAN FD to the other device, but I am not able to transform this data into a .wav file properly and hear what I say through the microphone. I only hear beeps.

I'm creating a new .wav every 4 CAN FD messages in order to make some kind of real time communication and decrease the delay, but I don't think this is possible or if I am thinking it the proper way.

In this thread I take the message sent by the CAN FD and concatenate it in a buffer in order to introduce it in a .wav file. I have tried bigger buffers but it doesn't change the outcome. How could I be able to take the data from the CAN FD and hear it?

Clarification: I know using CAN FD to transmit audio isn't the proper way, but it is for a master project.

struct canfd_frame frame;
 CAN_MSG msg;
    int trama_can[72];
    int nbytes;
    while (status_libreria == 0)
        ;
    unsigned char buffer[256];
    // FILE * fPtr;
    int i=0,x=0;
    //fPtr = fopen("Test.txt", "w");
    while (1) {
        do {
            nbytes = read(s, &frame, sizeof(struct canfd_frame));
        } while (nbytes == 0);
        msg.id.ext = frame.can_id;
        msg.dlc = frame.len;

        if (msg.dlc > 8)
            msg.dlc = 8; //Protecci�n hasta adaptar AC3LIB a CANFD

        Numas_memcpy(&(msg.data.bdata), &(frame.data), msg.dlc);

        can_frame_2_ac3lib(&msg, BUS_VERTICAL);
        for(x=0;x<64;x++) buffer[i*64+x] = frame.data[x];
        printf("%d \r\n",frame.data[x]);
        printf("i:%d \r\n",i);
        // Copiar datos a fichero.wav y reproducirlo simultaneamente
        if (i == 3) {
            printf("Datos IN\r\n");
            write_wav("prueba.wav",256 , (short int *)buffer, 16000);

            //fwrite(buffer,1,sizeof(buffer),fPtr);
            //fclose(fPtr);
            system("aplay prueba.wav -f cd");
            i = 0;
            system("rm prueba.wav");
        }
        i++;
    }

32 first bytes of the audio file being recorded

In the picture, as you can see, the data is being recorded. moreover, this data is the same data as in the ADC, but when I play it, I only hear noise.


Solution

  • Simplify the problem first. Make sure you can transmit known data from one end to the other first at low rates. I'm sure the suggestion below will sound far too trivial. But until you are absolutely confident you understand it all, I predict you sill have many struggles.

    Slowly - one frame per second, or even slower.

    • Learn to send one 0x55 byte from one end to the other and verify at the receiver.
    • Learn to send a few 0x55 in one frame and verify.
    • Learn to send 0x12345678 - verify it ends up with the bytes in the right order at the other end
    • Learn to send a counter. Check it at the receiver, make sure you do not drop any data.

    Now do it all again but 10x faster.

    Continue until you can send a counter at 10x the rate you need to for the audio without dropping any frames at all, for minutes and then hours.

    Stress the rest of the system to make sure it still works under stress.

    Only now, can you start to learn about sending audio.

    Trust me, you will learn a lot!