* Write the new Media:Length attribute instead of the old Audio:Length one.
* Use uint64 instead of off_t for the frame numbers. * Shuffled Volume methods around to match the declaration order. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41282 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007-2010, Axel Dörfler, [email protected].
|
* Copyright 2007-2011, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Inode* _CreateNode(Inode* parent, const char* name,
|
Inode* _CreateNode(Inode* parent, const char* name,
|
||||||
off_t start, off_t frames, int32 type);
|
uint64 start, uint64 frames, int32 type);
|
||||||
int _OpenAttributes(int mode,
|
int _OpenAttributes(int mode,
|
||||||
enum attr_mode attrMode = kDiscIDAttributes);
|
enum attr_mode attrMode = kDiscIDAttributes);
|
||||||
void _RestoreAttributes();
|
void _RestoreAttributes();
|
||||||
@@ -170,7 +170,7 @@ private:
|
|||||||
class Inode {
|
class Inode {
|
||||||
public:
|
public:
|
||||||
Inode(Volume* volume, Inode* parent,
|
Inode(Volume* volume, Inode* parent,
|
||||||
const char* name, off_t start, off_t frames,
|
const char* name, uint64 start, uint64 frames,
|
||||||
int32 type);
|
int32 type);
|
||||||
~Inode();
|
~Inode();
|
||||||
|
|
||||||
@@ -190,11 +190,11 @@ public:
|
|||||||
{ return fCreationTime; }
|
{ return fCreationTime; }
|
||||||
time_t ModificationTime() const
|
time_t ModificationTime() const
|
||||||
{ return fModificationTime; }
|
{ return fModificationTime; }
|
||||||
off_t StartFrame() const
|
uint64 StartFrame() const
|
||||||
{ return fStartFrame; }
|
{ return fStartFrame; }
|
||||||
off_t FrameCount() const
|
uint64 FrameCount() const
|
||||||
{ return fFrameCount; }
|
{ return fFrameCount; }
|
||||||
off_t Size() const
|
uint64 Size() const
|
||||||
{ return fFrameCount * kFrameSize; }
|
{ return fFrameCount * kFrameSize; }
|
||||||
// does not include the WAV header
|
// does not include the WAV header
|
||||||
|
|
||||||
@@ -207,6 +207,8 @@ public:
|
|||||||
const char* string);
|
const char* string);
|
||||||
status_t AddAttribute(const char* name, type_code type,
|
status_t AddAttribute(const char* name, type_code type,
|
||||||
uint32 value);
|
uint32 value);
|
||||||
|
status_t AddAttribute(const char* name, type_code type,
|
||||||
|
uint64 value);
|
||||||
status_t RemoveAttribute(const char* name,
|
status_t RemoveAttribute(const char* name,
|
||||||
bool checkNamespace = false);
|
bool checkNamespace = false);
|
||||||
|
|
||||||
@@ -232,8 +234,8 @@ private:
|
|||||||
uid_t fUserID;
|
uid_t fUserID;
|
||||||
time_t fCreationTime;
|
time_t fCreationTime;
|
||||||
time_t fModificationTime;
|
time_t fModificationTime;
|
||||||
off_t fStartFrame;
|
uint64 fStartFrame;
|
||||||
off_t fFrameCount;
|
uint64 fFrameCount;
|
||||||
AttributeList fAttributes;
|
AttributeList fAttributes;
|
||||||
AttrCookieList fAttrCookies;
|
AttrCookieList fAttrCookies;
|
||||||
wav_header fWAVHeader;
|
wav_header fWAVHeader;
|
||||||
@@ -608,37 +610,6 @@ Volume::InitCheck()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ void
|
|
||||||
Volume::DetermineName(uint32 cddbID, int device, char* name, size_t length)
|
|
||||||
{
|
|
||||||
name[0] = '\0';
|
|
||||||
|
|
||||||
int attrFD = open_attributes(cddbID, device, O_RDONLY,
|
|
||||||
kDiscIDAttributes);
|
|
||||||
if (attrFD < 0) {
|
|
||||||
// We do not have attributes set. Read CD text.
|
|
||||||
cdtext text;
|
|
||||||
if (read_cdtext(device, text) == B_OK) {
|
|
||||||
if (text.artist != NULL && text.album != NULL)
|
|
||||||
snprintf(name, length, "%s - %s", text.artist, text.album);
|
|
||||||
else if (text.artist != NULL || text.album != NULL) {
|
|
||||||
snprintf(name, length, "%s", text.artist != NULL
|
|
||||||
? text.artist : text.album);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We have an attribute file. Read name from it.
|
|
||||||
if (!read_line(attrFD, name, length))
|
|
||||||
name[0] = '\0';
|
|
||||||
|
|
||||||
close(attrFD);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name[0])
|
|
||||||
strlcpy(name, "Audio CD", length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::Mount(const char* device)
|
Volume::Mount(const char* device)
|
||||||
{
|
{
|
||||||
@@ -700,9 +671,9 @@ Volume::Mount(const char* device)
|
|||||||
scsi_cd_msf& start = toc->tracks[i].start.time;
|
scsi_cd_msf& start = toc->tracks[i].start.time;
|
||||||
int32 track = i + 1;
|
int32 track = i + 1;
|
||||||
|
|
||||||
off_t startFrame = start.minute * kFramesPerMinute
|
uint64 startFrame = start.minute * kFramesPerMinute
|
||||||
+ start.second * kFramesPerSecond + start.frame;
|
+ start.second * kFramesPerSecond + start.frame;
|
||||||
off_t frames = next.minute * kFramesPerMinute
|
uint64 frames = next.minute * kFramesPerMinute
|
||||||
+ next.second * kFramesPerSecond + next.frame
|
+ next.second * kFramesPerSecond + next.frame
|
||||||
- startFrame;
|
- startFrame;
|
||||||
|
|
||||||
@@ -742,13 +713,10 @@ Volume::Mount(const char* device)
|
|||||||
inode->AddAttribute("Audio:Album", B_STRING_TYPE, text.album);
|
inode->AddAttribute("Audio:Album", B_STRING_TYPE, text.album);
|
||||||
inode->AddAttribute("Audio:Title", B_STRING_TYPE, text.titles[i]);
|
inode->AddAttribute("Audio:Title", B_STRING_TYPE, text.titles[i]);
|
||||||
inode->AddAttribute("Audio:Genre", B_STRING_TYPE, text.genre);
|
inode->AddAttribute("Audio:Genre", B_STRING_TYPE, text.genre);
|
||||||
inode->AddAttribute("Audio:Track", B_INT32_TYPE, track);
|
inode->AddAttribute("Audio:Track", B_INT32_TYPE, (uint32)track);
|
||||||
inode->AddAttribute("Audio:Bitrate", B_STRING_TYPE, "1411 kbps");
|
inode->AddAttribute("Audio:Bitrate", B_STRING_TYPE, "1411 kbps");
|
||||||
|
inode->AddAttribute("Media:Length", B_INT64_TYPE,
|
||||||
snprintf(title, sizeof(title), "%02lu:%02lu",
|
inode->FrameCount() * 1000000LL / kFramesPerSecond);
|
||||||
uint32(inode->FrameCount() / kFramesPerMinute),
|
|
||||||
uint32((inode->FrameCount() % kFramesPerMinute) / kFramesPerSecond));
|
|
||||||
inode->AddAttribute("Audio:Length", B_STRING_TYPE, title);
|
|
||||||
inode->AddAttribute("BEOS:TYPE", B_MIME_STRING_TYPE, "audio/x-wav");
|
inode->AddAttribute("BEOS:TYPE", B_MIME_STRING_TYPE, "audio/x-wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,6 +749,22 @@ Volume::Mount(const char* device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::SetName(const char* name)
|
||||||
|
{
|
||||||
|
if (name == NULL || !name[0])
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
name = strdup(name);
|
||||||
|
if (name == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
free(fName);
|
||||||
|
fName = (char*)name;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Semaphore&
|
Semaphore&
|
||||||
Volume::Lock()
|
Volume::Lock()
|
||||||
{
|
{
|
||||||
@@ -788,38 +772,6 @@ Volume::Lock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Inode*
|
|
||||||
Volume::_CreateNode(Inode* parent, const char* name, off_t start, off_t frames,
|
|
||||||
int32 type)
|
|
||||||
{
|
|
||||||
Inode* inode = new Inode(this, parent, name, start, frames, type);
|
|
||||||
if (inode == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (inode->InitCheck() != B_OK) {
|
|
||||||
delete inode;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISREG(type)) {
|
|
||||||
// we need to order it by track for compatibility with BeOS' cdda
|
|
||||||
Inode* current = fFirstEntry;
|
|
||||||
Inode* last = NULL;
|
|
||||||
while (current != NULL) {
|
|
||||||
last = current;
|
|
||||||
current = current->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last)
|
|
||||||
last->SetNext(inode);
|
|
||||||
else
|
|
||||||
fFirstEntry = inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Inode*
|
Inode*
|
||||||
Volume::Find(ino_t id)
|
Volume::Find(ino_t id)
|
||||||
{
|
{
|
||||||
@@ -848,22 +800,6 @@ Volume::Find(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
Volume::SetName(const char* name)
|
|
||||||
{
|
|
||||||
if (name == NULL || !name[0])
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
name = strdup(name);
|
|
||||||
if (name == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
free(fName);
|
|
||||||
fName = (char*)name;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Volume::DisableCDDBLookUps()
|
Volume::DisableCDDBLookUps()
|
||||||
{
|
{
|
||||||
@@ -873,6 +809,69 @@ Volume::DisableCDDBLookUps()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
Volume::DetermineName(uint32 cddbID, int device, char* name, size_t length)
|
||||||
|
{
|
||||||
|
name[0] = '\0';
|
||||||
|
|
||||||
|
int attrFD = open_attributes(cddbID, device, O_RDONLY,
|
||||||
|
kDiscIDAttributes);
|
||||||
|
if (attrFD < 0) {
|
||||||
|
// We do not have attributes set. Read CD text.
|
||||||
|
cdtext text;
|
||||||
|
if (read_cdtext(device, text) == B_OK) {
|
||||||
|
if (text.artist != NULL && text.album != NULL)
|
||||||
|
snprintf(name, length, "%s - %s", text.artist, text.album);
|
||||||
|
else if (text.artist != NULL || text.album != NULL) {
|
||||||
|
snprintf(name, length, "%s", text.artist != NULL
|
||||||
|
? text.artist : text.album);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We have an attribute file. Read name from it.
|
||||||
|
if (!read_line(attrFD, name, length))
|
||||||
|
name[0] = '\0';
|
||||||
|
|
||||||
|
close(attrFD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name[0])
|
||||||
|
strlcpy(name, "Audio CD", length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Inode*
|
||||||
|
Volume::_CreateNode(Inode* parent, const char* name, uint64 start,
|
||||||
|
uint64 frames, int32 type)
|
||||||
|
{
|
||||||
|
Inode* inode = new Inode(this, parent, name, start, frames, type);
|
||||||
|
if (inode == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (inode->InitCheck() != B_OK) {
|
||||||
|
delete inode;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_ISREG(type)) {
|
||||||
|
// we need to order it by track for compatibility with BeOS' cdda
|
||||||
|
Inode* current = fFirstEntry;
|
||||||
|
Inode* last = NULL;
|
||||||
|
while (current != NULL) {
|
||||||
|
last = current;
|
||||||
|
current = current->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
last->SetNext(inode);
|
||||||
|
else
|
||||||
|
fFirstEntry = inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Opens the file that contains the volume and inode titles as well as all
|
/*! Opens the file that contains the volume and inode titles as well as all
|
||||||
of their attributes.
|
of their attributes.
|
||||||
The attributes are stored in files below B_USER_SETTINGS_DIRECTORY/cdda.
|
The attributes are stored in files below B_USER_SETTINGS_DIRECTORY/cdda.
|
||||||
@@ -1148,8 +1147,8 @@ Attribute::IsProtectedNamespace(const char* name)
|
|||||||
// #pragma mark - Inode class
|
// #pragma mark - Inode class
|
||||||
|
|
||||||
|
|
||||||
Inode::Inode(Volume* volume, Inode* parent, const char* name, off_t start,
|
Inode::Inode(Volume* volume, Inode* parent, const char* name, uint64 start,
|
||||||
off_t frames, int32 type)
|
uint64 frames, int32 type)
|
||||||
:
|
:
|
||||||
fNext(NULL)
|
fNext(NULL)
|
||||||
{
|
{
|
||||||
@@ -1300,7 +1299,16 @@ Inode::AddAttribute(const char* name, type_code type, const char* string)
|
|||||||
status_t
|
status_t
|
||||||
Inode::AddAttribute(const char* name, type_code type, uint32 value)
|
Inode::AddAttribute(const char* name, type_code type, uint32 value)
|
||||||
{
|
{
|
||||||
return AddAttribute(name, type, true, (const uint8*)&value, sizeof(uint32));
|
uint32 data = B_HOST_TO_LENDIAN_INT32(value);
|
||||||
|
return AddAttribute(name, type, true, (const uint8*)&data, sizeof(uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::AddAttribute(const char* name, type_code type, uint64 value)
|
||||||
|
{
|
||||||
|
uint64 data = B_HOST_TO_LENDIAN_INT64(value);
|
||||||
|
return AddAttribute(name, type, true, (const uint8*)&data, sizeof(uint64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user