Skippy MP3 Streaming

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,

I created a new topic as I believe that this question has deviated from the other topic. I'm going to attach my code at the end. It might be sloppy, but I'm just trying to get it working.

Ok, still have problems. I got the buffer working, using a length of around 1500 characters right now. I make it circular such that the index goes back to the beginning and if there's an overrun, I have it freeze and notify me.

I checked my algorithm by sending a preset string of 32 characters repeatedly and counted hits and misses. No misses were counted and to make sure test was not invalid, I changed algorithm slightly and misses came up whenever buffer looped.

I also implemented software flow control by sending XON and XOFF characters from the AVR. I've tested and can confirm that it works.

The problem is that for some reason the output clicks and pops and plays too fast with a lot of distortion. I'll post the section of code that performs it, maybe there's something wrong?

for (;;)
{
  if (length >= 32)
  {  
    if bit_is_set(PINB, DREQ)
		{
		  sendMP3();
      count1++;
	  }
  }
  
  if (count1 >= 1000)
  {
    count1=0;
    printf("Length = %u\n",length);
  }

  if ((length <= 600) && (send == 0))
  {
    USART_Transmit(XON);
    send = 1;
  }
}

I should note that I have it sending XOFF in the ISR if the buffer gets more full than 1200. My buffer size is 1536.

Whether I get any output or not really seems to depend on the numbers I'm using. For example, if I send if the buffer is greater than 32 characters only, it doesn't play, but if I make keep a mandatory buffer of more than 128 characters it doesn't play either.

It plays really jerky and the length is always 0. Any ideas? Also, a lot of times in the middle of the song it'll stop decoding and freeze.

I finally got an o-scope and can see that the data going out in 32 byte packets about every 2ms.

I'm using 2Mbaud UART transmission which I've tested and is error free. I'm using a 1MHz SPI connection which is 1/4 the maximum stated in the manual of the MP3 device of 4MHz. I'm using the VS1002 MP3 chip.

I'm assuming that the MP3 chip reads the bitrate and sampling frequency from the MP3 data and sets those as playback settings. Then, I'm assuming, it would accept data into its buffer and send DREQ low whenever that buffer is full and can't accept another 32 bytes. My program essentially monitors this pin and whenever it goes low, sends a chunk of 32 bytes using the following code:

void sendMP3(void)
{
  for (i=0; i<32; i++)
  {
    SPI_MasterTransmit(buffer[start]);
    start++;
    length--;
  }

  if (start == (buffsize-1))
    start=0;
}

For completeness' sake, here's my ISR code:

ISR(USART0_RX_vect)
{
  cli();
  buffer[end]=UDR0;
  end++;
  length++;
  if (length>buffsize)//buffer overflow, loop forever
  {
    printf("overflow");
    for (;;)
    {}
	}

  if ((length >= 1200) && (send == 1))
  {
    USART_Transmit(XOFF);
    send = 0;
  }

  if (end == (buffsize-1))
    end=0;
  sei();
}

Anything I'm overlooking?

Thanks,
JH

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can't open the file right now, but are the variables used in interrupts and normal code declared volatile?

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

Is the file not working? Yes, variables used in interrupts and normal code are declared volatile. I might have declared my other global variables volatile as well, does this create a problem?

JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I'm assuming that the MP3 chip reads the bitrate and sampling frequency from the MP3 data and sets those as playback settings. Then, I'm assuming, it would accept data into its buffer and send DREQ low whenever that buffer is full and can't accept another 32 bytes. My program essentially monitors this pin and whenever it goes low, sends a chunk of 32 bytes using the following code:

That's not what the datasheet says: if dreq is *high*, send 32 bytes (or a command). Then check again; if it's still high, send another 32 bytes; if it's low don't send anything.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

Yea, you're right, my mistake. My code does monitor for when it goes high, just as you said. I just misspoke.

Let me know if you find any problems with my code, or have any ideas for why it's skipping, playing distorted and too fast.

Thanks,

JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

printf()'s in ISR's ?

That rings alarm bells!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would normally never use a printf in an ISR, except that it's an indication of overflow and I freeze the process there anyway. If that printf gets executed, I'm in trouble to begin with.

Let me know if anything else rings bells :).

JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys,

Thanks for the help on this project. The project is due on Tuesday, and I'm kind of resigned to the fact that MP3 functionality will likely not be included barring some miraculous discovery.

I ordered a backup decoder chip from futurlec a while back and it'll get here on Monday. Maybe my original chip partially broke and this one will work... Reaching, but whatever.

My project is a multi-function wireless alarm clock and I'm hoping to eventually use it myself. I will likely continue working on this after the quarter is over and would appreciate any input you guys may have.

Thanks,
JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe you set wrong value to SCI_CLOCKF register in VS1002. And minimal input clock for VS1002 is 12Mhz, you have 4Mhz

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

what fuctions does the alarm clock have and what more will you add?

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Pinka and JW,

I tested and am pretty sure that I put the right value in SCI_CLOCKF. I enabled the clock doubler and set the clock value to be 12.288MHz. This crystal was provided on the SparkFun breakout board that I bought for the VS1002. I put in a sine test that should result in ~5kHz output based on the manual, and I measured that on an o-scope.

As to the input clock, I'm assuming you're referring to the SPI clock. If you're not, please let me know as that could be a bug. The SPI clock has a maximum speed of 4MHz.

JW-
So far the alarm clock has alarm settings that can be set by the computer as well as time synchronization with the computer. The computer also sends an array of random numbers between 20 and 60. During the alarm signal the LCD prompts for input for the multiplication and addition of some of these numbers. If correct, the alarm will turn off.

The connection is done with a Bluetooth connection.

Right now the computer can send an MP3 to the device and it will play, but there's distortion and it plays too fast.

There is button input, LCD output, and 7-segment array output for time. The 7-segment array is run by a LED driver that takes SPI input at 500kHz.

JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok,

Quick question. For some reason, when I start streaming a lot of times, my MCU just restarts. Any idea why this would be happening? It's in the STK500.

JH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at the control register that contains the flags that say why the chip just reset (probably MCUCSR)