[haiku-commits] r35183 - haiku/branches/developer/siarzhuk/usb_audio

  • From: zharik@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 19 Jan 2010 22:08:52 +0100 (CET)

Author: siarzhuk
Date: 2010-01-19 22:08:52 +0100 (Tue, 19 Jan 2010)
New Revision: 35183
Changeset: http://dev.haiku-os.org/changeset/35183/haiku

Modified:
   haiku/branches/developer/siarzhuk/usb_audio/Device.cpp
   haiku/branches/developer/siarzhuk/usb_audio/Device.h
   haiku/branches/developer/siarzhuk/usb_audio/Stream.cpp
   haiku/branches/developer/siarzhuk/usb_audio/Stream.h
Log:
- draft implementation of the buffer exchnage;
- multi buffer force stop handler added;
- cleanup.


Modified: haiku/branches/developer/siarzhuk/usb_audio/Device.cpp
===================================================================
--- haiku/branches/developer/siarzhuk/usb_audio/Device.cpp      2010-01-19 
20:45:20 UTC (rev 35182)
+++ haiku/branches/developer/siarzhuk/usb_audio/Device.cpp      2010-01-19 
21:08:52 UTC (rev 35183)
@@ -28,7 +28,8 @@
                fNotifyReadSem(-1), 
                fNotifyWriteSem(-1), 
                fNotifyBuffer(NULL),
-               fNotifyBufferLength(0)
+               fNotifyBufferLength(0),
+               fBuffersReadySem(-1)
 { 
        const usb_device_descriptor
                        *deviceDescriptor = 
gUSBModule->get_device_descriptor(device);
@@ -55,6 +56,12 @@
                return;
        }
 
+       fBuffersReadySem = create_sem(0, DRIVER_NAME "_buffers_ready");
+       if (fBuffersReadySem < B_OK) {
+               TRACE_ALWAYS("Error of creating ready buffers 
semaphore:%#010x\n", 
+                                                                               
                                        fBuffersReadySem);
+               return;
+       }
 
        if (_SetupEndpoints() != B_OK) {
                return;
@@ -94,6 +101,9 @@
        if (fNotifyWriteSem >= B_OK)
                delete_sem(fNotifyWriteSem);
        
+       if(fBuffersReadySem > B_OK)
+               delete_sem(fBuffersReadySem);
+       
 //     if (!fRemoved) //???
 //             gUSBModule->cancel_queued_transfers(fNotifyEndpoint);
 
@@ -249,8 +259,7 @@
                        return _MultiBufferExchange((multi_buffer_info*)buffer);
 
                case B_MULTI_BUFFER_FORCE_STOP:         /* force stop of 
playback, nothing in data */
-                       TRACE(("B_MULTI_BUFFER_FORCE_STOP\n"));
-                       return B_ERROR;
+                       return _MultiBufferForceStop();
 
                default:
                        TRACE_ALWAYS("Unhandled IOCTL catched: %#010x\n", op);
@@ -556,7 +565,30 @@
                }
        }
 
-       snooze(1000000);
+       status_t status = B_ERROR;
+       bool anyBufferProcessed = false;
+       for(int i = 0; i < fStreams.Count() && !anyBufferProcessed; i++) {
+               status = acquire_sem_etc(fBuffersReadySem, 1, 
+                                                       B_RELATIVE_TIMEOUT | 
B_CAN_INTERRUPT, 50000);
+               if(status == B_TIMED_OUT) {
+                       TRACE_ALWAYS("Timeout during buffers exchange.\n");
+                       break;
+               }
+
+           anyBufferProcessed = fStreams[i]->ExchangeBuffer(Info);
+               status = anyBufferProcessed ? B_OK : B_ERROR;
+       }
+
+       return status;
+}
+
+
+status_t
+Device::_MultiBufferForceStop()
+{
+       for(int i = 0; i < fStreams.Count(); i++) {
+               fStreams[i]->Stop();
+       }
        return B_OK;
 }
 

Modified: haiku/branches/developer/siarzhuk/usb_audio/Device.h
===================================================================
--- haiku/branches/developer/siarzhuk/usb_audio/Device.h        2010-01-19 
20:45:20 UTC (rev 35182)
+++ haiku/branches/developer/siarzhuk/usb_audio/Device.h        2010-01-19 
21:08:52 UTC (rev 35183)
@@ -26,6 +26,7 @@
                class           FeatureUnit;
 class Device {
                friend          class           FeatureUnit;
+               friend          class           Stream;
 
 public:
                                                        Device(usb_device 
device);
@@ -118,6 +119,7 @@
                status_t                        
_MultiSetMix(multi_mix_value_info *Info);
                status_t                        
_MultiListMixControls(multi_mix_control_info* Info);
                status_t                        
_MultiBufferExchange(multi_buffer_info* Info);
+               status_t                        _MultiBufferForceStop();
 
                // interface and device infos
 //             uint16                          fFrameSize;
@@ -138,6 +140,7 @@
                uint8 *                         fNotifyBuffer;
                uint32                          fNotifyBufferLength;
 
+               sem_id                          fBuffersReadySem;
                // MII bus handler
 //             MIIBus                          fMII;
 

Modified: haiku/branches/developer/siarzhuk/usb_audio/Stream.cpp
===================================================================
--- haiku/branches/developer/siarzhuk/usb_audio/Stream.cpp      2010-01-19 
20:45:20 UTC (rev 35182)
+++ haiku/branches/developer/siarzhuk/usb_audio/Stream.cpp      2010-01-19 
21:08:52 UTC (rev 35183)
@@ -22,7 +22,8 @@
                fDescriptorsCount(0),
                fCurrentBuffer(0),
                fStartingFrame(0),
-               fSamplesCount(0)/*,
+               fSamplesCount(0),
+               fProcessedBuffers(0)/*,
                fBuffersPhysAddress(0)/ *,
                fRealTime(0),
                fFramesCount(0),
@@ -205,8 +206,10 @@
 {
        status_t result = B_BUSY;
        if(!fIsRunning) {
-               if(!fIsInput)
-                       result = _QueueNextTransfer();
+               if(!fIsInput) {
+                       for(size_t i = 0; i < kSamplesBufferCount; i++)
+                               result = _QueueNextTransfer(i);
+               }
                else
                        result = B_OK;
                fIsRunning = result == B_OK;
@@ -228,7 +231,7 @@
 
 
 status_t       
-Stream::_QueueNextTransfer()
+Stream::_QueueNextTransfer(size_t queuedBuffer)
 {
        TypeIFormatDescriptor* format = 
                
static_cast<TypeIFormatDescriptor*>(fAlternates[fActiveAlternate]->Format());
@@ -241,12 +244,12 @@
        size_t packetsCount = fDescriptorsCount / kSamplesBufferCount;
        
        TRACE("buffers:%#010x[%#x]\ndescrs:%#010x[%#x]\n", 
-                       buffers + bufferSize * fCurrentBuffer, bufferSize, 
-                       fDescriptors + fCurrentBuffer * packetsCount, 
packetsCount);
+                       buffers + bufferSize * queuedBuffer, bufferSize, 
+                       fDescriptors + queuedBuffer * packetsCount, 
packetsCount);
 
        return gUSBModule->queue_isochronous(fStreamEndpoint, 
-                       buffers + bufferSize * fCurrentBuffer, bufferSize, 
-                       fDescriptors + fCurrentBuffer * packetsCount, 
packetsCount, 
+                       buffers + bufferSize * queuedBuffer, bufferSize, 
+                       fDescriptors + queuedBuffer * packetsCount, 
packetsCount, 
                        NULL/*&fStartingFrame*/, 0, Stream::_TransferCallback, 
this);
 
        return B_OK;
@@ -258,22 +261,23 @@
        uint32 actualLength)
 {
        Stream *stream = (Stream *)cookie;
-
+/*
        stream->fCurrentBuffer++;
        if(stream->fCurrentBuffer >= kSamplesBufferCount) {
                stream->fCurrentBuffer = 0;
        }
+*/
+       
+       status_t result = stream->_QueueNextTransfer(stream->fCurrentBuffer);
+       
+       if(atomic_add(&stream->fProcessedBuffers, 1) > 
(int32)kSamplesBufferCount) {
+               TRACE_ALWAYS("Processed buffers overflow:%d\n", 
stream->fProcessedBuffers);
+       }
 
-       status_t result = stream->_QueueNextTransfer();
+       release_sem_etc(stream->fDevice->fBuffersReadySem, 1, 
B_DO_NOT_RESCHEDULE);
 
        TRACE_ALWAYS("st:%#010x, len:%d -> %#010x\n", status, actualLength, 
result);
-/*
-       atomic_add(&device->fInsideNotify, 1);
-       if (status == B_CANCELED || device->fRemoved) {
-               atomic_add(&device->fInsideNotify, -1);
-               return;
-       }
-*/
+
 /*     if (status != B_OK) {
                TRACE_ALWAYS("Device status error:%#010x\n", status);
                status_t result = 
gUSBModule->clear_feature(device->fControLeNDPOint,
@@ -282,14 +286,6 @@
                        TRACE_ALWAYS("Error during clearing of HALT 
state:%#010x.\n", result);
        }
 */     
-       // parse data in overriden class
-//     device->OnNotify(actualLength);
-
-       // schedule next notification buffer
-//     gUSBModule->queue_interrupt(device->fNotifyEndpoint, 
device->fNotifyBuffer,
-//             device->fNotifyBufferLength, _NotifyCallback, device);
-
-//     atomic_add(&device->fInsideNotify, -1);
 }
 
 
@@ -457,92 +453,27 @@
        return B_HANDLED_INTERRUPT;
 }
 
-
-void
-Stream::ExchangeBuffers(bigtime_t& RealTime, 
-                                                               bigtime_t& 
FramesCount, int32& BufferCycle)
+*/
+bool
+Stream::ExchangeBuffer(multi_buffer_info* Info)
 {
-       RealTime = fRealTime;
-       FramesCount = fFramesCount;
-       BufferCycle = fBufferCycle;
-}
-
-
-RecordStream::RecordStream(Device* device, uint32 HWChannel) : Stream(device, 
true, HWChannel)
-{
-}
-
-RecordStream::~RecordStream()
-{
-}
-
-       
-status_t
-RecordStream::Start()
-{
-       uint32 ESO = ((fBufferSize * 2) - 1) & 0xffff;
-       uint32 Delta = ((48000 << 12) / 48000) & 0xffff;
-       uint32 FMControl = 0x03;
-//     uint32 ReverbVolume = 0x7f;
-//     uint32 ChorusVolume = 0x7f;
-       uint32 Control = 0x0f; // 16.bit, stereo, signed, loop enabled
-//     uint32 ChannelVolume = fIsInput ? 0xff : 0x00;
-       uint32 Rec = 0x8880;
-
-       uint32 ChannelRegs[5] = {0};
-
-       // CSO, Sample interpolation coefficient and FMS
-       ChannelRegs[0] = 0;
-       // Loop Begin Address
-       ChannelRegs[1] = uint32(fBuffersPhysAddress) & 0x3fffffff;
-       // ESO & Delta Sample Rate Ratio
-       ChannelRegs[2] = Delta | (ESO << 16);
-       // FM control, Reverb and Chorus Volume
-       ChannelRegs[3] = (Rec << 16) / *| (FMControl << 14)/ * | (ReverbVolume 
<< 7) | ChorusVolume* /;
-       // GVSEL, PAN. VOL. Control and curr. Envelope
-       ChannelRegs[4] = / *(ChannelVolume << 16) |* / (Control << 12)/ * | 
0x80000000* /;
-
-       TRACE("ChannelRegs:%#010x %#010x %#010x %#010x %#010x\n", 
-                       ChannelRegs[0], ChannelRegs[1], ChannelRegs[2], 
-                                                       ChannelRegs[3], 
ChannelRegs[4]);
-
-uint32 CIRs[3] = {0};  
-       cpu_status cst = fDevice->Lock();
-
-       // select current channel
-       uint32 CIR = fDevice->ReadPCI32(TrChIndexReg);
-       CIRs[0] = CIR;
-       CIR = fDevice->ReadPCI32(TrChIndexReg) & ~0x3f;
-       CIRs[1] = CIR;
-       CIR |= (fHWChannel + 32) & 0x3f; // we use Bank B for PCM!
-       CIRs[2] = CIR;
-       fDevice->WritePCI32(TrChIndexReg, CIR);
-               
-       // write registers...
-       for(size_t i = 0; i < _countof(ChannelRegs); i++) {
-               fDevice->WritePCI32(0xe0 + i * 4, ChannelRegs[i]);
+       if(fProcessedBuffers <= 0) {
+               // looks like somebody else has processed buffers but this 
stream
+               release_sem_etc(fDevice->fBuffersReadySem, 1, 
B_DO_NOT_RESCHEDULE);
+               return false;
        }
 
-///    fDevice->WritePCI32(0xa8, 0x0000);
-       fDevice->WritePCI32(0xf4, 0x0000);
-       fDevice->WritePCI32(0xf8, 0x0000);
+       Info->played_real_time = system_time();//TODO fRealTime;
+       Info->played_frames_count += fSamplesCount / kSamplesBufferCount;
+       Info->playback_buffer_cycle = fCurrentBuffer;
 
-       // enable INT for current channel
-       uint32 ChIntMask = fDevice->ReadPCI32(TrEnableINTBReg);
-       ChIntMask |= 1 << fHWChannel;
-       fDevice->WritePCI32(TrAddressINTBReg, 1 << fHWChannel); // clear INT 
for current channel
-       fDevice->WritePCI32(TrEnableINTBReg, ChIntMask); // enable it
+       fCurrentBuffer++;
+       fCurrentBuffer %= kSamplesBufferCount;
 
-       // start current channel
-       fDevice->WritePCI32(TrStartBReg, 1 << fHWChannel);      
+       atomic_add(&fProcessedBuffers, -1);
 
-       fDevice->Unlock(cst);
-       
-TRACE("Rec:CIRS:%#010x %#010x %#010x \n", CIRs[0], CIRs[1], CIRs[2]);
-
-       return B_OK;
+       return true;
 }
-*/
 
 /*
 ASInterfaceDescriptor* 

Modified: haiku/branches/developer/siarzhuk/usb_audio/Stream.h
===================================================================
--- haiku/branches/developer/siarzhuk/usb_audio/Stream.h        2010-01-19 
20:45:20 UTC (rev 35182)
+++ haiku/branches/developer/siarzhuk/usb_audio/Stream.h        2010-01-19 
21:08:52 UTC (rev 35183)
@@ -38,11 +38,8 @@
                status_t                        OnSetConfiguration(usb_device 
device, 
                                                                const 
usb_configuration_info *config);
 
+               bool                            
ExchangeBuffer(multi_buffer_info* Info);
 /*
-               void                            ExchangeBuffers(bigtime_t& 
RealTime, 
-                                                                               
        bigtime_t& FramesCount, 
-                                                                               
        int32& BufferCycle);
-
                int32                           InterruptHandler(uint32 
SignaledChannelsMask);
 */
 //             ASInterfaceDescriptor*  ASInterface();
@@ -71,7 +68,8 @@
                size_t                                          
fDescriptorsCount;
                size_t                          fCurrentBuffer;
                uint32                          fStartingFrame;
-               size_t                                          fSamplesCount;
+               size_t                          fSamplesCount;
+               int32                           fProcessedBuffers;
 //             void*                           fBuffersPhysAddress;
 /*             bigtime_t                       fRealTime;
                bigtime_t                       fFramesCount;
@@ -79,7 +77,7 @@
 public:
                uint32                          fCSP; */
 private:
-               status_t                        _QueueNextTransfer();
+               status_t                        _QueueNextTransfer(size_t 
buffer);
 static void                            _TransferCallback(void *cookie, int32 
status,
                                                                void *data, 
uint32 actualLength);
 };


Other related posts:

  • » [haiku-commits] r35183 - haiku/branches/developer/siarzhuk/usb_audio - zharik