* 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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
// 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) {
|
||||
off_t frame = offset / kFrameSize;
|
||||
uint32 count = bufferSize / kFrameSize;
|
||||
if (frame + count > endFrame)
|
||||
count = endFrame - frame;
|
||||
|
||||
status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
|
||||
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.
|
||||
*/
|
||||
#ifndef CDDA_H
|
||||
@@ -30,7 +30,7 @@ struct cdtext {
|
||||
|
||||
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_cdda_data(int fd, off_t offset, void *data, size_t length,
|
||||
off_t bufferOffset, void *buffer, size_t bufferSize);
|
||||
status_t read_cdda_data(int fd, off_t endFrame, off_t offset, void *data,
|
||||
size_t length, off_t bufferOffset, void *buffer, size_t bufferSize);
|
||||
|
||||
#endif // CDDA_H
|
||||
|
||||
@@ -388,7 +388,6 @@ read_attributes(int fd, Inode *inode)
|
||||
return false;
|
||||
|
||||
count = B_BENDIAN_TO_HOST_INT32(count);
|
||||
dprintf("inode %s read %lu attrs\n", inode->Name(), count);
|
||||
if (count > kMaxAttributes)
|
||||
return false;
|
||||
|
||||
@@ -405,7 +404,6 @@ dprintf("inode %s read %lu attrs\n", inode->Name(), count);
|
||||
type = B_BENDIAN_TO_HOST_INT32(type);
|
||||
size = B_BENDIAN_TO_HOST_INT32(size);
|
||||
name[length] = '\0';
|
||||
dprintf(" type %08lx, size %lu, name %s\n", type, size, name);
|
||||
|
||||
Attribute *attribute = new Attribute(name, type);
|
||||
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_type = attribute->Type();
|
||||
} else {
|
||||
stat.st_size = inode->Size();
|
||||
stat.st_size = inode->Size() + sizeof(wav_header);
|
||||
stat.st_mode = inode->Type();
|
||||
stat.st_type = 0;
|
||||
}
|
||||
@@ -782,7 +780,6 @@ Volume::_OpenAttributes(int mode, enum attr_mode attrMode)
|
||||
} else
|
||||
strlcat(path, "/shared", B_PATH_NAME_LENGTH);
|
||||
|
||||
dprintf("PATH: %s\n", path);
|
||||
int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644);
|
||||
|
||||
free(path);
|
||||
@@ -807,7 +804,6 @@ Volume::_RestoreAttributes()
|
||||
return;
|
||||
}
|
||||
|
||||
dprintf("VOLUME %s\n", line);
|
||||
SetName(line);
|
||||
|
||||
for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) {
|
||||
@@ -815,7 +811,6 @@ dprintf("VOLUME %s\n", line);
|
||||
break;
|
||||
|
||||
inode->SetName(line);
|
||||
dprintf("INODE %s\n", line);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
status_t status = B_OK;
|
||||
size_t bytesRead = 0;
|
||||
|
||||
if (offset < sizeof(wav_header)) {
|
||||
// read fake WAV header
|
||||
size_t size = sizeof(wav_header) - offset;
|
||||
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;
|
||||
|
||||
buffer = (void *)((uint8 *)buffer + size);
|
||||
length -= size;
|
||||
bytesRead += size;
|
||||
offset = 0;
|
||||
} else
|
||||
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
|
||||
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());
|
||||
|
||||
bytesRead += length;
|
||||
}
|
||||
if (status == B_OK)
|
||||
*_length = length;
|
||||
*_length = bytesRead;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user