From 7e0ca24f4995f6fa529ca8caf2c32d22cb81138b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Wed, 17 Sep 2003 22:14:40 +0000 Subject: [PATCH] Added source for 'play'; this is the straight source from ftp://planetmirror.com/raid/13/beos/samples/media_kit/obsolete/play.cpp It doesn't compile under R5 yet though. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4744 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/bin/play.cpp | 405 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 src/apps/bin/play.cpp diff --git a/src/apps/bin/play.cpp b/src/apps/bin/play.cpp new file mode 100644 index 0000000000..4c7593c619 --- /dev/null +++ b/src/apps/bin/play.cpp @@ -0,0 +1,405 @@ +/* ++++++++++ + play.cpp + Copyright (C) 1995 Be Incorporated. All Rights Reserved. ++++++ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* ---------- + play requested track +----- */ + +play(int id, scsi_play_track *track) +{ + track->start_index = 1; + track->end_track = 99; + track->end_index = 1; + if (!ioctl(id, SCSI_PLAY_TRACK, track)) + printf("Playing audio...\n"); + else + printf("Play audio failed\n"); +} + + +/* ---------- + show valid cd-rom id's +----- */ + +void try_dir(const char *directory, long *count, bool show) +{ + bool add; + const char *name; + int fd; + BPath path; + BDirectory dir; + BEntry entry; + scsiprobe_inquiry inquiry; + ide_ctrl_info ide_info; + + dir.SetTo(directory); + if (dir.InitCheck() == B_NO_ERROR) { + dir.Rewind(); + while (dir.GetNextEntry(&entry) >= 0) { + entry.GetPath(&path); + name = path.Path(); + if (entry.IsDirectory()) + try_dir(name, count, show); + else if (strstr(name, "/raw")) { + add = FALSE; + if (strstr(name, "/scsi")) { + if ((fd = open("/dev/scsiprobe", 0)) >= 0) { + inquiry.path = name[15] - '0'; + inquiry.id = name[16] - '0'; + inquiry.lun = name[17] - '0'; + inquiry.len = 36; + if (ioctl(fd, SCSIPROBE_INQUIRY, &inquiry) == B_NO_ERROR) + add = ((inquiry.data[0] & 0x1f) == 5); + close(fd); + } + } + else if (strstr(name, "/ide")) { + if ((fd = open("/dev/disk/ide/rescan", 0)) >= 0) { + if (ioctl(fd, IDE_GET_DEVICES_INFO, &ide_info) == B_NO_ERROR) { + if (name[14] == '0') { + if ((strstr(name, "master")) && + (ide_info.ide_0_master_type == B_CD)) + add = true; + else if ((strstr(name, "slave")) && + (ide_info.ide_0_slave_type == B_CD)) + add = true; + } + else { + if ((strstr(name, "master")) && + (ide_info.ide_1_master_type == B_CD)) + add = true; + else if ((strstr(name, "slave")) && + (ide_info.ide_1_slave_type == B_CD)) + add = true; + } + } + close(fd); + } + } + if (add) { + *count += 1; + if (show) + printf(" %s\n", name); + } + } + } + } +} + +/* ---------- + show valid cd-rom id's +----- */ + +int count_ids(bool show) +{ + long count = 0; + + try_dir("/dev/disk", &count, show); + return (count); +} + + +/* ---------- + main +----- */ + +int +main (int argc, char **argv) +{ + int id; + int i; + int length; + int start; + long command; + long req_track = 0; + long vol; + long index; + ulong frames; + short tmp; + uchar *buf; + scsi_toc toc; + scsi_play_track track; + scsi_volume volume; + scsi_position position; + scsi_read_cd read_cd; + scsi_scan scan; + FILE *f; + + length = count_ids(FALSE); + if (!length) { + printf("No CD-ROM drive present.\n"); + return 0; + } + errno = 0; + + if (argc > 2) + command = strtol (argv[2], 0, 0); + else + command = 0; + + if ((argc < 2) || (errno) || + (command < 0) || (command > 8)) { + printf("Usage: play device [command [param]]\n\n"); + printf(" Valid devices:\n"); + count_ids(TRUE); + printf("\n"); + printf(" Valid commands:\n"); + printf(" 0 [n] - play from track n [1]\n"); + printf(" 1 - pause\n"); + printf(" 2 - resume\n"); + printf(" 3 - stop\n"); + printf(" 4 - eject\n"); + printf(" 5 n - set volume to n (0 <= n <= 255)\n"); + printf(" 6 - current position\n"); + printf(" 7 n s - save track n to file s\n"); + printf(" 8 [c] - scan in direction c (f = forward, b = backward)\n\n"); + return 0; + } + + if ((id = open(argv[1], 0)) >= 0) { + switch (command) { + case 0: + if (!ioctl(id, SCSI_GET_TOC, &toc)) { + track.start_track = 0; + for (i = toc.toc_data[2]; i <= toc.toc_data[3]; i++) { + length = (toc.toc_data[(((i + 1) - toc.toc_data[2]) * 8) + 4 + 5] * 60) + + (toc.toc_data[(((i + 1) - toc.toc_data[2]) * 8) + 4 + 6]); + length -= ((toc.toc_data[((i - toc.toc_data[2]) * 8) + 4 + 5] * 60) + + (toc.toc_data[((i - toc.toc_data[2]) * 8) + 4 + 6])); + printf(" Track %.2d: %.2d:%.2d - ", i, length / 60, length % 60); + if (toc.toc_data[((i - toc.toc_data[2]) * 8) + 4 + 1] & 4) + printf("DATA\n"); + else { + printf("AUDIO\n"); + if (!track.start_track) + track.start_track = i; + } + } + if (track.start_track) { + if (argc > 3) { + req_track = strtol (argv[3], 0, 0); + if ((req_track < toc.toc_data[2]) || (req_track > toc.toc_data[3])) + printf("Requested track is out of range\n"); + else + if (toc.toc_data[((req_track - toc.toc_data[2]) * 8) + 4 + 1] & 4) + printf("Requested track is not an audio track\n"); + else { + track.start_track = req_track; + play(id, &track); + } + } + else + play(id, &track); + } + else + printf("No audio tracks on CD\n"); + } + else + printf("Could not read table of contents on CD\n"); + break; + + case 1: + printf("Pausing audio\n"); + ioctl(id, SCSI_PAUSE_AUDIO); + break; + + case 2: + printf("Resuming audio\n"); + ioctl(id, SCSI_RESUME_AUDIO); + break; + + case 3: + printf("Stopping audio\n"); + ioctl(id, SCSI_STOP_AUDIO); + break; + + case 4: + printf("Ejecting CD\n"); + ioctl(id, SCSI_EJECT); + break; + + case 5: + if (argc < 4) + printf("Specify the volume\n"); + else { + vol = strtol (argv[3], 0, 0); + if ((vol < 0) || (vol > 255)) + printf("Volume is out of range (0 - 255)\n"); + else { + printf("Setting volume to %d\n", vol); + volume.port0_volume = vol; + volume.port1_volume = vol; + volume.flags = scsi_port0_volume | scsi_port1_volume; + ioctl(id, SCSI_SET_VOLUME, &volume); + } + } + break; + + case 6: + if (ioctl(id, SCSI_GET_POSITION, &position) == B_ERROR) + printf("Could not get current position\n"); + else { + switch(position.position[1]) { + case 0x00: + printf("Position not supported by device\n"); + break; + + case 0x11: + printf("Playing track %d (%.2d:%.2d:%.2d)\n", + position.position[6], + position.position[9], + position.position[10], + position.position[11]); + break; + + case 0x12: + printf("Paused at track %d (%.2d:%.2d:%.2d)\n", + position.position[6], + position.position[9], + position.position[10], + position.position[11]); + break; + + case 0x13: + printf("Play has been completed\n"); + break; + + case 0x14: + printf("Play stopped due to error\n"); + break; + + case 0x15: + printf("No status to return\n"); + break; + + default: + printf("Unexpected result: %.2x\n", + position.position[1]); + } + } + break; + + case 7: + if (argc < 4) { + printf("Specify the track to save\n"); + break; + } + + if (argc < 5) { + printf("Specify a file to save to\n"); + break; + } + + f = fopen(argv[4], "w"); + if (f == NULL) { + printf("Un-able to create %s\n", argv[4]); + break; + } + + req_track = strtol (argv[3], 0, 0); + if (!ioctl(id, SCSI_GET_TOC, &toc)) { + if (req_track > toc.toc_data[3]) { + printf("Track %d is out of range [%d-%d]\n", req_track, + toc.toc_data[2], toc.toc_data[3]); + break; + } + index = 0; + while (toc.toc_data[4 + (index * 8) + 2] != req_track) { + index++; + } + start = (toc.toc_data[4 + (index * 8) + 5] * 60 * 75) + + (toc.toc_data[4 + (index * 8) + 6] * 75) + + toc.toc_data[4 + (index * 8) + 7]; + index++; + length = ((toc.toc_data[4 + (index * 8) + 5] * 60 * 75) + + (toc.toc_data[4 + (index * 8) + 6] * 75) + + toc.toc_data[4 + (index * 8) + 7]) - start; + + frames = min_c(1 * 75, (int) length); + read_cd.buffer = (char *)malloc(frames * 2352); + + printf("Saving track %d to %s...\n", req_track, argv[4]); + while (length) { + index = start; + read_cd.start_m = index / (60 * 75); + index %= (60 * 75); + read_cd.start_s = index / 75; + index %= 75; + read_cd.start_f = index; + + index = min_c(frames, length); + read_cd.buffer_length = index * 2352; + length -= index; + start += index; + + read_cd.length_m = index / (60 * 75); + index %= (60 * 75); + read_cd.length_s = index / 75; + index %= 75; + read_cd.length_f = index; + + for (i = 0; i < 5; i++) + if (ioctl(id, SCSI_READ_CD, &read_cd) == B_NO_ERROR) + break; + if (i == 5) { + printf("Error reading CD-DA\n"); + break; + } + buf = (uchar *)read_cd.buffer; + for (i = 0; i < read_cd.buffer_length; i += 2) { + tmp = (short)((buf[1] << 8) | buf[0]); + *(short *)(&buf[0]) = tmp; + buf += 2; + } + fwrite(read_cd.buffer, read_cd.buffer_length, 1, f); + } + free(read_cd.buffer); + fclose(f); + } + else + printf("Failed to read table of contents\n"); + break; + + case 8: + if (argc == 4) { + if (!strcmp(argv[3], "f") || !strcmp(argv[3], "F")) + scan.direction = 1; + else if (!strcmp(argv[3], "b") || !strcmp(argv[3], "B")) + scan.direction = -1; + else { + printf("Use 'f' to scan forward, 'b' to scan backwards\n"); + break; + } + } + else + scan.direction = 0; + scan.speed = 0; + if (ioctl(id, SCSI_SCAN, &scan) == B_ERROR) + printf("Error trying to scan\n"); + else + printf("Scanning...\n"); + break; + } + close(id); + } + else + printf("CD player is empty or invalid scsi-id\n"); + return 0; +}