VS1053 noisy recording NodeMCU

Writing software for systems that use VLSI Solution's devices as slave codecs to a host microcontroller.
ys123
User
Posts: 12
Joined: Fri 2017-01-27 13:12

Re: VS1053 noisy recording NodeMCU

Postby ys123 » Wed 2017-02-08 16:28

I've got some updates. First, I've written a program that streams the sound over wifi using UDP to a client. The client then writes the packages to disk as a WAV file (header is also written). While it sounds a lot better, there seem to be small chuncks of audio missing causing it to play faster.

Recorded as PCM, 8000Hz mono.
Attachments
out.wav
(63.52 KiB) Downloaded 15 times

Hannu
User
Posts: 9
Joined: Mon 2016-05-30 11:54

Re: VS1053 noisy recording NodeMCU

Postby Hannu » Thu 2017-02-09 9:32

Just a small thing. UDP doesn't have any quality of service. Packet may drop silently or they can arrive in wrong order.

I would suggest a counter on start of each packet which can then be skipped when further processed. That way the wrong order can be detected and packets can be reordered.

Dropped packets are harder. You need to have some resend ring buffer and if packet doesn't arrive, you need to be able to query the dropped packet before it is overwritten in buffer. and the amount of memory, network lag and packet size determine the size of the ring buffer and count of elements on it.

Or writing zero to missing parts is another solution.

But for starters, adding counter and logging numbers would be a good start for debugging.

ys123
User
Posts: 12
Joined: Fri 2017-01-27 13:12

Re: VS1053 noisy recording NodeMCU

Postby ys123 » Wed 2017-02-15 15:36

After checking the network, it seems the packets are all being transferred properly. It seems there are some small gaps in the sound, could it be I'm not reading the vs1053 buffer fast enough?

User avatar
pasi
VLSI Staff
Posts: 1313
Joined: Thu 2010-07-15 16:04

Re: VS1053 noisy recording NodeMCU

Postby pasi » Wed 2017-02-15 15:39

How short are the gap?

Do you have samplerate adjustment on the playback side? The crystal frequency of two units are never the same, so for real-time sources the playback needs to adjust the samplerate according to the actual source audio rate. (I.e. in practice according to the FIFO fill state on the playback device.)
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

ys123
User
Posts: 12
Joined: Fri 2017-01-27 13:12

Re: VS1053 noisy recording NodeMCU

Postby ys123 » Mon 2017-02-20 12:36

The gap is about ~0.030 seconds. The speed is now correct, although as you can see there are clear gaps in the sound.

I'm reading the words in such a way:

Code: Select all

   while(1)
      while (wordswaiting > 255)
         send buffer
         wordswaiting - 255
         
         if(wordswaiting > 0 & wordswaiting < 255)
            send remaining buffer
Attachments
Capture.PNG
Capture.PNG (27.15 KiB) Viewed 130 times

User avatar
pasi
VLSI Staff
Posts: 1313
Joined: Thu 2010-07-15 16:04

Re: VS1053 noisy recording NodeMCU

Postby pasi » Mon 2017-02-20 13:17

The gaps occur too often and last too long to be arising from crystal frequency difference.

Check that you are not sending extra data to SDI accidentally.

Is there any way you could save the data you are sending to the vs1053 for analysis?

Do you have an oscilloscope that you could use to monitor the frequency of the audio packets sent and received?
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

ys123
User
Posts: 12
Joined: Fri 2017-01-27 13:12

Re: VS1053 noisy recording NodeMCU

Postby ys123 » Mon 2017-02-20 17:19

pasi wrote:The gaps occur too often and last too long to be arising from crystal frequency difference.

Check that you are not sending extra data to SDI accidentally.

Is there any way you could save the data you are sending to the vs1053 for analysis?

Do you have an oscilloscope that you could use to monitor the frequency of the audio packets sent and received?


Attached is the original sound, and the sound recorded by the vs1053. Please note that it is a loud recording, although it's not clipped.

Unfortunately I don't have access to an oscilloscope in my workplace. I use the 'Plot Spectrum' feature from Audacity to check the frequency of the recording.

If there is anything I can do, please let me know. Also, if you'd need the used code let me know.
Attachments
out.wav
Recorded sound, 8kHz mono
(200.04 KiB) Downloaded 7 times
500-1500.wav
Original 500-1500Hz sound
(31.29 KiB) Downloaded 6 times

User avatar
pasi
VLSI Staff
Posts: 1313
Joined: Thu 2010-07-15 16:04

Re: VS1053 noisy recording NodeMCU

Postby pasi » Mon 2017-02-20 18:37

One sweep is 2 seconds, but in the output there's less data. The output also contains both zero-data, indicating there is not enough data to play back (DAC underflow), causing the signal to be faded towards 0, and portions where the signal jumps, like there is data missing.

So, both point to either the transmitter not reading all of the data from vs1053, reading the wrong amount, or the receiver not getting all of the data.

Both ends seem to agree on the samplerate.

I don't think this is a word/byte issue, but it doesn't hurt to check. (I.e. check if you are reading words instead of bytes, getting double the amount of data sometimes, and wrapping the buffer, then getting the fill state to indicate less data available on the next read.)
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

ys123
User
Posts: 12
Joined: Fri 2017-01-27 13:12

Re: VS1053 noisy recording NodeMCU

Postby ys123 » Wed 2017-03-01 12:15

I'm reading the vs1053 in two ways. The code below produces the sound you've heard in my previous post.

Code: Select all

const int RECBUFFSIZE {510};
const int WORD_SIZE { RECBUFFSIZE / 2 };
const int PACKET_SIZE { RECBUFFSIZE + 2 };

char recording_buffer[RECBUFFSIZE];

while(1)
      {
         yield();
         
         uint16_t wordswaiting = musicPlayer.recordedWordsWaiting();
               
         while(wordswaiting >= WORD_SIZE)
         {
            uint16_t ww = WORD_SIZE;
            recording_buffer[0] = (ww * 2) >> 8;
            recording_buffer[1] = (ww * 2) & 0xFF;
                  
            for(int i=2; i < PACKET_SIZE; i += 2)
            {
               uint16_t t = musicPlayer.recordedReadWord();
               recording_buffer[i] = t & 0xFF;
               recording_buffer[i+1] = t >> 8;
            }
                                    
            Udp.beginPacket(remote_ip, remote_port);
            Udp.write(recording_buffer, PACKET_SIZE);
            Udp.endPacket();
               
            wordswaiting -= WORD_SIZE;

            if(wordswaiting > 0 && wordswaiting < WORD_SIZE)
            {
               memset(recording_buffer, 0, RECBUFFSIZE);
               ww = wordswaiting;
               
               recording_buffer[0] = (ww * 2) >> 8;
               recording_buffer[1] = (ww * 2) & 0xFF;
                     
               for(int i=2; i < wordswaiting; i += 2)
               {
                  uint16_t t = musicPlayer.recordedReadWord();
                  recording_buffer[i] = t & 0xFF;
                  recording_buffer[i+1] = t >> 8;
               }
                     
               Udp.beginPacket(remote_ip, remote_port);
               Udp.write(recording_buffer, PACKET_SIZE);
               Udp.endPacket();
               
               wordswaiting -= wordswaiting;
            }

         }
      }

Because the receiving end reads the entire package (except the first two bytes), there are gaps in the sound. However, when I'm reading from the vs1053 in the following way, it plays back a lot faster. The following code is taken from the vs1053 manual (section 2.3.3).

Code: Select all

const int RECBUFFSIZE {512};
char recording_buffer[RECBUFFSIZE];

      while(1)
      {
         uint16_t n = musicPlayer.recordedWordsWaiting();
         
         if(n >= 256)
         {
            int i;
            for(i=0; i < RECBUFFSIZE; i+=2)
            {
               uint16_t t = musicPlayer.recordedReadWord();
               recording_buffer[i] = t & 0xFF;
               recording_buffer[i+1] = t >> 8;
            }
            
            Udp.beginPacket(remote_ip, remote_port);
            Udp.write(recording_buffer, RECBUFFSIZE);
            Udp.endPacket();
         }
         else
            delay(1);
      }


The delay(1) function makes the program freeze for 1ms (sometimes I measured 2ms), and gives the background thread handling the WiFi/network stack a chance. This code produces the sound you can hear that I've attached. As you can hear it's not entirely fluid, the input file is the same one from my previous post.

As far as I know, I should be reading the vs1053 in the correct way.
Attachments
Capture.PNG
Capture.PNG (69.05 KiB) Viewed 66 times
out.wav
(200.04 KiB) Downloaded 6 times

User avatar
Henrik
VLSI Staff
Posts: 1008
Joined: Tue 2010-06-22 14:10

Re: VS1053 noisy recording NodeMCU

Postby Henrik » Wed 2017-03-15 13:08

Hello!

Have you been able to solve the problem?

I looked at your file (out.wav) and to me it seems obvious that some portions of data have been left out - most likely because you read it too slow. There are clear jumps in the data. Actually, from the jumps it seems to me that you leave almost exactly 50% of the data unread - whether that happens by a programming error or by data not being read fast enough and VS1053 data buffer overflowing.

To check for this, you might want to use a slower data format, e.i. try recording 4-bit IMA ADPCM instead of 16-bit PCM. (Remember to adjust headers accordingly or you'll just get noise.)

Kind regards,
- Henrik
Good signatures never die. They just fade away.


Return to “Microcontroller Software”

Who is online

Users browsing this forum: No registered users