* 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.
|
||||
*/
|
||||
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
|
||||
private:
|
||||
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,
|
||||
enum attr_mode attrMode = kDiscIDAttributes);
|
||||
void _RestoreAttributes();
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
class Inode {
|
||||
public:
|
||||
Inode(Volume* volume, Inode* parent,
|
||||
const char* name, off_t start, off_t frames,
|
||||
const char* name, uint64 start, uint64 frames,
|
||||
int32 type);
|
||||
~Inode();
|
||||
|
||||
@@ -190,11 +190,11 @@ public:
|
||||
{ return fCreationTime; }
|
||||
time_t ModificationTime() const
|
||||
{ return fModificationTime; }
|
||||
off_t StartFrame() const
|
||||
uint64 StartFrame() const
|
||||
{ return fStartFrame; }
|
||||
off_t FrameCount() const
|
||||
uint64 FrameCount() const
|
||||
{ return fFrameCount; }
|
||||
off_t Size() const
|
||||
uint64 Size() const
|
||||
{ return fFrameCount * kFrameSize; }
|
||||
// does not include the WAV header
|
||||
|
||||
@@ -207,6 +207,8 @@ public:
|
||||
const char* string);
|
||||
status_t AddAttribute(const char* name, type_code type,
|
||||
uint32 value);
|
||||
status_t AddAttribute(const char* name, type_code type,
|
||||
uint64 value);
|
||||
status_t RemoveAttribute(const char* name,
|
||||
bool checkNamespace = false);
|
||||
|
||||
@@ -232,8 +234,8 @@ private:
|
||||
uid_t fUserID;
|
||||
time_t fCreationTime;
|
||||
time_t fModificationTime;
|
||||
off_t fStartFrame;
|
||||
off_t fFrameCount;
|
||||
uint64 fStartFrame;
|
||||
uint64 fFrameCount;
|
||||
AttributeList fAttributes;
|
||||
AttrCookieList fAttrCookies;
|
||||
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
|
||||
Volume::Mount(const char* device)
|
||||
{
|
||||
@@ -700,9 +671,9 @@ Volume::Mount(const char* device)
|
||||
scsi_cd_msf& start = toc->tracks[i].start.time;
|
||||
int32 track = i + 1;
|
||||
|
||||
off_t startFrame = start.minute * kFramesPerMinute
|
||||
uint64 startFrame = start.minute * kFramesPerMinute
|
||||
+ start.second * kFramesPerSecond + start.frame;
|
||||
off_t frames = next.minute * kFramesPerMinute
|
||||
uint64 frames = next.minute * kFramesPerMinute
|
||||
+ next.second * kFramesPerSecond + next.frame
|
||||
- startFrame;
|
||||
|
||||
@@ -742,13 +713,10 @@ Volume::Mount(const char* device)
|
||||
inode->AddAttribute("Audio:Album", B_STRING_TYPE, text.album);
|
||||
inode->AddAttribute("Audio:Title", B_STRING_TYPE, text.titles[i]);
|
||||
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");
|
||||
|
||||
snprintf(title, sizeof(title), "%02lu:%02lu",
|
||||
uint32(inode->FrameCount() / kFramesPerMinute),
|
||||
uint32((inode->FrameCount() % kFramesPerMinute) / kFramesPerSecond));
|
||||
inode->AddAttribute("Audio:Length", B_STRING_TYPE, title);
|
||||
inode->AddAttribute("Media:Length", B_INT64_TYPE,
|
||||
inode->FrameCount() * 1000000LL / kFramesPerSecond);
|
||||
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&
|
||||
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*
|
||||
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
|
||||
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
|
||||
of their attributes.
|
||||
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
|
||||
|
||||
|
||||
Inode::Inode(Volume* volume, Inode* parent, const char* name, off_t start,
|
||||
off_t frames, int32 type)
|
||||
Inode::Inode(Volume* volume, Inode* parent, const char* name, uint64 start,
|
||||
uint64 frames, int32 type)
|
||||
:
|
||||
fNext(NULL)
|
||||
{
|
||||
@@ -1300,7 +1299,16 @@ Inode::AddAttribute(const char* name, type_code type, const char* string)
|
||||
status_t
|
||||
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