1 bit PCM playback in C

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

In know Anthony Barrett made what appears to be a very nice audio player, and I have certainly learned quite a bit from his project, I'm just a bit unsure about exactly how to use the data. I want to port that project to C, and add a TWI EEPROM to get a lot more playback time. I don't think TWI will keep up with even 8khz reading a byte or two at a time, but if I load up huge chunks (1 to 2K) at a time I can play short clips with minimal delay in between.

So my question is this: how exactly does 1 bit PCM work, what do I do with each bit and when do I do it?

"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
-- Douglas Adams

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

Its called delta modulation.... in the transmitter each bit is the difference between the input and the bit you just sent. Basically a comparator! The receiver is a resistor and capacitor. Send a string of 1111s into it, the cap charges. Send a string of 0000s, the cap dischargers towrd zero. Send 01010101 and it sort of stays the same. Each step is a clock... so if you want 8 bit audio at 4khz, you need to clock about 256 times 4khz. Thats a lot of bits. Ususally there is an 'adaptive' part that uses a 16 or 32khz clock, but each bit represents a step size that varies depending on how fast the signal is changing.

Imagecraft compiler user

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

KillerSpud wrote:
I don't think TWI will keep up with even 8khz reading a byte or two at a time, but if I load up huge chunks (1 to 2K) at a time I can play short clips with minimal delay in between.

8-bit 8 kHz PCM means 64 kilobits per second. TWI hardware goes up to 400kHz transfer rate, but depending on your memory device it may be limited to 100kHz. As it transfers 9 bits per byte, it translates well more then 64 kilobits per second, even when time taken to set up the transfer or handling the TWI module is taken into account. This requires either continuous reading of memory in single big block (you can start reading once and read single byte again when needed) or in multiple small blocks (more than few bytes).

You can have continuous playback if you have for example one 1kb buffer, but think of it as two halves of 512 byte buffers, and right after one of the 512 byte buffers has been played out, you read new data to it while playing the other 512 byte buffer. I guess this is called double buffering or ping-pong buffering.

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

Quote:
TWI hardware goes up to 400kHz transfer rate,
Fast-mode Plus I2C devices can go up to 1MHz now an possibly higher. Not sure how Atmel TWI does handle that.

edit anyway after "my favourite screen" appeared and cound not edit or do anything I was going to say that HS mode goes up to 3.4MHz.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Sooo... running at 16KHz, do I need to change the bit every (1/16k) 62.5 uS? Thats kinda fast, but I figure I can do it. At that rate it would take 2K bytes (16K bits / 8) per second, and to transfer that from a TWI EEPROM would take about 5 mS ((2k * 9 {8 + ack}) / 400k). I suppose if I used an interrupt to drive the sound output I could have a pretty comfortable buffer, say using 500 byte blocks.

Now, doing some more math, 8 bits would hang around for about 500uS, or 62.5uS per bit. It would take 12.5uS to fetch a byte from the EEPROM (address/w, pointerH, PointerL, address/R, data). Its a tight fit, but I think it is doable, even without interrupts.

The next hurdle will be programming the EEPROM, how do I load that sound file onto it? at 128K x 8 I don't have anything that can store that on flash. Ok, so an ATmega1284 could hold it all, but I don't have one of those (and its the only model that comes in PDIP).

I could possibly load it via serial, but I know nothing about how download protocols work. I seem to remember something about raw dumps, but its been about a decade and a half since I've even looked at it.

Ideas anyone?

"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
-- Douglas Adams

Last Edited: Sun. May 31, 2009 - 04:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Point is not to read single byte blocks from TWI eeprom. After you have read ONE byte from it, you can just pause communications and or read as many bytes you wish - it's still a single read operation. Send STOP and new read address only when you need to jump into different address.

If you have any kind of serial communication working, you can just have a command after which the AVR waits for 128kbytes for example and stores them into eeprom when bytes are arriving. Remember to write data into eeprom in blocks that are of correct size for your eeprom, otherwise if you write one byte at a time, you waste both time and eeprom endurance, as it will program the whole block at a time even if you change just one bit or byte.

If you want to have a protocol for that, check out XMODEM. It uses 128 or 1024 byte blocks, which are quite big when thinking about TWI eeprom writing. But then again, your eeprom is so large it may have 32 byte blocks.

If you want more storage space, transfer speed etc, you could use SD or MMC cards.

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

the only reason I would consider reading a single byte at a time is to keep the code straight forward and simple. Keeping track of buffers takes a lot more coding and planning and interrupts. If I can simply use polling I only need to do one thing at a time.

However, with this particular application I may be able to keep each sound sample small enough to fit in SRAM. It will be speaking individual words and numbers, like voice mail or a bank's phone teller.

"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
-- Douglas Adams

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

I claim for speech ADPCM gives lowest data rate... 8bit 8khz pcm=8 kbytes per sec, differential pcm cuts that in half by sending signed 4 bit differences between samples packed into bytes (4kbytes per sec), the adaptive part cuts it in half again to 2 kbytes per sec.... 16k bits per sec.

Imagecraft compiler user