You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
4.9 KiB
226 lines
4.9 KiB
/*
|
|
cdda input class based on cdparanoia
|
|
Copyright (C) 2000 Martin Vogt
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation.
|
|
|
|
For more information look at the file COPYRIGHT in this package
|
|
|
|
*/
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef CDDA_PARANOIA
|
|
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
#include "cddaInputStream.h"
|
|
#include "inputDetector.h"
|
|
|
|
|
|
void paranoiaCallback(long, int) {
|
|
//cout << "long:"<<a<<" int:"<<b<<endl;
|
|
}
|
|
|
|
CDDAInputStream::CDDAInputStream() {
|
|
drive = NULL;
|
|
paranoia=NULL;
|
|
device=NULL;
|
|
track=1;
|
|
}
|
|
|
|
|
|
CDDAInputStream::~CDDAInputStream() {
|
|
close();
|
|
}
|
|
|
|
// here we should encdoe the track Nr. as well
|
|
// eg: /dev/cdrom#1
|
|
int CDDAInputStream::getTrackAndDevice(const char* url) {
|
|
int matches=0;
|
|
// dest = "cdda:/dev/cdrom/track01.cda"
|
|
char* noprotoString=InputDetector::removeProtocol(url);
|
|
// noprotoString="/dev/cdrom/track01.cda"
|
|
char* filename=InputDetector::getFilename(noprotoString);
|
|
// filename="track01.cda"
|
|
char* filenameNoExt=InputDetector::getWithoutExtension(filename);
|
|
// filenameNoExt="track01"
|
|
char* dir=InputDetector::removeExtension(noprotoString,filename);
|
|
// dir="/dev/cdrom/"
|
|
device=InputDetector::removeSlash(dir);
|
|
track=1;
|
|
if (filenameNoExt != NULL) {
|
|
matches=sscanf(filenameNoExt,"track%02d",&track);
|
|
}
|
|
if (matches == 0) {
|
|
cout << "no trackNumber found using default"<<endl;
|
|
}
|
|
cout << "device:"<<device<<" track:"<<track<<endl;
|
|
|
|
if (noprotoString != NULL) {
|
|
delete noprotoString;
|
|
}
|
|
if (filename != NULL) {
|
|
delete filename;
|
|
}
|
|
if (filenameNoExt != NULL) {
|
|
delete filenameNoExt;
|
|
}
|
|
if (dir != NULL) {
|
|
delete dir;
|
|
}
|
|
if (device == NULL) {
|
|
cout << "no device found, using any"<<endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int CDDAInputStream::open(const char* dest) {
|
|
if (getTrackAndDevice(dest) == true) {
|
|
drive = cdda_identify(device, CDDA_MESSAGE_PRINTIT, 0);
|
|
}
|
|
|
|
if (drive == NULL) {
|
|
cout << "cdda_identify failed trying to find a device"<<endl;
|
|
drive=cdda_find_a_cdrom(CDDA_MESSAGE_PRINTIT, 0);
|
|
}
|
|
if (drive == NULL) {
|
|
cout << "nope. nothing found. give up"<<endl;
|
|
return false;
|
|
}
|
|
cout << "cdda_open -s"<<endl;
|
|
if (cdda_open(drive) != 0) {
|
|
cout << "cdda_open(drive) failed"<<endl;
|
|
close();
|
|
return false;
|
|
}
|
|
cout << "cdda_open -e"<<endl;
|
|
|
|
// debug things a bit
|
|
int trackCount = drive->tracks;
|
|
for (int i = 1; i <= trackCount; i++) {
|
|
if (IS_AUDIO(drive, i)) {
|
|
printf("track%02d.cda\n", i);
|
|
} else {
|
|
printf("no audio:%d\n",i);
|
|
}
|
|
}
|
|
|
|
paranoia = paranoia_init(drive);
|
|
if (paranoia == NULL) {
|
|
cout << "paranoia init failed"<<endl;
|
|
close();
|
|
return false;
|
|
}
|
|
|
|
firstSector=cdda_track_firstsector(drive, track);
|
|
lastSector=cdda_track_lastsector(drive, track);
|
|
currentSector=firstSector;
|
|
// paranoia && drive != NULL -> initialized!
|
|
|
|
int paranoiaLevel = PARANOIA_MODE_FULL ^ PARANOIA_MODE_NEVERSKIP;
|
|
paranoia_modeset(paranoia, paranoiaLevel);
|
|
cdda_verbose_set(drive, CDDA_MESSAGE_PRINTIT, CDDA_MESSAGE_PRINTIT);
|
|
paranoia_seek(paranoia, firstSector, SEEK_SET);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CDDAInputStream::close() {
|
|
if (isOpen() == false) {
|
|
return;
|
|
}
|
|
cdda_close(drive);
|
|
drive=NULL;
|
|
if (paranoia != NULL) {
|
|
paranoia_free(paranoia);
|
|
paranoia = 0;
|
|
}
|
|
if (device != NULL) {
|
|
delete device;
|
|
device=NULL;
|
|
}
|
|
}
|
|
|
|
|
|
int CDDAInputStream::isOpen() {
|
|
return (drive != NULL);
|
|
}
|
|
|
|
|
|
int CDDAInputStream::eof() {
|
|
if (isOpen()==false) {
|
|
return true;
|
|
}
|
|
if (currentSector >= lastSector) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
int CDDAInputStream::read(char* dest,int len) {
|
|
if (len != 2*CD_FRAMESIZE_RAW) {
|
|
cout << "len must be 2*CD_FRAMESIZE_RAW"<<endl;
|
|
exit(0);
|
|
}
|
|
int16_t * buf = paranoia_read(paranoia, paranoiaCallback);
|
|
currentSector++;
|
|
if (buf == NULL) {
|
|
cout << "paranoia_read failed"<<endl;
|
|
close();
|
|
return 0;
|
|
}
|
|
memcpy(dest,buf,sizeof(int16_t)*CD_FRAMESIZE_RAW);
|
|
return CD_FRAMESIZE_RAW;
|
|
}
|
|
|
|
|
|
int CDDAInputStream::seek(long bytePos) {
|
|
int byteLength=getByteLength();
|
|
float ratio=(float)bytePos/(float)(byteLength+1);
|
|
float wantSector=ratio*(float)((lastSector-firstSector));
|
|
if (isOpen()) {
|
|
currentSector=(int)wantSector;
|
|
cout << "paranoia_seek:"<<currentSector<<endl;
|
|
paranoia_seek(paranoia, currentSector, SEEK_SET);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CDDAInputStream::clear() {
|
|
cout << "direct virtual call CDDAInputStream::clear:"<<endl;
|
|
}
|
|
|
|
|
|
long CDDAInputStream::getByteLength() {
|
|
int sectors=lastSector-firstSector;
|
|
int bytes=sectors*CD_FRAMESIZE_RAW*sizeof(int16_t);
|
|
cout << "getByteLength:"<<bytes<<endl;
|
|
return bytes;
|
|
}
|
|
|
|
|
|
long CDDAInputStream::getBytePosition() {
|
|
int readSectors=currentSector-firstSector;
|
|
int bytes=readSectors*CD_FRAMESIZE_RAW*sizeof(int16_t);
|
|
return bytes;
|
|
}
|
|
|
|
#endif
|
|
//CDDA_PARANOIA
|
|
|
|
|
|
|
|
|
|
|