* read_cdda_data() needs to know the last frame of the track, so that it can
cut down the buffer size on the last request. This fixes bug #2565. * cdda_read() did report an incorrect number of bytes read. This fixes bug #2511, and also that you couldn't copy tracks via "cp". * cdda_read_stat() did not include the WAV header in its reported size. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26853 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -602,7 +602,7 @@ read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
read_cdda_data(int fd, off_t offset, void *data, size_t length,
|
read_cdda_data(int fd, off_t endFrame, off_t offset, void *data, size_t length,
|
||||||
off_t bufferOffset, void *buffer, size_t bufferSize)
|
off_t bufferOffset, void *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
if (bufferOffset >= 0 && bufferOffset <= offset + length
|
if (bufferOffset >= 0 && bufferOffset <= offset + length
|
||||||
@@ -627,12 +627,14 @@ read_cdda_data(int fd, off_t offset, void *data, size_t length,
|
|||||||
|
|
||||||
length -= bytes;
|
length -= bytes;
|
||||||
}
|
}
|
||||||
// we don't handle the case we would need to split the request
|
// we don't handle the case where we would need to split the request
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
off_t frame = offset / kFrameSize;
|
off_t frame = offset / kFrameSize;
|
||||||
uint32 count = bufferSize / kFrameSize;
|
uint32 count = bufferSize / kFrameSize;
|
||||||
|
if (frame + count > endFrame)
|
||||||
|
count = endFrame - frame;
|
||||||
|
|
||||||
status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
|
status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2007, Axel Dörfler, [email protected].
|
* Copyright 2007-2008, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef CDDA_H
|
#ifndef CDDA_H
|
||||||
@@ -30,7 +30,7 @@ struct cdtext {
|
|||||||
|
|
||||||
status_t read_cdtext(int fd, cdtext &text);
|
status_t read_cdtext(int fd, cdtext &text);
|
||||||
status_t read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length);
|
status_t read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length);
|
||||||
status_t read_cdda_data(int fd, off_t offset, void *data, size_t length,
|
status_t read_cdda_data(int fd, off_t endFrame, off_t offset, void *data,
|
||||||
off_t bufferOffset, void *buffer, size_t bufferSize);
|
size_t length, off_t bufferOffset, void *buffer, size_t bufferSize);
|
||||||
|
|
||||||
#endif // CDDA_H
|
#endif // CDDA_H
|
||||||
|
|||||||
@@ -388,7 +388,6 @@ read_attributes(int fd, Inode *inode)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
count = B_BENDIAN_TO_HOST_INT32(count);
|
count = B_BENDIAN_TO_HOST_INT32(count);
|
||||||
dprintf("inode %s read %lu attrs\n", inode->Name(), count);
|
|
||||||
if (count > kMaxAttributes)
|
if (count > kMaxAttributes)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -405,7 +404,6 @@ dprintf("inode %s read %lu attrs\n", inode->Name(), count);
|
|||||||
type = B_BENDIAN_TO_HOST_INT32(type);
|
type = B_BENDIAN_TO_HOST_INT32(type);
|
||||||
size = B_BENDIAN_TO_HOST_INT32(size);
|
size = B_BENDIAN_TO_HOST_INT32(size);
|
||||||
name[length] = '\0';
|
name[length] = '\0';
|
||||||
dprintf(" type %08lx, size %lu, name %s\n", type, size, name);
|
|
||||||
|
|
||||||
Attribute *attribute = new Attribute(name, type);
|
Attribute *attribute = new Attribute(name, type);
|
||||||
if (attribute->SetSize(size) != B_OK
|
if (attribute->SetSize(size) != B_OK
|
||||||
@@ -431,7 +429,7 @@ fill_stat_buffer(Volume *volume, Inode *inode, Attribute *attribute,
|
|||||||
stat.st_mode = S_ATTR | 0666;
|
stat.st_mode = S_ATTR | 0666;
|
||||||
stat.st_type = attribute->Type();
|
stat.st_type = attribute->Type();
|
||||||
} else {
|
} else {
|
||||||
stat.st_size = inode->Size();
|
stat.st_size = inode->Size() + sizeof(wav_header);
|
||||||
stat.st_mode = inode->Type();
|
stat.st_mode = inode->Type();
|
||||||
stat.st_type = 0;
|
stat.st_type = 0;
|
||||||
}
|
}
|
||||||
@@ -782,7 +780,6 @@ Volume::_OpenAttributes(int mode, enum attr_mode attrMode)
|
|||||||
} else
|
} else
|
||||||
strlcat(path, "/shared", B_PATH_NAME_LENGTH);
|
strlcat(path, "/shared", B_PATH_NAME_LENGTH);
|
||||||
|
|
||||||
dprintf("PATH: %s\n", path);
|
|
||||||
int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644);
|
int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644);
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
@@ -807,7 +804,6 @@ Volume::_RestoreAttributes()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("VOLUME %s\n", line);
|
|
||||||
SetName(line);
|
SetName(line);
|
||||||
|
|
||||||
for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) {
|
for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) {
|
||||||
@@ -815,7 +811,6 @@ dprintf("VOLUME %s\n", line);
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
inode->SetName(line);
|
inode->SetName(line);
|
||||||
dprintf("INODE %s\n", line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_attributes(fd, fRootNode)) {
|
if (read_attributes(fd, fRootNode)) {
|
||||||
@@ -1546,17 +1541,20 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset,
|
|||||||
length = maxSize - offset;
|
length = maxSize - offset;
|
||||||
|
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
|
size_t bytesRead = 0;
|
||||||
|
|
||||||
if (offset < sizeof(wav_header)) {
|
if (offset < sizeof(wav_header)) {
|
||||||
// read fake WAV header
|
// read fake WAV header
|
||||||
size_t size = sizeof(wav_header) - offset;
|
size_t size = sizeof(wav_header) - offset;
|
||||||
size = min_c(size, length);
|
size = min_c(size, length);
|
||||||
|
|
||||||
if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size) < B_OK)
|
if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size)
|
||||||
|
< B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
buffer = (void *)((uint8 *)buffer + size);
|
buffer = (void *)((uint8 *)buffer + size);
|
||||||
length -= size;
|
length -= size;
|
||||||
|
bytesRead += size;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
} else
|
} else
|
||||||
offset -= sizeof(wav_header);
|
offset -= sizeof(wav_header);
|
||||||
@@ -1565,11 +1563,14 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset,
|
|||||||
// read actual CD data
|
// read actual CD data
|
||||||
offset += inode->StartFrame() * kFrameSize;
|
offset += inode->StartFrame() * kFrameSize;
|
||||||
|
|
||||||
status = read_cdda_data(volume->Device(), offset, buffer, length,
|
status = read_cdda_data(volume->Device(),
|
||||||
|
inode->StartFrame() + inode->FrameCount(), offset, buffer, length,
|
||||||
cookie->buffer_offset, cookie->buffer, volume->BufferSize());
|
cookie->buffer_offset, cookie->buffer, volume->BufferSize());
|
||||||
|
|
||||||
|
bytesRead += length;
|
||||||
}
|
}
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
*_length = length;
|
*_length = bytesRead;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user