* compute offset based on vendor (32 for non intel) and sample rate

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29327 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2009-02-26 23:27:28 +00:00
parent 2144797f02
commit b5aca78a04

View File

@ -504,13 +504,12 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
const char* desc) const char* desc)
{ {
uint32 bufferSize, bufferPhysicalAddress, alloc; uint32 bufferSize, bufferPhysicalAddress, alloc;
uint32 response[2], index; uint32 response[2];
physical_entry pe; physical_entry pe;
bdl_entry_t* bufferDescriptors; bdl_entry_t* bufferDescriptors;
corb_t verb[2]; corb_t verb[2];
uint8* buffer; uint8* buffer;
status_t rc; status_t rc;
uint16 format;
/* Clear previously allocated memory */ /* Clear previously allocated memory */
if (stream->buffer_area >= B_OK) { if (stream->buffer_area >= B_OK) {
@ -523,10 +522,34 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
stream->buffer_descriptors_area = B_ERROR; stream->buffer_descriptors_area = B_ERROR;
} }
/* Find out stream format and sample rate */
uint16 format = (stream->num_channels - 1) & 0xf;
switch (stream->sample_format) {
case B_FMT_8BIT_S: format |= FORMAT_8BIT; stream->bps = 8; break;
case B_FMT_16BIT: format |= FORMAT_16BIT; stream->bps = 16; break;
case B_FMT_20BIT: format |= FORMAT_20BIT; stream->bps = 20; break;
case B_FMT_24BIT: format |= FORMAT_24BIT; stream->bps = 24; break;
case B_FMT_32BIT: format |= FORMAT_32BIT; stream->bps = 32; break;
default:
dprintf("hda: Invalid sample format: 0x%lx\n",
stream->sample_format);
break;
}
for (uint32 index = 0; index < sizeof(kRates) / sizeof(kRates[0]); index++) {
if (kRates[index].multi_rate == stream->sample_rate) {
format |= kRates[index].hw_rate;
stream->rate = kRates[index].rate;
break;
}
}
// Stream interrupts seem to arrive too early on most HDA // Stream interrupts seem to arrive too early on most HDA
// so we adjust buffer descriptors to take this into account // so we adjust buffer descriptors to take this into account
// TODO compute this value based on sample rate and depending on the hardware uint32 offset = (stream->sample_size * stream->num_channels) * stream->rate / 48000;
uint32 offset = 1 * (stream->sample_size * stream->num_channels); if (stream->controller->pci_info.vendor_id != INTEL_VENDORID)
offset *= 32;
/* Calculate size of buffer (aligned to 128 bytes) */ /* Calculate size of buffer (aligned to 128 bytes) */
bufferSize = stream->sample_size * stream->num_channels bufferSize = stream->sample_size * stream->num_channels
@ -535,6 +558,8 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld, offset %ld **********\n", dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld, offset %ld **********\n",
stream->sample_size, stream->num_channels, stream->buffer_length, offset); stream->sample_size, stream->num_channels, stream->buffer_length, offset);
dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld F=0x%x\n", __func__, stream->id,
stream->rate, stream->bps, format);
/* Calculate total size of all buffers (aligned to size of B_PAGE_SIZE) */ /* Calculate total size of all buffers (aligned to size of B_PAGE_SIZE) */
alloc = bufferSize * stream->num_buffers; alloc = bufferSize * stream->num_buffers;
@ -559,7 +584,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
alloc, stream->num_buffers); alloc, stream->num_buffers);
/* Store pointers (both virtual/physical) */ /* Store pointers (both virtual/physical) */
for (index = 0; index < stream->num_buffers; index++) { for (uint32 index = 0; index < stream->num_buffers; index++) {
stream->buffers[index] = buffer + (index * bufferSize); stream->buffers[index] = buffer + (index * bufferSize);
stream->physical_buffers[index] = bufferPhysicalAddress stream->physical_buffers[index] = bufferPhysicalAddress
+ (index * bufferSize); + (index * bufferSize);
@ -601,7 +626,7 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
} }
/* Setup buffer descriptor list (BDL) entries */ /* Setup buffer descriptor list (BDL) entries */
for (index = 0; index < stream->num_buffers; index++, bufferDescriptors++) { for (uint32 index = 0; index < stream->num_buffers; index++, bufferDescriptors++) {
bufferDescriptors->lower = stream->physical_buffers[index] + offset; bufferDescriptors->lower = stream->physical_buffers[index] + offset;
bufferDescriptors->upper = 0; bufferDescriptors->upper = 0;
fragments++; fragments++;
@ -616,31 +641,6 @@ hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream,
} }
/* Configure stream registers */ /* Configure stream registers */
format = (stream->num_channels - 1) & 0xf;
switch (stream->sample_format) {
case B_FMT_8BIT_S: format |= FORMAT_8BIT; stream->bps = 8; break;
case B_FMT_16BIT: format |= FORMAT_16BIT; stream->bps = 16; break;
case B_FMT_20BIT: format |= FORMAT_20BIT; stream->bps = 20; break;
case B_FMT_24BIT: format |= FORMAT_24BIT; stream->bps = 24; break;
case B_FMT_32BIT: format |= FORMAT_32BIT; stream->bps = 32; break;
default:
dprintf("hda: Invalid sample format: 0x%lx\n",
stream->sample_format);
break;
}
for (index = 0; index < sizeof(kRates) / sizeof(kRates[0]); index++) {
if (kRates[index].multi_rate == stream->sample_rate) {
format |= kRates[index].hw_rate;
stream->rate = kRates[index].rate;
break;
}
}
dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld F=0x%x\n", __func__, stream->id,
stream->rate, stream->bps, format);
stream->Write16(HDAC_STREAM_FORMAT, format); stream->Write16(HDAC_STREAM_FORMAT, format);
stream->Write32(HDAC_STREAM_BUFFERS_BASE_LOWER, stream->Write32(HDAC_STREAM_BUFFERS_BASE_LOWER,
stream->physical_buffer_descriptors); stream->physical_buffer_descriptors);