OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [Documentation/] [cdrom/] [sbpcd] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1625 jcastillo
This README belongs to release 4.2 or newer of the SoundBlaster Pro
2
(Matsushita, Kotobuki, Panasonic, CreativeLabs, Longshine and Teac)
3
CD-ROM driver for Linux.
4
 
5
sbpcd really, really is NOT for ANY IDE/ATAPI drive!
6
Not even if you have an "original" SoundBlaster card with an IDE interface!
7
So, you better have a look into README.ide if your port address is 0x1F0,
8
0x170, 0x1E8, 0x168 or similar.
9
I get tons of mails from IDE/ATAPI drive users - I really can't continue
10
any more to answer them all. So, if your drive/interface information sheets
11
mention "IDE" (primary, secondary, tertiary, quaternary) and the DOS driver
12
invoking line within your CONFIG.SYS is using an address below 0x230:
13
DON'T ROB MY LAST NERVE - jumper your interface to address 0x170 and IRQ 15
14
(that is the "secondary IDE" configuration), set your drive to "master" and
15
use ide-cd as your driver. If you do not have a second IDE hard disk, use the
16
LILO commands
17
   hdb=noprobe hdc=cdrom
18
and get lucky.
19
To make it fully clear to you: if you mail me about IDE/ATAPI drive problems,
20
my answer is above, and I simply will discard your mail, hoping to stop the
21
flood and to find time to lead my 12-years old son towards happy computing.
22
 
23
The driver is able to drive the whole family of "traditional" AT-style (that
24
is NOT the new "Enhanced IDE" or "ATAPI" drive standard) Matsushita,
25
Kotobuki, Panasonic drives, sometimes labelled as "CreativeLabs". The
26
well-known drives are CR-521, CR-522, CR-523, CR-562, CR-563.
27
CR-574 is an IDE/ATAPI drive.
28
 
29
The Longshine LCS-7260 is a double-speed drive which uses the "old"
30
Matsushita command set. It is supported - with help by Serge Robyns.
31
Vertos ("Elitegroup Computer Systems", ECS) has a similar drive - support
32
has started; come in contact if you have such a "Vertos 100" or "ECS-AT"
33
drive.
34
 
35
There exists an "IBM External ISA CD-ROM Drive" which in fact is a CR-563
36
with a special controller board. This drive is supported (the interface is
37
of the "LaserMate" type), and it is possibly the best buy today (cheaper than
38
an internal drive, and you can use it as an internal, too - f.e. plug it into
39
a soundcard).
40
 
41
CreativeLabs has a new drive "CD200" and a similar drive "CD200F". The latter
42
is made by Funai and sometimes named "E2550UA", newer models may be named
43
"MK4015". The CD200F drives should fully work.
44
CD200 drives without "F" are still giving problems: drive detection and
45
playing audio should work, data access will result in errors. I need qualified
46
feedback about the bugs within the data functions or a drive (I never saw a
47
CD200).
48
 
49
The quad-speed Teac CD-55A drive is supported, but still does not reach "full
50
speed". The data rate already reaches 500 kB/sec if you set SBP_BUFFER_FRAMES
51
to 64 (it is not recommended to do that for normal "file access" usage, but it
52
can speed up things a lot if you use something like "dd" to read from the
53
drive; I use it for verifying self-written CDs this way).
54
The drive itself is able to deliver 600 kB/sec, so this has to get a point of
55
work; with the normal setup, the performance currently is not even as good as
56
double-speed.
57
 
58
This driver is NOT for Mitsumi or Sony or Aztech or Philips or XXX drives,
59
and again: this driver is in no way usable for any IDE/ATAPI drive. If you
60
think your drive should work and it doesn't: send me the DOS driver for your
61
beast (gzipped + uuencoded) and your CONFIG.SYS if you want to ask me for help,
62
and include an original log message excerpt, and try to give all information
63
a complete idiot needs to understand your hassle already with your first
64
mail. And if you want to say "as I have mailed you before", be sure that I
65
don't remember your "case" by such remarks; at the moment, I have some
66
hundreds open correspondences about Linux CDROM questions (hope to reduce if
67
the IDE/ATAPI user questions disappear).
68
 
69
 
70
This driver will work with the soundcard interfaces (SB Pro, SB 16, Galaxy,
71
SoundFX, Mozart, MAD16 ...) and with the "no-sound" cards (Panasonic CI-101P,
72
LaserMate, WDH-7001C, Longshine LCS-6853, Teac ...).
73
 
74
It works with the "configurable" interface "Sequoia S-1000", too, which is
75
used on the Spea Media FX and Ensonic Soundscape sound cards. You have to
76
specify the type "SBPRO 2" and the true CDROM port address with it, not the
77
"configuration port" address.
78
 
79
If you have a sound card which needs a "configuration driver" instead of
80
jumpers for interface types and addresses (like Mozart cards) - those
81
drivers get invoked before the DOS CDROM driver in your CONFIG.SYS, typical
82
names are "cdsetup.sys" and "mztinit.sys" -, let the sound driver do the
83
CDROM port configuration (the leading comments in linux/drivers/sound/mad16.c
84
are just for you!). Hannu Savolainen's mad16.c code is able to set up my
85
Mozart card - I simply had to add
86
   #define MAD16_CONF 0x06
87
   #define MAD16_CDSEL 0x03
88
to configure the CDROM interface for type "Panasonic" (LaserMate) and address
89
0x340.
90
 
91
The interface type has to get configured in /usr/include/linux/sbpcd.h,
92
because the register layout is different between the "SoundBlaster" and the
93
"LaserMate" type.
94
 
95
I got a report that the Teac interface card "I/F E117098" is of type
96
"SoundBlaster" (i.e. you have to set SBPRO to 1) even with the addresses
97
0x300 and above. This is unusual, and it can't get covered by the auto
98
probing scheme.
99
The Teac 16-bit interface cards (like P/N E950228-00A, default address 0x2C0)
100
need the SBPRO 3 setup.
101
 
102
If auto-probing found the drive, the address is correct. The reported type
103
may be wrong. A "mount" will give success only if the interface type is set
104
right. Playing audio should work with a wrong set interface type, too.
105
 
106
With some Teac and some CD200 drives I have seen interface cards which seem
107
to lack the "drive select" lines; always drive 0 gets addressed. To avoid
108
"mirror drives" (four drives detected where you only have one) with such
109
interface cards, set MAX_DRIVES to 1 and jumper your drive to ID 0 (if
110
possible).
111
 
112
 
113
Up to 4 drives per interface card, and up to 4 interface cards are supported.
114
All supported drive families can be mixed, but the CR-521 drives are
115
hard-wired to drive ID 0. The drives have to use different drive IDs, and each
116
drive has to get a unique minor number (0...3), corresponding indirectly to
117
its drive ID.
118
The drive IDs may be selected freely from 0 to 3 - they do not have to be in
119
consecutive order.
120
 
121
As Don Carroll, don@ds9.us.dell.com or FIDO 1:382/14, told me, it is possible
122
to change old drives to any ID, too. He writes in this sense:
123
   "In order to be able to use more than one single speed drive
124
   (they do not have the ID jumpers) you must add a DIP switch
125
   and two resistors. The pads are already on the board next to
126
   the power connector. You will see the silkscreen for the
127
   switch if you remove the top cover.
128
                    1 2 3 4
129
             ID 0 = x F F x             O = "on"
130
             ID 1 = x O F x             F = "off"
131
             ID 2 = x F O x             x = "don't care"
132
             ID 3 = x O O x
133
   Next to the switch are the positions for R76 (7k) and R78
134
   (12k). I had to play around with the resistor values - ID 3
135
   did not work with other values. If the values are not good,
136
   ID 3 behaves like ID 0."
137
 
138
To use more than 4 drives, you simply need a second controller card at a
139
different address and a second cable.
140
 
141
The driver supports reading of data from the CD and playing of audio tracks.
142
The audio part should run with WorkMan, xcdplayer, with the "non-X11" products
143
CDplayer and WorkBone - tell me if it is not compatible with other software.
144
The only accepted measure for correctness with the audio functions is the
145
"cdtester" utility (appended) - most audio player programmers seem to be
146
better musicians than programmers. ;-)
147
 
148
With the CR-56x and the CD200 drives, the reading of audio frames is possible.
149
This is implemented by an IOCTL function which reads READ_AUDIO frames of
150
2352 bytes at once (configurable with the "READ_AUDIO" define, default is 0).
151
Reading the same frame a second time gives different data; the frame data
152
start at a different position, but all read bytes are valid, and we always
153
read 98 consecutive chunks (of 24 Bytes) as a frame. Reading more than 1 frame
154
at once possibly misses some chunks at each frame boundary. This lack has to
155
get corrected by external, "higher level" software which reads the same frame
156
again and tries to find and eliminate overlapping chunks (24-byte-pieces).
157
 
158
The transfer rate with reading audio (1-frame-pieces) currently is very slow.
159
This can be better reading bigger chunks, but the "missing" chunks possibly
160
occur at the beginning of each single frame.
161
The software interface possibly may change a bit the day the SCSI driver
162
supports it too.
163
 
164
With all but the CR-52x drives, MultiSession is supported.
165
Photo CDs work (the "old" drives like CR-521 can access only the first
166
session of a photoCD).
167
At ftp.gwdg.de:/pub/linux/hpcdtoppm/ you will find Hadmut Danisch's package to
168
convert photo CD image files and Gerd Knorr's viewing utility.
169
 
170
The transfer rate will reach 150 kB/sec with CR-52x drives, 300 kB/sec with
171
CR-56x drives, and currently not more than 500 kB/sec (usually less than
172
250 kB/sec) with the Teac quad speed drives.
173
XA (PhotoCD) disks with "old" drives give only 50 kB/sec.
174
 
175
This release consists of
176
- this README file
177
- the driver file linux/drivers/cdrom/sbpcd.c
178
- the stub files linux/drivers/cdrom/sbpcd[234].c
179
- the header file linux/include/linux/sbpcd.h.
180
 
181
 
182
To install:
183
-----------
184
 
185
1. Setup your hardware parameters. Though the driver does "auto-probing" at a
186
   lot of (not all possible!) addresses, this step is recommended for
187
   every-day use. You should let sbpcd auto-probe once and use the reported
188
   address if a drive got found. The reported type may be incorrect; it is
189
   correct if you can mount a data CD. There is no choice for you with the
190
   type; only one is the right, the others are deadly wrong.
191
 
192
   a. Go into /usr/src/linux/include/linux/sbpcd.h and configure it for your
193
      hardware (near the beginning):
194
      a1. Set it up for the appropriate type of interface board.
195
          "Original" CreativeLabs sound cards need "SBPRO 1".
196
          Most "compatible" sound cards (almost all "non-CreativeLabs" cards)
197
          need "SBPRO 0".
198
          The "no-sound" board from OmniCd needs the "SBPRO 1" setup.
199
          The Teac 8-bit "no-sound" boards need the "SBPRO 1" setup.
200
          The Teac 16-bit "no-sound" boards need the "SBPRO 3" setup.
201
          All other "no-sound" boards need the "SBPRO 0" setup.
202
          The Spea Media FX and Ensoniq SoundScape cards need "SBPRO 2".
203
          sbpcd.c holds some examples in its auto-probe list.
204
          If you configure "SBPRO" wrong, the playing of audio CDs will work,
205
          but you will not be able to mount a data CD.
206
      a2. Tell the address of your CDROM_PORT (not of the sound port).
207
      a3. If 4 drives get found, but you have only one, set MAX_DRIVES to 1.
208
      a4. Set DISTRIBUTION to 0.
209
   b. Additionally for 2.a1 and 2.a2, the setup may be done during
210
      boot time (via the "kernel command line" or "LILO option"):
211
          sbpcd=0x320,LaserMate
212
      or
213
          sbpcd=0x230,SoundBlaster
214
      or
215
          sbpcd=0x338,SoundScape
216
      or
217
          sbpcd=0x2C0,Teac16bit
218
      This is especially useful if you install a fresh distribution.
219
      If the second parameter is a number, it gets taken as the type
220
      setting; 0 is "LaserMate", 1 is "SoundBlaster", 2 is "SoundScape",
221
      3 is "Teac16bit".
222
      So, for example
223
          sbpcd=0x230,1
224
      is equivalent to
225
          sbpcd=0x230,SoundBlaster
226
 
227
2. "cd /usr/src/linux" and do a "make config" and select "y" for Matsushita
228
   CD-ROM support and for ISO9660 FileSystem support. If you do not have a
229
   second, third, or fourth controller installed, do not say "y" to the
230
   secondary Matsushita CD-ROM questions.
231
 
232
3. Then do a "make dep", then make the kernel image ("make zlilo" or else).
233
 
234
4. Make the device file(s). This step usually already has been done by the
235
   MAKEDEV script.
236
   The driver uses MAJOR 25, so, if necessary, do
237
        mknod /dev/sbpcd  b 25 0       (if you have only one drive)
238
   and/or
239
        mknod /dev/sbpcd0 b 25 0
240
        mknod /dev/sbpcd1 b 25 1
241
        mknod /dev/sbpcd2 b 25 2
242
        mknod /dev/sbpcd3 b 25 3
243
   to make the node(s).
244
 
245
   The "first found" drive gets MINOR 0 (regardless to its jumpered ID), the
246
   "next found" (at the same cable) gets MINOR 1, ...
247
 
248
   For a second interface board, you have to make nodes like
249
        mknod /dev/sbpcd4 b 26 0
250
        mknod /dev/sbpcd5 b 26 1
251
   and so on. Use the MAJORs 26, 27, 28.
252
 
253
   If you further make a link like
254
        ln -s sbpcd /dev/cdrom
255
   you can use the name /dev/cdrom, too.
256
 
257
5. Reboot with the new kernel.
258
 
259
You should now be able to do
260
              mkdir /CD
261
and
262
              mount -rt iso9660 /dev/sbpcd /CD
263
or
264
              mount -rt iso9660 -o block=2048 /dev/sbpcd /CD
265
and see the contents of your CD in the /CD directory.
266
To use audio CDs, a mounting is not recommended (and it would fail if the
267
first track is not a data track).
268
 
269
 
270
Using sbpcd as a "loadable module":
271
-----------------------------------
272
 
273
If you do NOT select "Matsushita/Panasonic CDROM driver support" during the
274
"make config" of your kernel, you can build the "loadable module" sbpcd.o.
275
Read /usr/src/linux/Documentation/modules.txt on this.
276
 
277
If sbpcd gets used as a module, the support of more than one interface
278
card (i.e. drives 4...15) is disabled.
279
 
280
You can specify interface address and type with the "insmod" command like:
281
 # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x340,0
282
or
283
 # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x230,1
284
or
285
 # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x338,2
286
where the last number represents the SBPRO setting (no strings allowed here).
287
 
288
 
289
Things of interest:
290
-------------------
291
 
292
The driver is configured to try the LaserMate type of interface at I/O port
293
0x0340 first. If this is not appropriate, sbpcd.h should get changed
294
(you will find the right place - just at the beginning).
295
 
296
No DMA and no IRQ is used.
297
 
298
To reduce or increase the amount of kernel messages, edit sbpcd.c and play
299
with the "DBG_xxx" switches (initialization of the variable "sbpcd_debug").
300
Don't forget to reflect what you do; enabling all DBG_xxx switches at once
301
may crash your system, and each message line is accompanied by a delay.
302
 
303
The driver uses the "variable BLOCK_SIZE" feature. To use it, you have to
304
specify "block=2048" as a mount option. Doing this will disable the direct
305
execution of a binary from the CD; you have to copy it to a device with the
306
standard BLOCK_SIZE (1024) before. So, do not use this if your system is
307
directly "running from the CDROM" (like some of YGGDRASIL's installation
308
variants). There are CDs on the market (like the german "unifix" Linux
309
distribution) which MUST get handled with a block_size of 1024. Generally,
310
one can say all the CDs which hold files of the name YMTRANS.TBL are defective;
311
do not use block=2048 with those.
312
 
313
Within sbpcd.h, you will find some "#define"s (f.e. EJECT and JUKEBOX). With
314
that, you can configure the driver for some special things.
315
You can use the appended program "cdtester" to set the auto-eject feature
316
during runtime. Jeff Tranter's "eject" utility can do this, too (and more)
317
for you.
318
 
319
There is an ioctl CDROMMULTISESSION to obtain with a user program if
320
the CD is an XA disk and - if it is - where the last session starts. The
321
"cdtester" program illustrates how to call it.
322
 
323
 
324
Auto-probing at boot time:
325
--------------------------
326
 
327
The driver does auto-probing at many well-known interface card addresses,
328
but not all:
329
Some probings can cause a hang if an NE2000 ethernet card gets touched, because
330
SBPCD's auto-probing happens before the initialization of the net drivers.
331
Those "hazardous" addresses are excluded from auto-probing; the "kernel
332
command line" feature has to be used during installation if you have your
333
drive at those addresses. The "module" version is allowed to probe at those
334
addresses, too.
335
 
336
The auto-probing looks first at the configured address resp. the address
337
submitted by the kernel command line. With this, it is possible to use this
338
driver within installation boot floppies, and for any non-standard address,
339
too.
340
 
341
Auto-probing will make an assumption about the interface type ("SBPRO" or not),
342
based upon the address. That assumption may be wrong (initialization will be
343
o.k., but you will get I/O errors during mount). In that case, use the "kernel
344
command line" feature and specify address & type at boot time to find out the
345
right setup.
346
 
347
For every-day use, address and type should get configured within sbpcd.h. That
348
will stop the auto-probing due to success with the first try.
349
 
350
The kernel command "sbpcd=0" suppresses each auto-probing and causes
351
the driver not to find any drive; it is meant for people who love sbpcd
352
so much that they do not want to miss it, even if they miss the drives. ;-)
353
 
354
If you configure "#define CDROM_PORT 0" in sbpcd.h, the auto-probing is
355
initially disabled and needs an explicit kernel command to get activated.
356
Once activated, it does not stop before success or end-of-list. This may be
357
useful within "universal" CDROM installation boot floppies (but using the
358
loadable module would be better because it allows an "extended" auto-probing
359
without fearing NE2000 cards).
360
 
361
To shorten the auto-probing list to a single entry, set DISTRIBUTION 0 within
362
sbpcd.h.
363
 
364
 
365
Setting up address and interface type:
366
--------------------------------------
367
 
368
If your I/O port address is not 0x340, you have to look for the #defines near
369
the beginning of sbpcd.h and configure them: set SBPRO to 0 or 1 or 2, and
370
change CDROM_PORT to the address of your CDROM I/O port.
371
 
372
Almost all of the "SoundBlaster compatible" cards behave like the no-sound
373
interfaces, i.e. need SBPRO 0!
374
 
375
With "original" SB Pro cards, an initial setting of CD_volume through the
376
sound cards MIXER register gets done.
377
If you are using a "compatible" sound card of types "LaserMate" or "SPEA",
378
you can set SOUND_BASE (in sbpcd.h) to get it done with your card, too...
379
 
380
 
381
Using audio CDs:
382
----------------
383
 
384
Workman, WorkBone, xcdplayer, cdplayer and the nice little tool "cdplay" (see
385
README.aztcd from the Aztech driver package) should work.
386
 
387
The program CDplayer likes to talk to "/dev/mcd" only, xcdplayer wants
388
"/dev/rsr0", workman loves "/dev/sr0" or "/dev/cdrom" - so, do the appropriate
389
links for using them without the need of supplying parameters.
390
 
391
 
392
Copying audio tracks:
393
---------------------
394
 
395
The following program will copy track 1 (or a piece of it) from an audio CD
396
into the file "track01":
397
 
398
/*=================== begin program ========================================*/
399
/*
400
 * read an audio track from a CD
401
 *
402
 * (c) 1994 Eberhard Moenkeberg 
403
 *          may be used & enhanced freely
404
 *
405
 * Due to non-existent sync bytes at the beginning of each audio frame (or due
406
 * to a firmware bug within all known drives?), it is currently a kind of
407
 * fortune if two consecutive frames fit together.
408
 * Usually, they overlap, or a little piece is missing. This happens in units
409
 * of 24-byte chunks. It has to get fixed by higher-level software (reading
410
 * until an overlap occurs, and then eliminate the overlapping chunks).
411
 * ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz holds an example of
412
 * such an algorithm.
413
 * This example program further is missing to obtain the SubChannel data
414
 * which belong to each frame.
415
 *
416
 * This is only an example of the low-level access routine. The read data are
417
 * pure 16-bit CDDA values; they have to get converted to make sound out of
418
 * them.
419
 * It is no fun to listen to it without prior overlap/underlap correction!
420
 */
421
#include 
422
#include 
423
#include 
424
 
425
static struct cdrom_tochdr hdr;
426
static struct cdrom_tocentry entry[101];
427
static struct cdrom_read_audio arg;
428
static u_char buffer[CD_FRAMESIZE_RAW];
429
static int datafile, drive;
430
static int i, j, limit, track, err;
431
static char filename[32];
432
 
433
main(int argc, char *argv[])
434
{
435
/*
436
 * open /dev/cdrom
437
 */
438
  drive=open("/dev/cdrom", 0);
439
  if (drive<0)
440
    {
441
      fprintf(stderr, "can't open drive.\n");
442
      exit (-1);
443
    }
444
/*
445
 * get TocHeader
446
 */
447
  fprintf(stdout, "getting TocHeader...\n");
448
  err=ioctl(drive, CDROMREADTOCHDR, &hdr);
449
  if (err!=0)
450
    {
451
      fprintf(stderr, "can't get TocHeader (error %d).\n", err);
452
      exit (-1);
453
    }
454
  else
455
    fprintf(stdout, "TocHeader: %d %d\n", hdr.cdth_trk0, hdr.cdth_trk1);
456
/*
457
 * get and display all TocEntries
458
 */
459
  fprintf(stdout, "getting TocEntries...\n");
460
  for (i=1;i<=hdr.cdth_trk1+1;i++)
461
    {
462
      if (i!=hdr.cdth_trk1+1) entry[i].cdte_track = i;
463
      else entry[i].cdte_track = CDROM_LEADOUT;
464
      entry[i].cdte_format = CDROM_LBA;
465
      err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]);
466
      if (err!=0)
467
        {
468
          fprintf(stderr, "can't get TocEntry #%d (error %d).\n", i, err);
469
          exit (-1);
470
        }
471
      else
472
        {
473
          fprintf(stdout, "TocEntry #%d: %1X %1X %06X %02X\n",
474
                 entry[i].cdte_track,
475
                 entry[i].cdte_adr,
476
                 entry[i].cdte_ctrl,
477
                 entry[i].cdte_addr.lba,
478
                 entry[i].cdte_datamode);
479
        }
480
    }
481
  fprintf(stdout, "got all TocEntries.\n");
482
/*
483
 * ask for track number (not implemented here)
484
 */
485
track=1;
486
#if 0 /* just read a little piece (4 seconds) */
487
entry[track+1].cdte_addr.lba=entry[track].cdte_addr.lba+300;
488
#endif
489
/*
490
 * read track into file
491
 */
492
  sprintf(filename, "track%02d\0", track);
493
  datafile=creat(filename, 0755);
494
  if (datafile<0)
495
    {
496
      fprintf(stderr, "can't open datafile %s.\n", filename);
497
      exit (-1);
498
    }
499
  arg.addr.lba=entry[track].cdte_addr.lba;
500
  arg.addr_format=CDROM_LBA; /* CDROM_MSF would be possible here, too. */
501
  arg.nframes=1;
502
  arg.buf=&buffer[0];
503
  limit=entry[track+1].cdte_addr.lba;
504
  for (;arg.addr.lba
505
    {
506
      err=ioctl(drive, CDROMREADAUDIO, &arg);
507
      if (err!=0)
508
        {
509
          fprintf(stderr, "can't read abs. frame #%d (error %d).\n",
510
                 arg.addr.lba, err);
511
        }
512
      j=write(datafile, &buffer[0], CD_FRAMESIZE_RAW);
513
      if (j!=CD_FRAMESIZE_RAW)
514
        {
515
          fprintf(stderr,"I/O error (datafile) at rel. frame %d\n",
516
                         arg.addr.lba-entry[track].cdte_addr.lba);
517
        }
518
      arg.addr.lba++;
519
    }
520
}
521
/*===================== end program ========================================*/
522
 
523
At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz is an adapted version of
524
Heiko Eissfeldt's digital-audio to .WAV converter (the original is there, too).
525
This is preliminary, as Heiko himself will care about it.
526
 
527
 
528
Known problems:
529
---------------
530
 
531
Currently, the detection of disk change or removal is actively disabled.
532
 
533
Most attempts to read the UPC/EAN code result in a stream of zeroes. All my
534
drives are mostly telling there is no UPC/EAN code on disk or there is, but it
535
is an all-zero number. I guess now almost no CD holds such a number.
536
 
537
Bug reports, comments, wishes, donations (technical information is a donation,
538
too :-) etc. to emoenke@gwdg.de.
539
 
540
SnailMail address, preferable for CD editors if they want to submit a free
541
"cooperation" copy:
542
                         Eberhard Moenkeberg
543
                         Reinholdstr. 14
544
                         D-37083 Goettingen
545
                         Germany
546
---
547
 
548
 
549
Appendix -- the "cdtester" utility:
550
 
551
/*
552
 * cdtester.c -- test the audio functions of a CD driver
553
 *
554
 * (c) 1995 Eberhard Moenkeberg 
555
 *          published under the GPL
556
 *
557
 *          made under heavy use of the "Tiny Audio CD Player"
558
 *          from Werner Zimmermann 
559
 *          (see linux/drivers/block/README.aztcd)
560
 */
561
#undef AZT_PRIVATE_IOCTLS /* not supported by every CDROM driver */
562
#define SBP_PRIVATE_IOCTLS /* not supported by every CDROM driver */
563
 
564
#include 
565
#include 
566
#include 
567
#include 
568
#include 
569
 
570
#ifdef AZT_PRIVATE_IOCTLS
571
#include 
572
#endif AZT_PRIVATE_IOCTLS
573
#ifdef SBP_PRIVATE_IOCTLS
574
#include 
575
#include 
576
#endif SBP_PRIVATE_IOCTLS
577
 
578
struct cdrom_tochdr hdr;
579
struct cdrom_tochdr tocHdr;
580
struct cdrom_tocentry TocEntry[101];
581
struct cdrom_tocentry entry;
582
struct cdrom_multisession ms_info;
583
struct cdrom_read_audio read_audio;
584
struct cdrom_ti ti;
585
struct cdrom_subchnl subchnl;
586
struct cdrom_msf msf;
587
struct cdrom_volctrl volctrl;
588
#ifdef AZT_PRIVATE_IOCTLS
589
union
590
{
591
        struct cdrom_msf msf;
592
        unsigned char buf[CD_FRAMESIZE_RAW];
593
} azt;
594
#endif AZT_PRIVATE_IOCTLS
595
int i, i1, i2, i3, j, k;
596
unsigned char sequence=0;
597
unsigned char command[80];
598
unsigned char first=1, last=1;
599
char *default_device="/dev/cdrom";
600
char dev[20];
601
char filename[20];
602
int drive;
603
int datafile;
604
int rc;
605
 
606
void help(void)
607
{
608
        printf("Available Commands:\n");
609
        printf("STOP          s      EJECT        e       QUIT         q\n");
610
        printf("PLAY TRACK    t      PAUSE        p       RESUME       r\n");
611
        printf("NEXT TRACK    n      REPEAT LAST  l       HELP         h\n");
612
        printf("SUBCHANNEL_Q  c      TRACK INFO   i       PLAY AT      a\n");
613
        printf("READ          d      READ RAW     w       READ AUDIO   A\n");
614
        printf("MS-INFO       M      TOC          T       START        S\n");
615
        printf("SET EJECTSW   X      DEVICE       D       DEBUG        Y\n");
616
        printf("AUDIO_BUFSIZ  Z      RESET        R       BLKRASET     B\n");
617
        printf("SET VOLUME    v      GET VOLUME   V\n");
618
}
619
 
620
/*
621
 *  convert MSF number (3 bytes only) to Logical_Block_Address
622
 */
623
int msf2lba(u_char *msf)
624
{
625
        int i;
626
 
627
        i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;
628
        if (i<0) return (0);
629
        return (i);
630
}
631
/*
632
 *  convert logical_block_address to m-s-f_number (3 bytes only)
633
 */
634
void lba2msf(int lba, unsigned char *msf)
635
{
636
        lba += CD_BLOCK_OFFSET;
637
        msf[0] = lba / (CD_SECS*CD_FRAMES);
638
        lba %= CD_SECS*CD_FRAMES;
639
        msf[1] = lba / CD_FRAMES;
640
        msf[2] = lba % CD_FRAMES;
641
}
642
 
643
int init_drive(char *dev)
644
{
645
        unsigned char msf_ent[3];
646
 
647
        /*
648
         * open the device
649
         */
650
        drive=open(dev,0);
651
        if (drive<0) return (-1);
652
        /*
653
         * get TocHeader
654
         */
655
        printf("getting TocHeader...\n");
656
        rc=ioctl(drive,CDROMREADTOCHDR,&hdr);
657
        if (rc!=0)
658
        {
659
                printf("can't get TocHeader (error %d).\n",rc);
660
                return (-2);
661
        }
662
        else
663
                first=hdr.cdth_trk0;
664
                last=hdr.cdth_trk1;
665
                printf("TocHeader: %d %d\n",hdr.cdth_trk0,hdr.cdth_trk1);
666
        /*
667
         * get and display all TocEntries
668
         */
669
        printf("getting TocEntries...\n");
670
        for (i=1;i<=hdr.cdth_trk1+1;i++)
671
        {
672
                if (i!=hdr.cdth_trk1+1) TocEntry[i].cdte_track = i;
673
                else TocEntry[i].cdte_track = CDROM_LEADOUT;
674
                TocEntry[i].cdte_format = CDROM_LBA;
675
                rc=ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i]);
676
                if (rc!=0)
677
                {
678
                        printf("can't get TocEntry #%d (error %d).\n",i,rc);
679
                }
680
                else
681
                {
682
                        lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
683
                        if (TocEntry[i].cdte_track==CDROM_LEADOUT)
684
                        {
685
                                printf("TocEntry #%02X: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",
686
                                       TocEntry[i].cdte_track,
687
                                       TocEntry[i].cdte_adr,
688
                                       TocEntry[i].cdte_ctrl,
689
                                       msf_ent[0],
690
                                       msf_ent[1],
691
                                       msf_ent[2],
692
                                       TocEntry[i].cdte_addr.lba,
693
                                       TocEntry[i].cdte_datamode);
694
                        }
695
                        else
696
                        {
697
                                printf("TocEntry #%02d: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",
698
                                       TocEntry[i].cdte_track,
699
                                       TocEntry[i].cdte_adr,
700
                                       TocEntry[i].cdte_ctrl,
701
                                       msf_ent[0],
702
                                       msf_ent[1],
703
                                       msf_ent[2],
704
                                       TocEntry[i].cdte_addr.lba,
705
                                       TocEntry[i].cdte_datamode);
706
                        }
707
                }
708
        }
709
        return (hdr.cdth_trk1); /* number of tracks */
710
}
711
 
712
void display(int size,unsigned char *buffer)
713
{
714
        k=0;
715
        getchar();
716
        for (i=0;i<(size+1)/16;i++)
717
        {
718
                printf("%4d:",i*16);
719
                for (j=0;j<16;j++)
720
                {
721
                        printf(" %02X",buffer[i*16+j]);
722
                }
723
                printf("  ");
724
                for (j=0;j<16;j++)
725
                {
726
                        if (isalnum(buffer[i*16+j]))
727
                                printf("%c",buffer[i*16+j]);
728
                        else
729
                                printf(".");
730
                }
731
                printf("\n");
732
                k++;
733
                if (k>=20)
734
                {
735
                        printf("press ENTER to continue\n");
736
                        getchar();
737
                        k=0;
738
                }
739
        }
740
}
741
 
742
main(int argc, char *argv[])
743
{
744
        printf("\nTesting tool for a CDROM driver's audio functions V0.1\n");
745
        printf("(C) 1995 Eberhard Moenkeberg \n");
746
        printf("initializing...\n");
747
 
748
        rc=init_drive(default_device);
749
        if (rc<0) printf("could not open %s (rc=%d).\n",default_device,rc);
750
        help();
751
        while (1)
752
        {
753
                printf("Give a one-letter command (h = help): ");
754
                scanf("%s",command);
755
                command[1]=0;
756
                switch (command[0])
757
                {
758
                case 'D':
759
                        printf("device name (f.e. /dev/sbpcd3): ? ");
760
                        scanf("%s",&dev);
761
                        close(drive);
762
                        rc=init_drive(dev);
763
                        if (rc<0) printf("could not open %s (rc %d).\n",dev,rc);
764
                        break;
765
                case 'e':
766
                        rc=ioctl(drive,CDROMEJECT);
767
                        if (rc<0) printf("CDROMEJECT: rc=%d.\n",rc);
768
                        break;
769
                case 'p':
770
                        rc=ioctl(drive,CDROMPAUSE);
771
                        if (rc<0) printf("CDROMPAUSE: rc=%d.\n",rc);
772
                        break;
773
                case 'r':
774
                        rc=ioctl(drive,CDROMRESUME);
775
                        if (rc<0) printf("CDROMRESUME: rc=%d.\n",rc);
776
                        break;
777
                case 's':
778
                        rc=ioctl(drive,CDROMSTOP);
779
                        if (rc<0) printf("CDROMSTOP: rc=%d.\n",rc);
780
                        break;
781
                case 'S':
782
                        rc=ioctl(drive,CDROMSTART);
783
                        if (rc<0) printf("CDROMSTART: rc=%d.\n",rc);
784
                        break;
785
                case 't':
786
                        rc=ioctl(drive,CDROMREADTOCHDR,&tocHdr);
787
                        if (rc<0)
788
                        {
789
                                printf("CDROMREADTOCHDR: rc=%d.\n",rc);
790
                                break;
791
                        }
792
                        first=tocHdr.cdth_trk0;
793
                        last= tocHdr.cdth_trk1;
794
                        if ((first==0)||(first>last))
795
                        {
796
                                printf ("--got invalid TOC data.\n");
797
                        }
798
                        else
799
                        {
800
                                printf("--enter track number(first=%d, last=%d): ",first,last);
801
                                scanf("%d",&i1);
802
                                ti.cdti_trk0=i1;
803
                                if (ti.cdti_trk0
804
                                if (ti.cdti_trk0>last) ti.cdti_trk0=last;
805
                                ti.cdti_ind0=0;
806
                                ti.cdti_trk1=last;
807
                                ti.cdti_ind1=0;
808
                                rc=ioctl(drive,CDROMSTOP);
809
                                rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
810
                                if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
811
                        }
812
                        break;
813
                case 'n':
814
                        rc=ioctl(drive,CDROMSTOP);
815
                        if (++ti.cdti_trk0>last) ti.cdti_trk0=last;
816
                        ti.cdti_ind0=0;
817
                        ti.cdti_trk1=last;
818
                        ti.cdti_ind1=0;
819
                        rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
820
                        if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
821
                        break;
822
                case 'l':
823
                        rc=ioctl(drive,CDROMSTOP);
824
                        if (--ti.cdti_trk0
825
                        ti.cdti_ind0=0;
826
                        ti.cdti_trk1=last;
827
                        ti.cdti_ind1=0;
828
                        rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
829
                        if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
830
                        break;
831
                case 'c':
832
                        subchnl.cdsc_format=CDROM_MSF;
833
                        rc=ioctl(drive,CDROMSUBCHNL,&subchnl);
834
                        if (rc<0) printf("CDROMSUBCHNL: rc=%d.\n",rc);
835
                        else
836
                        {
837
                                printf("AudioStatus:%s  Track:%d  Mode:%d  MSF=%02d:%02d:%02d\n",
838
                                       subchnl.cdsc_audiostatus==CDROM_AUDIO_PLAY ? "PLAYING":"NOT PLAYING",
839
                                       subchnl.cdsc_trk,subchnl.cdsc_adr,
840
                                       subchnl.cdsc_absaddr.msf.minute,
841
                                       subchnl.cdsc_absaddr.msf.second,
842
                                       subchnl.cdsc_absaddr.msf.frame);
843
                        }
844
                        break;
845
                case 'i':
846
                        printf("Track No.: ");
847
                        scanf("%d",&i1);
848
                        entry.cdte_track=i1;
849
                        if (entry.cdte_track
850
                        if (entry.cdte_track>last)  entry.cdte_track=last;
851
                        entry.cdte_format=CDROM_MSF;
852
                        rc=ioctl(drive,CDROMREADTOCENTRY,&entry);
853
                        if (rc<0) printf("CDROMREADTOCENTRY: rc=%d.\n",rc);
854
                        else
855
                        {
856
                                printf("Mode %d Track, starts at %02d:%02d:%02d\n",
857
                                       entry.cdte_adr,
858
                                       entry.cdte_addr.msf.minute,
859
                                       entry.cdte_addr.msf.second,
860
                                       entry.cdte_addr.msf.frame);
861
                        }
862
                        break;
863
                case 'a':
864
                        printf("Address (min:sec:frm)  ");
865
                        scanf("%d:%d:%d",&i1,&i2,&i3);
866
                        msf.cdmsf_min0=i1;
867
                        msf.cdmsf_sec0=i2;
868
                        msf.cdmsf_frame0=i3;
869
                        if (msf.cdmsf_sec0>59) msf.cdmsf_sec0=59;
870
                        if (msf.cdmsf_frame0>74) msf.cdmsf_frame0=74;
871
                        lba2msf(TocEntry[last+1].cdte_addr.lba-1,&msf.cdmsf_min1);
872
                        rc=ioctl(drive,CDROMSTOP);
873
                        rc=ioctl(drive,CDROMPLAYMSF,&msf);
874
                        if (rc<0) printf("CDROMPLAYMSF: rc=%d.\n",rc);
875
                        break;
876
                case 'V':
877
                        rc=ioctl(drive,CDROMVOLREAD,&volctrl);
878
                        if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);
879
                        printf("Volume: channel 0 (left) %d, channel 1 (right) %d\n",volctrl.channel0,volctrl.channel1);
880
                        break;
881
                case 'R':
882
                        rc=ioctl(drive,CDROMRESET);
883
                        if (rc<0) printf("CDROMRESET: rc=%d.\n",rc);
884
                        break;
885
                case 'B': /* set the driver's (?) read ahead value */
886
                        printf("enter read-ahead size: ? ");
887
                        scanf("%d",&i);
888
                        rc=ioctl(drive,BLKRASET,i);
889
                        if (rc<0) printf("BLKRASET: rc=%d.\n",rc);
890
                        break;
891
#ifdef AZT_PRIVATE_IOCTLS /*not supported by every CDROM driver*/
892
                case 'd':
893
                        printf("Address (min:sec:frm)  ");
894
                        scanf("%d:%d:%d",&i1,&i2,&i3);
895
                        azt.msf.cdmsf_min0=i1;
896
                        azt.msf.cdmsf_sec0=i2;
897
                        azt.msf.cdmsf_frame0=i3;
898
                        if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;
899
                        if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;
900
                        rc=ioctl(drive,CDROMREADMODE1,&azt.msf);
901
                        if (rc<0) printf("CDROMREADMODE1: rc=%d.\n",rc);
902
                        else display(CD_FRAMESIZE,azt.buf);
903
                        break;
904
                case 'w':
905
                        printf("Address (min:sec:frame)  ");
906
                        scanf("%d:%d:%d",&i1,&i2,&i3);
907
                        azt.msf.cdmsf_min0=i1;
908
                        azt.msf.cdmsf_sec0=i2;
909
                        azt.msf.cdmsf_frame0=i3;
910
                        if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;
911
                        if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;
912
                        rc=ioctl(drive,CDROMREADMODE2,&azt.msf);
913
                        if (rc<0) printf("CDROMREADMODE2: rc=%d.\n",rc);
914
                        else display(CD_FRAMESIZE_RAW,azt.buf); /* currently only 2336 */
915
                        break;
916
#endif
917
                case 'v':
918
                        printf("--Channel 0 (Left)  (0-255): ");
919
                        scanf("%d",&i1);
920
                        volctrl.channel0=i1;
921
                        printf("--Channel 1 (Right) (0-255): ");
922
                        scanf("%d",&i1);
923
                        volctrl.channel1=i1;
924
                        volctrl.channel2=0;
925
                        volctrl.channel3=0;
926
                        rc=ioctl(drive,CDROMVOLCTRL,&volctrl);
927
                        if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);
928
                        break;
929
                case 'q':
930
                        close(drive);
931
                        exit(0);
932
                case 'h':
933
                        help();
934
                        break;
935
                case 'T': /* display TOC entry - without involving the driver */
936
                        scanf("%d",&i);
937
                        if ((ihdr.cdth_trk1))
938
                                printf("invalid track number.\n");
939
                        else
940
                                printf("TocEntry %02d: adr=%01X ctrl=%01X msf=%02d:%02d:%02d mode=%02X\n",
941
                                       TocEntry[i].cdte_track,
942
                                       TocEntry[i].cdte_adr,
943
                                       TocEntry[i].cdte_ctrl,
944
                                       TocEntry[i].cdte_addr.msf.minute,
945
                                       TocEntry[i].cdte_addr.msf.second,
946
                                       TocEntry[i].cdte_addr.msf.frame,
947
                                       TocEntry[i].cdte_datamode);
948
                        break;
949
                case 'A': /* read audio data into file */
950
                        printf("Address (min:sec:frm) ? ");
951
                        scanf("%d:%d:%d",&i1,&i2,&i3);
952
                        read_audio.addr.msf.minute=i1;
953
                        read_audio.addr.msf.second=i2;
954
                        read_audio.addr.msf.frame=i3;
955
                        read_audio.addr_format=CDROM_MSF;
956
                        printf("# of frames ? ");
957
                        scanf("%d",&i1);
958
                        read_audio.nframes=i1;
959
                        k=read_audio.nframes*CD_FRAMESIZE_RAW;
960
                        read_audio.buf=malloc(k);
961
                        if (read_audio.buf==NULL)
962
                        {
963
                                printf("can't malloc %d bytes.\n",k);
964
                                break;
965
                        }
966
                        sprintf(filename,"audio_%02d%02d%02d_%02d.%02d\0",
967
                                read_audio.addr.msf.minute,
968
                                read_audio.addr.msf.second,
969
                                read_audio.addr.msf.frame,
970
                                read_audio.nframes,
971
                                ++sequence);
972
                        datafile=creat(filename, 0755);
973
                        if (datafile<0)
974
                        {
975
                                printf("can't open datafile %s.\n",filename);
976
                                break;
977
                        }
978
                        rc=ioctl(drive,CDROMREADAUDIO,&read_audio);
979
                        if (rc!=0)
980
                        {
981
                                printf("CDROMREADAUDIO: rc=%d.\n",rc);
982
                        }
983
                        else
984
                        {
985
                                rc=write(datafile,&read_audio.buf,k);
986
                                if (rc!=k) printf("datafile I/O error (%d).\n",rc);
987
                        }
988
                        close(datafile);
989
                        break;
990
                case 'X': /* set EJECT_SW (0: disable, 1: enable auto-ejecting) */
991
                        scanf("%d",&i);
992
                        rc=ioctl(drive,CDROMEJECT_SW,i);
993
                        if (rc!=0)
994
                                printf("CDROMEJECT_SW: rc=%d.\n",rc);
995
                        else
996
                                printf("EJECT_SW set to %d\n",i);
997
                        break;
998
                case 'M': /* get the multisession redirection info */
999
                        ms_info.addr_format=CDROM_LBA;
1000
                        rc=ioctl(drive,CDROMMULTISESSION,&ms_info);
1001
                        if (rc!=0)
1002
                        {
1003
                                printf("CDROMMULTISESSION(lba): rc=%d.\n",rc);
1004
                        }
1005
                        else
1006
                        {
1007
                                if (ms_info.xa_flag) printf("MultiSession offset (lba): %d (0x%06X)\n",ms_info.addr.lba,ms_info.addr.lba);
1008
                                else
1009
                                {
1010
                                        printf("this CD is not an XA disk.\n");
1011
                                        break;
1012
                                }
1013
                        }
1014
                        ms_info.addr_format=CDROM_MSF;
1015
                        rc=ioctl(drive,CDROMMULTISESSION,&ms_info);
1016
                        if (rc!=0)
1017
                        {
1018
                                printf("CDROMMULTISESSION(msf): rc=%d.\n",rc);
1019
                        }
1020
                        else
1021
                        {
1022
                                if (ms_info.xa_flag)
1023
                                        printf("MultiSession offset (msf): %02d:%02d:%02d (0x%02X%02X%02X)\n",
1024
                                               ms_info.addr.msf.minute,
1025
                                               ms_info.addr.msf.second,
1026
                                               ms_info.addr.msf.frame,
1027
                                               ms_info.addr.msf.minute,
1028
                                               ms_info.addr.msf.second,
1029
                                               ms_info.addr.msf.frame);
1030
                                else printf("this CD is not an XA disk.\n");
1031
                        }
1032
                        break;
1033
#ifdef SBP_PRIVATE_IOCTLS
1034
                case 'Y': /* set the driver's message level */
1035
#if 0 /* not implemented yet */
1036
                        printf("enter switch name (f.e. DBG_CMD): ");
1037
                        scanf("%s",&dbg_switch);
1038
                        j=get_dbg_num(dbg_switch);
1039
#else
1040
                        printf("enter DDIOCSDBG switch number: ");
1041
                        scanf("%d",&j);
1042
#endif
1043
                        printf("enter 0 for \"off\", 1 for \"on\": ");
1044
                        scanf("%d",&i);
1045
                        if (i==0) j|=0x80;
1046
                        printf("calling \"ioctl(drive,DDIOCSDBG,%d)\"\n",j);
1047
                        rc=ioctl(drive,DDIOCSDBG,j);
1048
                        printf("DDIOCSDBG: rc=%d.\n",rc);
1049
                        break;
1050
                case 'Z': /* set the audio buffer size */
1051
                        printf("# frames wanted: ? ");
1052
                        scanf("%d",&j);
1053
                        rc=ioctl(drive,CDROMAUDIOBUFSIZ,j);
1054
                        printf("%d frames granted.\n",rc);
1055
                        break;
1056
#endif SBP_PRIVATE_IOCTLS
1057
                default:
1058
                        printf("unknown command: \"%s\".\n",command);
1059
                        break;
1060
                }
1061
        }
1062
}
1063
/*==========================================================================*/
1064
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.