From 8cc39dac67ae2796d1cba8892bef237fe38fedbf Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Fri, 1 Jul 2005 00:58:57 +0000 Subject: [PATCH] I guess I forgot to add these to the repository last time. Oops. :D git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13374 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/cdplayer/CDAudioDevice.cpp | 451 ++++++++++++++++++++++++++++ src/apps/cdplayer/CDAudioDevice.h | 72 +++++ 2 files changed, 523 insertions(+) create mode 100644 src/apps/cdplayer/CDAudioDevice.cpp create mode 100644 src/apps/cdplayer/CDAudioDevice.h diff --git a/src/apps/cdplayer/CDAudioDevice.cpp b/src/apps/cdplayer/CDAudioDevice.cpp new file mode 100644 index 0000000000..a50f6babee --- /dev/null +++ b/src/apps/cdplayer/CDAudioDevice.cpp @@ -0,0 +1,451 @@ +#include "CDAudioDevice.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi.h" + + +CDAudioDevice::CDAudioDevice(void) +{ + FindDrives("/dev/disk"); + SetDrive(0); +} + +CDAudioDevice::~CDAudioDevice(void) +{ + for(int32 i=0; i= 0x13) || + ((pos.position[1] == 0x12) && (!pos.position[6]))) + return kStopped; + else + if (pos.position[1] == 0x11) + return kPlaying; + else + return kPaused; +} + +int16 +CDAudioDevice::CountTracks(void) +{ + scsi_toc toc; + status_t result = ioctl(fFileHandle, B_SCSI_GET_TOC, &toc); + + if (result != B_OK) + return -1; + + return toc.toc_data[3]; +} + +// Get the 0-based index of the current track +int16 +CDAudioDevice::GetTrack(void) +{ + scsi_position pos; + + status_t media_status = B_DEV_NO_MEDIA; + + ioctl(fFileHandle, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status)); + if (media_status != B_OK) + return -1; + + status_t result = ioctl(fFileHandle, B_SCSI_GET_POSITION, &pos); + if (result != B_OK) + return -1; + + if (!pos.position[1] || pos.position[1] >= 0x13 + || (pos.position[1] == 0x12 && !pos.position[6])) + return 0; + else + return pos.position[6]; +} + +uint8 +CDAudioDevice::CountDrives(void) +{ + return fDriveList.CountItems(); +} + +bool +CDAudioDevice::SetDrive(const int32 &drive) +{ + BString *path = (BString*) fDriveList.ItemAt(drive); + + if(!path) + return false; + + int device = open(path->String(), O_RDONLY); + if(device >= 0) + { + fFileHandle = device; + fDrivePath = path; + return true; + } + + return false; +} + +const char * +CDAudioDevice::GetDrivePath(void) const +{ + if(!fDrivePath) + return NULL; + + return fDrivePath->String(); +} + +int32 CDAudioDevice::FindDrives(const char *path) +{ + BDirectory dir(path); + + if(dir.InitCheck() != B_OK) + return B_ERROR; + + dir.Rewind(); + + BEntry entry; + while(dir.GetNextEntry(&entry) >= 0) + { + BPath path; + const char *name; + entry_ref e; + + if(entry.GetPath(&path) != B_OK) + continue; + + name = path.Path(); + if(entry.GetRef(&e) != B_OK) + continue; + + if(entry.IsDirectory()) + { + // ignore floppy -- it is not silent + if(strcmp(e.name, "floppy") == 0) + continue; + + int32 count = FindDrives(name); + + if(count > 0) + return count; + } + else + { + int devfd; + device_geometry g; + + // ignore partitions + if(strcmp(e.name, "raw") != 0) + continue; + + devfd = open(name, O_RDONLY); + if(devfd < 0) + continue; + + if(ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) + { + if(g.device_type == B_CD) + fDriveList.AddItem(new BString(name)); + } + close(devfd); + } + } + return fDriveList.CountItems(); +} + +bool +CDAudioDevice::GetTime(cdaudio_time &track, cdaudio_time &disc) +{ + scsi_position pos; + + // Sanity check + status_t media_status = B_DEV_NO_MEDIA; + ioctl(fFileHandle, B_GET_MEDIA_STATUS, &media_status, sizeof(media_status)); + if (media_status != B_OK) + return false; + + status_t result = ioctl(fFileHandle, B_SCSI_GET_POSITION, &pos); + + if (result != B_OK) + return false; + + if ((!pos.position[1]) || (pos.position[1] >= 0x13) || + ((pos.position[1] == 0x12) && (!pos.position[6]))) + { + // This indicates that we have a CD, but we are stopped. + return false; + } + + disc.minutes = pos.position[9]; + disc.seconds = pos.position[10]; + track.minutes = pos.position[13]; + track.seconds = pos.position[14]; + return true; +} + +struct ConvertedToc +{ + int32 min; + int32 sec; + int32 frame; +}; + +static int32 +cddb_sum(int n) +{ + char buf[12]; + int32 ret = 0; + + sprintf(buf, "%u", n); + for (const char *p = buf; *p != '\0'; p++) + ret += (*p - '0'); + return ret; +} + +int32 +CDAudioDevice::GetDiscID(void) +{ + // Read the disc + scsi_toc toc; + status_t result = ioctl(fFileHandle, B_SCSI_GET_TOC, &toc); + + if (result != B_OK) + return -1; + + + int32 id, numTracks; + BString frameOffsetsString; + + ConvertedToc tocData[100]; + + // figure out the disc ID + for (int index = 0; index < 100; index++) + { + tocData[index].min = toc.toc_data[9 + 8*index]; + tocData[index].sec = toc.toc_data[10 + 8*index]; + tocData[index].frame = toc.toc_data[11 + 8*index]; + } + numTracks = toc.toc_data[3] - toc.toc_data[2] + 1; + + int32 sum1 = 0; + int32 sum2 = 0; + for (int index = 0; index < numTracks; index++) + { + sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec); + + // the following is probably running over too far + sum2 += (tocData[index + 1].min * 60 + tocData[index + 1].sec) - + (tocData[index].min * 60 + tocData[index].sec); + } + id = ((sum1 % 0xff) << 24) + (sum2 << 8) + numTracks; + + return id; +} diff --git a/src/apps/cdplayer/CDAudioDevice.h b/src/apps/cdplayer/CDAudioDevice.h new file mode 100644 index 0000000000..3887815ee1 --- /dev/null +++ b/src/apps/cdplayer/CDAudioDevice.h @@ -0,0 +1,72 @@ +#ifndef CDAUDIODEVICE_H +#define CDAUDIODEVICE_H + +#include +#include +#include + +enum CDState { + kNoCD=0, + kStopped, + kPaused, + kPlaying, + kSkipping +}; + +typedef struct +{ + int32 minutes; + int32 seconds; +} cdaudio_time; + +typedef struct +{ + int32 disc_id; + int32 track_count; + int32 length; + + BString frame_offsets; +} cdaudio_data; + +class CDAudioDevice +{ +public: + CDAudioDevice(void); + ~CDAudioDevice(void); + + bool Play(const int16 &track); + bool Pause(void); + bool Resume(void); + bool Stop(void); + bool Eject(void); + + bool StartFastFwd(void); + bool StopFastFwd(void); + + bool StartRewind(void); + bool StopRewind(void); + + bool SetVolume(uint8 value); + uint8 GetVolume(void); + + CDState GetState(void); + + int16 CountTracks(void); + int16 GetTrack(void); + + uint8 CountDrives(void); + bool SetDrive(const int32 &drive); + const char * GetDrivePath(void) const; + + bool GetTime(cdaudio_time &track, cdaudio_time &disc); + int32 GetDiscID(void); + +private: + int32 FindDrives(const char *path); + + int fFileHandle; + BString * fDrivePath; + BList fDriveList; +}; + +#endif