0

I am trying to transmit audio using CAN FD and the data format it sends it is in uint8_t, when the sample I take from the microphone with the ADC is an uint32_t. Will I have any problem trying to insert this uint8_t data into a wav after being transmitted with CAN FD? I have tried to create .wav with the data but I only hear noise.

This is and image of a .wav file I create with a simple 64 byte CAN FD message.

.wav file

I know only introducing 64 bytes is a really small amount for a .wav but I dont know how to concatenate more data into a buffer in order to get bigger files. Thiis the function I use to create my .wav

void write_little_endian(unsigned int word, int num_bytes, FILE *wav_file)
    {
        uint16_t buf;
        while(num_bytes>0)
        {   buf = word & 0xff;
            fwrite(&buf, 1,1, wav_file);
            num_bytes--;
        word >>= 8;
        }
    }

void write_wav(char * filename, unsigned long num_samples, short int * data, int s_rate)
    {
        FILE* wav_file;
        unsigned int sample_rate;
        unsigned int num_channels;
        unsigned int bytes_per_sample;
        unsigned int byte_rate;
        unsigned long i;    /* counter for samples */

        num_channels = 1;   /* monoaural */
        bytes_per_sample = 1;

        if (s_rate<=0) sample_rate = 16000;
        else sample_rate = (unsigned int) s_rate;

        byte_rate = sample_rate*num_channels*bytes_per_sample;

        wav_file = fopen(filename, "wb");
        assert(wav_file);   /* make sure it opened */

        /* write RIFF header */
        fwrite("RIFF", 1, 4, wav_file);

        write_little_endian(36 + bytes_per_sample* num_samples*num_channels, 4, wav_file);
        fwrite("WAVE", 1, 4, wav_file);

        /* write fmt  subchunk */
        fwrite("fmt ", 1, 4, wav_file);

        write_little_endian(16, 4, wav_file);   /* SubChunk1Size is 16 */
        write_little_endian(1, 2, wav_file);    /* PCM is format 1 */
        write_little_endian(num_channels, 2, wav_file);
        write_little_endian(sample_rate, 4, wav_file);
        write_little_endian(byte_rate, 4, wav_file);
        write_little_endian(num_channels*bytes_per_sample, 2, wav_file);  /* block align */
        write_little_endian(8*bytes_per_sample, 2, wav_file);  /* bits/sample */

        /* write data subchunk */
        fwrite("data", 1, 4, wav_file);
        write_little_endian(bytes_per_sample* num_samples*num_channels, 4, wav_file);
        for (i=0; i< num_samples; i++)
        {   write_little_endian((unsigned int)(data[i]),bytes_per_sample, wav_file);
        }

        fclose(wav_file);
    }

I send this command to call it and I receive what I will post on the next image:

write_wav("test.wav", 44100, (short int *)buffer, 44100);

.wav with a bigger buffer of 44100 samples of uint16_t

But when I play this file, the audio is just beeps and noise, not my voice :(

Update = After some tries, I think the problem resides in the data I send throught the CAN FD. I have watched the data inside another .wav and the format doesnt look similar to mines. I dont know how to send uint32_t data that I acquire with the ADC through a uint8_t format CAN FD data field. I have tried casting the data but I dont know how to prepare it for the .wav Can anyone help me with that? Should I send it with uint8_t and then back to uin32_t before inserting it into a .wav?

Suspe18
  • 15
  • 7
  • read up on raw audio format called PCM which is simply a set of integers which represent the height of the raw audio curve ... when transforming from one audio format into another you need to convert the audio from format A into PCM then from PCM into format B ... I suggest you limit to mono audio instead of stereo for starters as it simplifies examining the data ... I strongly suggest you plot this PCM audio or use a known input audio say a sin wave so you can confirm the data is correct ... focus on confirming your PCM audio is valid before worrying about creating a WAV file from the PCM – Scott Stensland Jan 14 '22 at 14:32
  • I don't really know how to approach PCM to be honest. I am sampling the microphone with the 12bit resolution ADC that my STM32 device has, I know the configuration is the proper one because I have tried the same on the demo program. But when I transmit the data through CAN FD it doesnt look the same the demo fills in his .wav program. The demo .wav and the one with my program doesn't look similar. – Suspe18 Jan 14 '22 at 15:00

1 Answers1

0

It depends on what sample rate you need. At 5 Mbps baudrate, 11 bit identifiers, 64 byte data, the effective payload will be transferred at roughly 4 Mbps (this can be calculated fairly exactly). The MCU will need a bit of execution time to process it, but it's probably negligible. That is, the real time spec by far exceeds at what sample rates the human ear stop hearing any differences at. Your problems aren't related to picking CAN FD as hardware/datalink layer. You could likely do this with classic CAN just fine too.

Obviously don't transfer files but raw data. It only needs to be turned into a file before playing.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thank you for the comment. I am transmitting the raw data to the other device, and then convert it into a .wav so I can listen to it. The thing is that when I convert the data I am not able to listen to what a recorded through the microphone and I only listen to beeps or noise. I have used some code from internet that converts the data into .wav but I dont know if the format of the data that I send into that .wav is properly placed. – Suspe18 Jan 14 '22 at 09:40