1 /* 2 * Driver for USB Audio Device Class devices. 3 * Copyright (c) 2009-13 S.Zharski <imker@gmx.li> 4 * Distributed under the terms of the MIT license. 5 * 6 */ 7 8 9 #include "Stream.h" 10 11 #include <usb/USB_audio.h> 12 13 #include "Device.h" 14 #include "Driver.h" 15 #include "Settings.h" 16 17 18 Stream::Stream(Device* device, size_t interface, usb_interface_list* List) 19 : 20 AudioStreamingInterface(&device->AudioControl(), interface, List), 21 fDevice(device), 22 fStatus(B_NO_INIT), 23 fStreamEndpoint(0), 24 fIsRunning(false), 25 fArea(-1), 26 fAreaSize(0), 27 fDescriptors(NULL), 28 fDescriptorsCount(0), 29 fCurrentBuffer(0), 30 fStartingFrame(0), 31 fSamplesCount(0), 32 fPacketSize(0), 33 fProcessedBuffers(0), 34 fInsideNotify(0) 35 { 36 } 37 38 39 Stream::~Stream() 40 { 41 delete_area(fArea); 42 } 43 44 45 status_t 46 Stream::_ChooseAlternate() 47 { 48 // lookup alternate with maximal (ch * 100 + resolution) 49 uint16 maxChxRes = 0; 50 for (int i = 0; i < fAlternates.Count(); i++) { 51 if (fAlternates[i]->Interface() == 0) { 52 TRACE(INF, "Ignore alternate %d - zero interface description.\n", i); 53 continue; 54 } 55 56 if (fAlternates[i]->Format() == 0) { 57 TRACE(INF, "Ignore alternate %d - zero format description.\n", i); 58 continue; 59 } 60 61 if (fAlternates[i]->Format()->fFormatType 62 != USB_AUDIO_FORMAT_TYPE_I) { 63 TRACE(ERR, "Ignore alternate %d - format type %#02x " 64 "is not supported.\n", i, fAlternates[i]->Format()->fFormatType); 65 continue; 66 } 67 68 switch (fAlternates[i]->Interface()->fFormatTag) { 69 case USB_AUDIO_FORMAT_PCM: 70 case USB_AUDIO_FORMAT_PCM8: 71 case USB_AUDIO_FORMAT_IEEE_FLOAT: 72 // case USB_AUDIO_FORMAT_ALAW: 73 // case USB_AUDIO_FORMAT_MULAW: 74 break; 75 default: 76 TRACE(ERR, "Ignore alternate %d - format %#04x is not " 77 "supported.\n", i, fAlternates[i]->Interface()->fFormatTag); 78 continue; 79 } 80 81 TypeIFormatDescriptor* format 82 = static_cast<TypeIFormatDescriptor*>(fAlternates[i]->Format()); 83 84 if (format->fNumChannels > 2) { 85 TRACE(ERR, "Ignore alternate %d - channel count %d " 86 "is not supported.\n", i, format->fNumChannels); 87 continue; 88 } 89 90 if (fAlternates[i]->Interface()->fFormatTag == USB_AUDIO_FORMAT_PCM) { 91 switch(format->fBitResolution) { 92 default: 93 TRACE(ERR, "Ignore alternate %d - bit resolution %d " 94 "is not supported.\n", i, format->fBitResolution); 95 continue; 96 case 8: case 16: case 18: case 20: case 24: case 32: 97 break; 98 } 99 } 100 101 uint16 chxRes = format->fNumChannels * 100 + format->fBitResolution; 102 if (chxRes > maxChxRes) { 103 maxChxRes = chxRes; 104 fActiveAlternate = i; 105 } 106 } 107 108 if (maxChxRes <= 0) { 109 TRACE(ERR, "No compatible alternate found. " 110 "Stream initialization failed.\n"); 111 return B_NO_INIT; 112 } 113 114 const ASEndpointDescriptor* endpoint 115 = fAlternates[fActiveAlternate]->Endpoint(); 116 fIsInput = (endpoint->fEndpointAddress & USB_ENDPOINT_ADDR_DIR_IN) 117 == USB_ENDPOINT_ADDR_DIR_IN; 118 119 if (fIsInput) 120 fCurrentBuffer = (size_t)-1; 121 122 TRACE(INF, "Alternate %d EP:%x selected for %s!\n", 123 fActiveAlternate, endpoint->fEndpointAddress, 124 fIsInput ? "recording" : "playback"); 125 126 return B_OK; 127 } 128 129 130 status_t 131 Stream::Init() 132 { 133 fStatus = _ChooseAlternate(); 134 return fStatus; 135 } 136 137 138 void 139 Stream::OnRemove() 140 { 141 // the transfer callback schedule traffic - so we must ensure that we are 142 // not inside the callback anymore before returning, as we would otherwise 143 // violate the promise not to use any of the pipes after returning from the 144 // removed callback 145 while (atomic_add(&fInsideNotify, 0) != 0) 146 snooze(100); 147 148 gUSBModule->cancel_queued_transfers(fStreamEndpoint); 149 } 150 151 152 status_t 153 Stream::_SetupBuffers() 154 { 155 // allocate buffer for worst (maximal size) case 156 TypeIFormatDescriptor* format = static_cast<TypeIFormatDescriptor*>( 157 fAlternates[fActiveAlternate]->Format()); 158 159 uint32 samplingRate = fAlternates[fActiveAlternate]->GetSamplingRate(); 160 uint32 sampleSize = format->fNumChannels * format->fSubframeSize; 161 162 // data size pro 1 ms USB 1 frame or 1/8 ms USB 2 microframe 163 fPacketSize = samplingRate * sampleSize 164 / (fDevice->fUSBVersion < 0x0200 ? 1000 : 8000); 165 TRACE(INF, "packetSize:%ld\n", fPacketSize); 166 167 if (fArea == -1) { 168 fAreaSize = (sizeof(usb_iso_packet_descriptor) + fPacketSize) 169 * sampleSize * 1024 / fPacketSize; 170 TRACE(INF, "estimate fAreaSize:%d\n", fAreaSize); 171 172 // round up to B_PAGE_SIZE and create area 173 fAreaSize = (fAreaSize + (B_PAGE_SIZE - 1)) &~ (B_PAGE_SIZE - 1); 174 TRACE(INF, "rounded up fAreaSize:%d\n", fAreaSize); 175 176 fArea = create_area( (fIsInput) ? DRIVER_NAME "_record_area" 177 : DRIVER_NAME "_playback_area", (void**)&fDescriptors, 178 B_ANY_KERNEL_ADDRESS, fAreaSize, B_CONTIGUOUS, 179 B_READ_AREA | B_WRITE_AREA); 180 181 if (fArea < 0) { 182 TRACE(ERR, "Error of creating %#x - " 183 "bytes size buffer area:%#010x\n", fAreaSize, fArea); 184 fStatus = fArea; 185 return fStatus; 186 } 187 188 TRACE(INF, "Created area id:%d at addr:%#010x size:%#010lx\n", 189 fArea, fDescriptors, fAreaSize); 190 } 191 192 // descriptors count 193 fDescriptorsCount = fAreaSize 194 / (sizeof(usb_iso_packet_descriptor) + fPacketSize); 195 196 // we need same size sub-buffers. round it 197 fDescriptorsCount /= kSamplesBufferCount; 198 fDescriptorsCount *= kSamplesBufferCount; 199 TRACE(INF, "descriptorsCount:%d\n", fDescriptorsCount); 200 201 // samples count 202 fSamplesCount = fDescriptorsCount * fPacketSize / sampleSize; 203 TRACE(INF, "samplesCount:%d\n", fSamplesCount); 204 205 // initialize descriptors array 206 for (size_t i = 0; i < fDescriptorsCount; i++) { 207 fDescriptors[i].request_length = fPacketSize; 208 fDescriptors[i].actual_length = 0; 209 fDescriptors[i].status = B_OK; 210 } 211 212 return fStatus; 213 } 214 215 216 status_t 217 Stream::OnSetConfiguration(usb_device device, 218 const usb_configuration_info* config) 219 { 220 if (config == NULL) { 221 TRACE(ERR, "NULL configuration. Not set.\n"); 222 return B_ERROR; 223 } 224 225 usb_interface_info* interface 226 = &config->interface[fInterface].alt[fActiveAlternate]; 227 if (interface == NULL) { 228 TRACE(ERR, "NULL interface. Not set.\n"); 229 return B_ERROR; 230 } 231 232 status_t status = gUSBModule->set_alt_interface(device, interface); 233 uint8 address = fAlternates[fActiveAlternate]->Endpoint()->fEndpointAddress; 234 235 TRACE(INF, "set_alt_interface %x\n", status); 236 237 for (size_t i = 0; i < interface->endpoint_count; i++) { 238 if (address == interface->endpoint[i].descr->endpoint_address) { 239 fStreamEndpoint = interface->endpoint[i].handle; 240 TRACE(INF, "%s Stream Endpoint [address %#04x] handle is: %#010x.\n", 241 fIsInput ? "Input" : "Output", address, fStreamEndpoint); 242 return B_OK; 243 } 244 } 245 246 TRACE(INF, "%s Stream Endpoint [address %#04x] was not found.\n", 247 fIsInput ? "Input" : "Output", address); 248 return B_ERROR; 249 } 250 251 252 status_t 253 Stream::Start() 254 { 255 status_t result = B_BUSY; 256 if (!fIsRunning) { 257 for (size_t i = 0; i < kSamplesBufferCount; i++) 258 result = _QueueNextTransfer(i, true); 259 fIsRunning = result == B_OK; 260 } 261 return result; 262 } 263 264 265 status_t 266 Stream::Stop() 267 { 268 if (fIsRunning) { 269 // wait until possible notification handling finished... 270 while (atomic_add(&fInsideNotify, 0) != 0) 271 snooze(100); 272 gUSBModule->cancel_queued_transfers(fStreamEndpoint); 273 fIsRunning = false; 274 } 275 276 return B_OK; 277 } 278 279 280 status_t 281 Stream::_QueueNextTransfer(size_t queuedBuffer, bool start) 282 { 283 TypeIFormatDescriptor* format = static_cast<TypeIFormatDescriptor*>( 284 fAlternates[fActiveAlternate]->Format()); 285 286 size_t bufferSize = format->fNumChannels * format->fSubframeSize; 287 bufferSize *= fSamplesCount / kSamplesBufferCount; 288 289 uint8* buffers = (uint8*)(fDescriptors + fDescriptorsCount); 290 291 size_t packetsCount = fDescriptorsCount / kSamplesBufferCount; 292 293 TRACE(DTA, "buffers:%#010x[%#x]\ndescrs:%#010x[%#x]\n", 294 buffers + bufferSize * queuedBuffer, bufferSize, 295 fDescriptors + queuedBuffer * packetsCount, packetsCount); 296 297 status_t status = gUSBModule->queue_isochronous(fStreamEndpoint, 298 buffers + bufferSize * queuedBuffer, bufferSize, 299 fDescriptors + queuedBuffer * packetsCount, packetsCount, 300 &fStartingFrame, start ? USB_ISO_ASAP : 0, 301 Stream::_TransferCallback, this); 302 303 TRACE(DTA, "frame:%#010x\n", fStartingFrame); 304 return status; // B_OK; 305 } 306 307 308 void 309 Stream::_TransferCallback(void* cookie, status_t status, void* data, 310 size_t actualLength) 311 { 312 Stream* stream = (Stream*)cookie; 313 atomic_add(&stream->fInsideNotify, 1); 314 if (status == B_CANCELED || stream->fDevice->fRemoved) { 315 atomic_add(&stream->fInsideNotify, -1); 316 TRACE(ERR, "Cancelled: c:%p st:%#010x, data:%#010x, len:%d\n", 317 cookie, status, data, actualLength); 318 return; 319 } 320 321 stream->fCurrentBuffer = (stream->fCurrentBuffer + 1) % kSamplesBufferCount; 322 323 stream->_DumpDescriptors(); 324 325 /*status_t result =*/ stream->_QueueNextTransfer(stream->fCurrentBuffer, false); 326 327 if (atomic_add(&stream->fProcessedBuffers, 1) > (int32)kSamplesBufferCount) 328 TRACE(ERR, "Processed buffers overflow:%d\n", stream->fProcessedBuffers); 329 330 release_sem_etc(stream->fDevice->fBuffersReadySem, 1, B_DO_NOT_RESCHEDULE); 331 332 TRACE(DTA, "st:%#010x, data:%#010x, len:%d\n", status, data, actualLength); 333 334 atomic_add(&stream->fInsideNotify, -1); 335 } 336 337 338 void 339 Stream::_DumpDescriptors() 340 { 341 //size_t packetsCount = fDescriptorsCount / kSamplesBufferCount; 342 size_t from = /*fCurrentBuffer > 0 ? packetsCount :*/ 0 ; 343 size_t to = /*fCurrentBuffer > 0 ?*/ fDescriptorsCount /*: packetsCount*/ ; 344 for (size_t i = from; i < to; i++) 345 TRACE(ISO, "%d:req_len:%d; act_len:%d; stat:%#010x\n", i, 346 fDescriptors[i].request_length, fDescriptors[i].actual_length, 347 fDescriptors[i].status); 348 } 349 350 351 status_t 352 Stream::GetEnabledChannels(uint32& offset, multi_channel_enable* Enable) 353 { 354 AudioChannelCluster* cluster = ChannelCluster(); 355 if (cluster == 0) 356 return B_ERROR; 357 358 for (size_t i = 0; i < cluster->ChannelsCount(); i++) { 359 B_SET_CHANNEL(Enable->enable_bits, offset++, true); 360 TRACE(INF, "Report channel %d as enabled.\n", offset); 361 } 362 363 return B_OK; 364 } 365 366 367 status_t 368 Stream::SetEnabledChannels(uint32& offset, multi_channel_enable* Enable) 369 { 370 AudioChannelCluster* cluster = ChannelCluster(); 371 if (cluster == 0) 372 return B_ERROR; 373 374 for (size_t i = 0; i < cluster->ChannelsCount(); i++, offset++) { 375 TRACE(INF, "%s channel %d.\n", 376 (B_TEST_CHANNEL(Enable->enable_bits, offset) 377 ? "Enable" : "Disable"), offset + 1); 378 } 379 380 return B_OK; 381 } 382 383 384 status_t 385 Stream::GetGlobalFormat(multi_format_info* Format) 386 { 387 _multi_format* format = fIsInput ? &Format->input : &Format->output; 388 format->cvsr = fAlternates[fActiveAlternate]->GetSamplingRate(); 389 format->rate = fAlternates[fActiveAlternate]->GetSamplingRateId(0); 390 format->format = fAlternates[fActiveAlternate]->GetFormatId(); 391 TRACE(INF, "%s.rate:%d cvsr:%f format:%#08x\n", 392 fIsInput ? "input" : "ouput", 393 format->rate, format->cvsr, format->format); 394 return B_OK; 395 } 396 397 398 status_t 399 Stream::SetGlobalFormat(multi_format_info* Format) 400 { 401 _multi_format* format = fIsInput ? &Format->input : &Format->output; 402 AudioStreamAlternate* alternate = fAlternates[fActiveAlternate]; 403 if (format->rate == alternate->GetSamplingRateId(0) 404 && format->format == alternate->GetFormatId()) { 405 TRACE(INF, "No changes required\n"); 406 return B_OK; 407 } 408 409 alternate->SetSamplingRateById(format->rate); 410 alternate->SetFormatId(format->format); 411 TRACE(INF, "%s.rate:%d cvsr:%f format:%#08x\n", 412 fIsInput ? "input" : "ouput", 413 format->rate, format->cvsr, format->format); 414 415 // cancel data flow - it will be rewaked at next buffer exchange call 416 Stop(); 417 418 // TODO: wait for cancelling? 419 420 // layout of buffers should be adjusted after changing sampling rate/format 421 status_t status = _SetupBuffers(); 422 423 if (status != B_OK) 424 return status; 425 426 // set endpoint speed 427 uint32 samplingRate = fAlternates[fActiveAlternate]->GetSamplingRate(); 428 size_t actualLength = 0; 429 usb_audio_sampling_freq freq = _ASFormatDescriptor::GetSamFreq(samplingRate); 430 uint8 address = fAlternates[fActiveAlternate]->Endpoint()->fEndpointAddress; 431 432 status = gUSBModule->send_request(fDevice->fDevice, 433 USB_REQTYPE_CLASS | USB_REQTYPE_ENDPOINT_OUT, 434 USB_AUDIO_SET_CUR, USB_AUDIO_SAMPLING_FREQ_CONTROL << 8, 435 address, sizeof(freq), &freq, &actualLength); 436 437 TRACE(ERR, "set_speed %02x%02x%02x for ep %#x %d: %x\n", 438 freq.bytes[0], freq.bytes[1], freq.bytes[2], 439 address, actualLength, status); 440 return status; 441 } 442 443 444 status_t 445 Stream::GetBuffers(multi_buffer_list* List) 446 { 447 // TODO: check the available buffers count! 448 if (fAreaSize == 0) 449 return B_NO_INIT; 450 451 int32 startChannel = List->return_playback_channels; 452 buffer_desc** Buffers = List->playback_buffers; 453 454 if (fIsInput) { 455 List->flags |= B_MULTI_BUFFER_RECORD; 456 List->return_record_buffer_size = fSamplesCount / kSamplesBufferCount; 457 List->return_record_buffers = kSamplesBufferCount; 458 startChannel = List->return_record_channels; 459 Buffers = List->record_buffers; 460 461 TRACE(DTA, "flags:%#10x\nreturn_record_buffer_size:%#010x\n" 462 "return_record_buffers:%#010x\n", List->flags, 463 List->return_record_buffer_size, List->return_record_buffers); 464 } else { 465 List->flags |= B_MULTI_BUFFER_PLAYBACK; 466 List->return_playback_buffer_size = fSamplesCount / kSamplesBufferCount; 467 List->return_playback_buffers = kSamplesBufferCount; 468 469 TRACE(DTA, "flags:%#10x\nreturn_playback_buffer_size:%#010x\n" 470 "return_playback_buffers:%#010x\n", List->flags, 471 List->return_playback_buffer_size, List->return_playback_buffers); 472 } 473 474 TypeIFormatDescriptor* format = static_cast<TypeIFormatDescriptor*>( 475 fAlternates[fActiveAlternate]->Format()); 476 // const ASEndpointDescriptor* endpoint 477 // = fAlternates[fActiveAlternate]->Endpoint(); 478 479 // [buffer][channel] init buffers 480 for (size_t buffer = 0; buffer < kSamplesBufferCount; buffer++) { 481 TRACE(DTA, "%s buffer #%d:\n", fIsInput ? "input" : "output", buffer + 1); 482 483 for (size_t channel = startChannel; 484 channel < format->fNumChannels; channel++) { 485 // init stride to the same for all buffers 486 uint32 stride = format->fSubframeSize * format->fNumChannels; 487 Buffers[buffer][channel].stride = stride; 488 489 // init to buffers area begin 490 Buffers[buffer][channel].base 491 = (char*)(fDescriptors + fDescriptorsCount); 492 // shift for whole buffer if required 493 size_t bufferSize = fPacketSize/*endpoint->fMaxPacketSize*/ 494 * (fDescriptorsCount / kSamplesBufferCount); 495 Buffers[buffer][channel].base += buffer * bufferSize; 496 // shift for channel if required 497 Buffers[buffer][channel].base += channel * format->fSubframeSize; 498 499 TRACE(DTA, "%d:%d: base:%#010x; stride:%#010x\n", buffer, channel, 500 Buffers[buffer][channel].base, Buffers[buffer][channel].stride); 501 } 502 } 503 504 if (fIsInput) { 505 List->return_record_channels += format->fNumChannels; 506 TRACE(MIX, "return_record_channels:%#010x\n", 507 List->return_record_channels); 508 } else { 509 List->return_playback_channels += format->fNumChannels; 510 TRACE(MIX, "return_playback_channels:%#010x\n", 511 List->return_playback_channels); 512 } 513 514 return B_OK; 515 } 516 517 518 bool 519 Stream::ExchangeBuffer(multi_buffer_info* Info) 520 { 521 if (fProcessedBuffers <= 0) 522 return false; 523 524 if (fIsInput) { 525 Info->recorded_real_time = system_time();// TODO fRealTime; 526 Info->recorded_frames_count += fSamplesCount / kSamplesBufferCount; 527 Info->record_buffer_cycle = fCurrentBuffer; 528 } else { 529 Info->played_real_time = system_time();// TODO fRealTime; 530 Info->played_frames_count += fSamplesCount / kSamplesBufferCount; 531 Info->playback_buffer_cycle = fCurrentBuffer; 532 } 533 534 atomic_add(&fProcessedBuffers, -1); 535 536 return true; 537 } 538 539