Page 1 of 1

Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu May 28, 2015 7:19 pm
by SpyderTL
I've started looking into reading PCM data from audio CDs, and it's turning out to be a little more complicated than I was expecting.

I only found one mention on the wiki here: Optical Drive

But there's not a lot of detail. I've got ISO9660 and CDFS code working. I just need to figure out how to modify it to read raw data. So far, I've found SCSI commands 0xBE, to read the various headers and channels, and 0xB9 to read raw user data. It looks like I could use either or these to get what I need, but I thought I'd check with you guys and see if I'm on the right track, and see if anyone had any suggestions, or working open source code I could look at.

Thanks guys. I'll add some information to the wiki when I get everything figured out.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Mon Jun 08, 2015 12:28 pm
by SpyderTL
Alright, I've made some progress with Audio CDs. I've successfully used the SCSI Read TOC command (0x43) to get a list of tracks and their starting position.

Now I'm having problems trying to get the raw audio data for those tracks, using either SCSI Read CD (0xBE), or SCSI Read CD MSF (0xB9).

If I request no fields at all, I get back a bunch of zeros, which makes sense. If I request no tracks, the status field (I'm using ATAPI, btw), just goes back to ready with no data request flag being set, which also makes sense.

But for some reason, if I request any fields (user data, ECC, headers, etc.), the CD spins up and then I get an error flag set in the ATA status port. Calling SCSI Read Sense Information either gives be a 0x0 sense key and sense code, or a 0x5 sense key and 0x24 sense code. According to the docs, this should be an INVALID FIELD IN CDB error, but I'm still trying to figure out which field it is complaining about. Maybe someone can give me some suggestions...

I've tried requesting just the User Data field (which is all that CD-DA has, so any other fields should be ignored anyway), and I've tried reading a single track starting with LBA 0, and LBA (75*60*9) to try to skip ahead to 9 minutes into the CD. I've also tried using the MSF version to pull from 00:00:00 to 00:00:01, and various other start/end points, and the results always seem to be the same.

I've been trying to troubleshoot this for a few days now, and I think I'm getting pretty close, but I thought I'd see if anyone has actually gotten this to work. Right now, I'm testing with Virtualbox, using the Host D: drive with "Passthrough" enabled. I may try some other VMs if I can't get this working, but I have verified that WinXP is able to play digital audio using this same configuration. (Disabling "Passthrough" causes WinXP to fail reading the audio data, however...)

I'm trying to read 2352 bytes of data (although I've also tried 2048 bytes, and 2 bytes, with the same results), but the error flag gets set before I even start reading data, so I don't think reading bytes is the issue.

Thanks guys. I'm open to any ideas or suggestions you may have.

The source is up on http://ozone.codeplex.com/SourceControl ... dDrive.xml if you want to take a look. The code is all XML based, and is of my own design, so hopefully it is readable enough to understand. (It's essentially x86 byte codes, with an XML transform to make them readable...)

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Mon Jun 08, 2015 2:01 pm
by Octocontrabass
SpyderTL wrote:Calling SCSI Read Sense Information either gives be a 0x0 sense key and sense code, or a 0x5 sense key and 0x24 sense code.
That's not really a full set of sense data, but I kind of get the idea.
SpyderTL wrote:According to the docs, this should be an INVALID POC FIELD error,
You meant INVALID FIELD IN CDB, right? What docs are you using?
SpyderTL wrote:but I'm still trying to figure out why I'm getting that error. Maybe someone can give me some pointers...
Dump your CDB and post it here so we can see what you're asking the drive to do. You might even notice the problem before posting.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Mon Jun 08, 2015 2:28 pm
by SpyderTL
Octocontrabass wrote:You meant INVALID FIELD IN CDB, right? What docs are you using?
Yep, I was in the process of fixing that when your reply popped up.
Octocontrabass wrote:Dump your CDB and post it here so we can see what you're asking the drive to do. You might even notice the problem before posting.
In order, I'm sending the following 12 bytes to the ATAPI Packet command:

Code: Select all

0xBE  // SCSI Command READ CD  (OR 0xB9 READ CD MSF)
0x00  // Any Sector Type, Error Correction Disabled

0x00  // Starting Logical Block Address (23332, big endian, which matches the first LBA of the second track in the TOC, although I've tried others as well..  like zero)
0x00
0x5b
0x24

0x00  // Transfer Length (1 block, big endian)
0x00
0x01

0x10  // Main Channel Selection (User Data, although documentation says that anything other than 0x0 returns user data for CD-DA)
0x00  // Subchannel Selection (none)
0x00  // Control  (Reserved for ATAPI, according to documentation)
My understanding is that all fields are big endian, and I'm writing them out two bytes at a time.

I'm using the MMC-6 10t documentation from 11 December 2009 (mmc6r02g.pdf) from the 13th monkey web site. http://www.13thmonkey.org/documentation/SCSI/

In that document, I did see something about the block size being 2048 for ATAPI controllers, but I'm not sure if that applies to CD-DA data or not. In any case, I tried 2048 bytes, and I got the same results.

EDIT: After sending this command, the CD spins up for a second or two, then I get a 0x41 (Ready, Error) in the IDE status field. When I request the sense information, I get a sense key of 0x00, and a sense code (ASC) of 0x00, and ASCQ of 0x00. (Using the values above. I've gotten 0x05 and 0x24 0x00 and 0x05 0x21 0x00 using different values/different audio CDs)

I'll try using a different Audio CD and see if I get different results...

EDIT: Using B9, instead, and enabling error correction, and requesting 00:00:00 to 00:00:01, the drive spins up for about 5 seconds, and then I get an error with sense key/code/subcode 0x04/0x3E/0x02 (TIMEOUT ON LOGICAL UNIT). I feel like I'm close to getting this working, but just missing something obvious.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Mon Jun 08, 2015 8:06 pm
by SpyderTL
Okay, I've made a little more progress...

Using READ CD MSF (0xB9) in VMWare Player, I've successfully read what appears to be valid audio data from 01:01:01 and 01:01:02. However, requesting 00:00:00 and 00:00:01 both return IDE status 0x51, and sense key/code/subcode 0x05/0x24/0x00.

Using the same build, and the same Audio CD, VirtualBox is giving me an IDE status of 0x41 and sense values of 0x00/0x00/0x00 for 01:01:01.

Can anyone shed some light into what may be going on here?

Thx.

Edit: This turned out to be a problem with requesting user data before the first track on the CD. According to the TOC, the first track starts at 00:02:00.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu Jun 11, 2015 6:17 pm
by SpyderTL
A little more progress. On VMWare, I'm getting data back using READ CD MSF, but not consistantly getting data using READ CD.

On VirtualBox, I'm getting 0x41 on both commands.

However, on VMWare, I'm having a problem with figuring out where to stop reading data. If I make multiple READ CD MSF calls with the same parameters, I'm getting different results. I discovered that I'm actually getting leftover data from the previous command.

I added code to the end of the call to read words until the DRQ flag goes away, and it appears that the flag is never cleared, because the code never returns.

Still trying to figure out what is going on. Any help would be appreciated.

Thanks guys.

EDIT: Has anyone successfully read audio data over ATAPI? Does anyone know if there is code in Linux that I could look at? From what I've read, Linux just provides the ability to send raw commands to the CD-ROM, and the applications has to do all of the work, but I haven't verified this, myself.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Sat Jun 13, 2015 7:49 am
by SpyderTL
Okay, I've figured out that I'm getting back 0xFF from the IDE Status register a few times after the Packet command is sent, and again after the entire block of data has been read. This is causing a "false" error condition, because if I specifically check for 0xFF and ignore it, I end up reading all of the data correctly.

However, the status appears to flip back to 0xFF after all of the data has been read, and it stays that way forever. Has anyone seen this behavior before?

I guess I could just keep track of how much data is left, and when that number goes to zero, I can just stop checking the Status register altogether...

I was checking the Busy flag to decide whether I was done, but it's always set if I'm getting 0xFF back...

(This is all happening in VMWare, BTW)

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu Jun 25, 2015 2:52 am
by SpyderTL
Final update...

I'm getting audio data from the CD in VMWare, but given up, for now, on VirtualBox.

I was polling the DRQ flag after sending the packet data, which the wiki says is a no-no. After switching to waiting for the IRQ, things got a little better, although I was still getting strange 0xFF values back from the status register after reading all of the data.

So I decided just to ignore it, and move ahead anyway. But as soon as I modified the code to store the audio data in memory (I was originally just reading it into AX), everything started working, and the weird 0xFF status went away. So I'm not sure if it was a timing issue, or I just had a bug somewhere, but things are working now.

Now, I've just got to get the sound card working (Ensoniq AudioPCI 97, in VMWare), and I'll have an actual working CD player!!

Just out of curiosity, anyone else have an OS that can play audio CDs? :)

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu Jun 25, 2015 3:23 am
by embryo2
SpyderTL wrote:Now, I've just got to get the sound card working (Ensoniq AudioPCI 97, in VMWare), and I'll have an actual working CD player!!

Just out of curiosity, anyone else have an OS that can play audio CDs? :)
Nice to see that the work is exciting you :)

But about CDs. Aren't they obsolete now? Isn't it better just to create some library that works with raw sound data without any dependencies on the source of the data? Then, if you have HDD or USB storage, you need only a driver and some means that feed the sound data to the sound library. And CD as a data storage is too slow, it has problems with reading data after some time and, of course, it is much less convenient to manipulate than USB based solutions.

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu Jun 25, 2015 4:32 am
by Octocontrabass
embryo2 wrote:But about CDs. Aren't they obsolete now?
They have not been surpassed by any "better" formats, and they are still produced in great numbers. The technology is old, but not obsolete.
embryo2 wrote:Isn't it better just to create some library that works with raw sound data without any dependencies on the source of the data?
Yes, but you still need something that can provide the raw sound data.
embryo2 wrote:Then, if you have HDD or USB storage, you need only a driver and some means that feed the sound data to the sound library.
Reading from CD is also something that can be handled in a driver.
embryo2 wrote:And CD as a data storage is too slow, it has problems with reading data after some time and, of course, it is much less convenient to manipulate than USB based solutions.
CDs are fast enough for audio. (Common "52X" CD drives are capable of reading the disc 52 times the minimum speed required for audio playback.) CDs are generally very reliable if you treat them well. They are much more convenient than USB on a computer that does not have USB ports!

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Thu Jun 25, 2015 3:54 pm
by SpyderTL
The way this is implemented is very C#/Java like.

I have a class that can read raw audio data from an IDE CD Drive, that essentially implements an interface that can return one sample at a time (as a byte, a float, a short, an integer, a string, or it can simply fiill an object that is passed in.)

Then I can pass that object to another object that simply reads data from the first object in whatever format (from the list above) it wants, and sends the data to the sound card. (For now, I only have Soundblaster working, but I've just started on the Ensoniq AudioPCI.)

I also have a class that can read raw data from a floppy drive, and one that can read raw data from an IDE Hard Drive. Then, I have a class that can read from any of these "reader" classes, and parse FAT tables, and return raw bites from individual files.

I can, technically, use any of these classes to feed audio data to the sound card, because they all support the same "reader" interface.

Pretty slick.

EDIT: I also have readers for raw CD-ROM data, and CDFS file data as well. I can also read raw data from a TCP/IP network connection, and use it as audio data, if I wanted. I even have readers that read system memory, and I/O ports, if I wanted to "play" my kernel, or my BIOS through the sound card. :)

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Fri Jun 26, 2015 6:31 am
by embryo2
Octocontrabass wrote:CDs are fast enough for audio.
Yes, reading some sequential stream of data is ok for CDs, but even reading a directory structure, for example, is a way too slow.

Of course, if you have some backlog of old CDs, then they somehow can be used, but with flash sticks of size 32GB and more I prefer to copy everything from old data-stores to the new media and to get the freedom of using the data everywhere (and much quicker).

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Fri Jun 26, 2015 6:36 am
by embryo2
SpyderTL wrote:I have a class that can read raw audio data from an IDE CD Drive, that essentially implements an interface that can return one sample at a time (as a byte, a float, a short, an integer, a string, or it can simply fiill an object that is passed in.)

Then I can pass that object to another object that simply reads data from the first object in whatever format (from the list above) it wants, and sends the data to the sound card. (For now, I only have Soundblaster working, but I've just started on the Ensoniq AudioPCI.)

I also have a class that can read raw data from a floppy drive, and one that can read raw data from an IDE Hard Drive. Then, I have a class that can read from any of these "reader" classes, and parse FAT tables, and return raw bites from individual files.

I can, technically, use any of these classes to feed audio data to the sound card, because they all support the same "reader" interface.
Well done :)

But it means you have a library that is able to work with audio in many forms, while the thread title only mentions audio CD which is a bit misleading. However, now I see the bigger picture :)

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Mon Jul 06, 2015 3:27 pm
by SpyderTL
I decided to play around a bit with VirtualBox and see if I could figure out why I couldn't get it to read audio data, when WinXP works just fine.

I figured out that I could, indeed, read audio data, but only after reading the TOC in a separate call. I'm not sure if this is supposed to work this way, but after reading the TOC, all of my other calls to READ CD and READ CD MSF both work properly!

Long story short, I can now play audio directly from a CD!!! At least for a few seconds, then it locks up... But still... hearing audio from a CD for the first time on my own OS, created using my own "language", it completely blows my mind! Especially considering that I haven't made any changes to the code in several weeks. I just had to "trick" it into working by reading the TOC first.

Holy Crap! I'm heading over to the AWWW YEAHHH thread...

Can't stop smiling!! :D

Re: Reading raw PCM data from Audio CD (CD-DA)

Posted: Tue Jul 07, 2015 12:35 pm
by embryo2
SpyderTL wrote:Long story short, I can now play audio directly from a CD!!!
...
Holy Crap! I'm heading over to the AWWW YEAHHH thread...

Can't stop smiling!! :D
Congratulations! Very nice feeling! And it is shown in a manner that is very inspiring :)