Пример #1
0
/*
 * This is called at different times to WriteAudioStream. Always seems to write 512 bytes
*/
static int blockingIOCallback( void *inputBuffer, void *outputBuffer,  unsigned long framesPerBuffer,  PaTimestamp outTime, void *userData )
//#endif
{
    PABLIO_Stream *data = (PABLIO_Stream*)userData;
    (void) outTime;

    /* This may get called with NULL inputBuffer during initial setup. */
    if( inputBuffer != NULL )
    {
		// printf("s_audio_pablio.c: WriteAudioStream. blockingIOCallback %i \n", (data->inbytesPerFrame * framesPerBuffer) );
        RingBuffer_Write( &data->inFIFO, inputBuffer, data->inbytesPerFrame * framesPerBuffer );
    }
    if( outputBuffer != NULL )
    {
        int i;
        int numBytes = data->outbytesPerFrame * framesPerBuffer;
        int numRead = RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes);
        /* Zero out remainder of buffer if we run out of data. */
        for( i=numRead; i<numBytes; i++ )
        {
            ((char *)outputBuffer)[i] = 0;
        }
    }
    return 0;
}
Пример #2
0
uint8_t UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t len) {
  if(HAL_UART_Transmit_IT(huart, pData, len) != HAL_OK) {
    if(RingBuffer_Write(&txBuf, pData, len) != RING_BUFFER_OK)
      return 0;
  }
  return 1;
}
Пример #3
0
/*
 * this is the BlioCallback function. It expects to recieve a PaMacBlio Object
 * pointer as userData.
 *
 */
int BlioCallback( const void *input, void *output, unsigned long frameCount,
	const PaStreamCallbackTimeInfo* timeInfo,
        PaStreamCallbackFlags statusFlags,
        void *userData )
{
   PaMacBlio *blio = (PaMacBlio*)userData;
   long avail;
   long toRead;
   long toWrite;

   /* set flags returned by OS: */
   OSAtomicOr32( statusFlags, &blio->statusFlags ) ;

   /* --- Handle Input Buffer --- */
   if( blio->inChan ) {
      avail = RingBuffer_GetWriteAvailable( &blio->inputRingBuffer );

      /* check for underflow */
      if( avail < frameCount * blio->inputSampleSize * blio->inChan )
         OSAtomicOr32( paInputOverflow, &blio->statusFlags );

      toRead = MIN( avail, frameCount * blio->inputSampleSize * blio->inChan );

      /* copy the data */
      /*printf( "reading %d\n", toRead );*/
      assert( toRead == RingBuffer_Write( &blio->inputRingBuffer, input, toRead ) );
#ifdef PA_MAC__BLIO_MUTEX
      /* Priority inversion. See notes below. */
      blioSetIsInputEmpty( blio, false );
#endif
   }


   /* --- Handle Output Buffer --- */
   if( blio->outChan ) {
      avail = RingBuffer_GetReadAvailable( &blio->outputRingBuffer );

      /* check for underflow */
      if( avail < frameCount * blio->outputSampleSize * blio->outChan )
         OSAtomicOr32( paOutputUnderflow, &blio->statusFlags );

      toWrite = MIN( avail, frameCount * blio->outputSampleSize * blio->outChan );

      if( toWrite != frameCount * blio->outputSampleSize * blio->outChan )
         bzero( ((char *)output)+toWrite,
                frameCount * blio->outputSampleSize * blio->outChan - toWrite );
      /* copy the data */
      /*printf( "writing %d\n", toWrite );*/
      assert( toWrite == RingBuffer_Read( &blio->outputRingBuffer, output, toWrite ) );
#ifdef PA_MAC__BLIO_MUTEX
      /* We have a priority inversion here. However, we will only have to
         wait if this was true and is now false, which means we've got
         some room in the buffer.
         Hopefully problems will be minimized. */
      blioSetIsOutputFull( blio, false );
#endif
   }

   return paContinue;
}
Пример #4
0
TEST(ringbuffer, aaa) {

    unsigned int len;
    unsigned char buf1[20];
    unsigned char buf2[20];

    (void)memset(buf2, 0x28, sizeof(buf2));

    RingBuffer_Clear(&forTest);
    TEST_ASSERT_EQUAL(TEST_RINGBUFFER_SIZE, RingBuffer_LeftSpace(&forTest));
    TEST_ASSERT_EQUAL(56, RingBuffer_PutData(&forTest, 0x28, 56));
    TEST_ASSERT_EQUAL(TEST_RINGBUFFER_SIZE - 56, RingBuffer_LeftSpace(&forTest));

    for (len = 0; len < 56; ) {
        int read = 56 - len;
        read = read > sizeof(buf1) ? sizeof(buf1) : read;
        TEST_ASSERT_EQUAL(read, RingBuffer_Read(&forTest, buf1, read));
        TEST_ASSERT_EQUAL_UINT8_ARRAY(buf1, buf2, read);
        //TEST_ASSERT_EQUAL_UINT8_ARRAY(buf1, "Hello world!!!", read);
        len += read;
    }


    (void)strcpy(buf1, "Hello world\n");
    TEST_ASSERT_EQUAL(strlen(buf1) + 1, RingBuffer_Write(&forTest, buf1, strlen(buf1) + 1));
    TEST_ASSERT_EQUAL(strlen(buf1) + 1, RingBuffer_PopString(&forTest, buf2, sizeof(buf2)));
    TEST_ASSERT_EQUAL_STRING(buf1, buf2);



    (void)strcpy(buf1, "Hello world\n");
    len = sizeof(buf2);
    TEST_ASSERT_EQUAL(strlen(buf1), RingBuffer_Write(&forTest, buf1, strlen(buf1)));
    TEST_ASSERT(RingBuffer_PopStringIsStartWith(&forTest, "Hello", buf2, &len));
    TEST_ASSERT_EQUAL(strlen(buf1), len);
    TEST_ASSERT_EQUAL_STRING(buf1, buf2);

    (void)strcpy(buf1, "Hello world\n");
    len = sizeof(buf2);
    TEST_ASSERT_EQUAL(strlen(buf1), RingBuffer_Write(&forTest, buf1, strlen(buf1)));
    TEST_ASSERT_FALSE(RingBuffer_PopStringIsStartWith(&forTest, "world", buf2, &len));
    TEST_ASSERT_EQUAL(strlen(buf1), len);
    TEST_ASSERT_EQUAL_STRING(buf1, buf2);
}
Пример #5
0
//-----------------------------------------------------------------------------------------
void JackVST::processReplacing (float **inputs, float **outputs, long sampleFrames)
{	
    if(fStatus == kIsOn) {
		for(int i = 0; i < fOutPortsNum;i++) {
			RingBuffer_Write(&fRingBufferOut[i],inputs[i],sizeof(float)*sampleFrames);
		}
		for(int i = 0; i < fInPortsNum;i++) {
			RingBuffer_Read(&fRingBufferIn[i],outputs[i],sizeof(float)*sampleFrames);
		}
    }
}
Пример #6
0
/************************************************************
 * Write data to ring buffer.
 * Will not return until all the data has been written.
 */
long WriteAudioStream( PASTREAMIO_Stream *aStream, void *data, long numFrames )
{
    long bytesWritten;
    char *p = (char *) data;
    long numBytes = aStream->bytesPerFrame * numFrames;
    while( numBytes > 0)
    {
        bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes );
        numBytes -= bytesWritten;
        p += bytesWritten;
        if( numBytes > 0) Pa_Sleep(10);
    }
    return numFrames;
}
Пример #7
0
/*
 * This is called at different times to blockingIOCallback. Always seems to write 512 bytes
*/
long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
{
    long bytesWritten;
    char *p = (char *) data;
    long numBytes = aStream->outbytesPerFrame * numFrames;
	// printf("s_audio_pablio.c: WriteAudioStream. writing %i \n", numBytes );
    while( numBytes > 0)
    {
        bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes );
        numBytes -= bytesWritten;
        p += bytesWritten;
        if( numBytes > 0) NPa_Sleep(10); /* MSP */
    }
    return numFrames;
}
Пример #8
0
//-----------------------------------------------------------------------------------------
int JackVST::JackProcess(jack_nframes_t nframes, void *arg) 
{
	list<JackVST*>::iterator it;
	
	for(it = JackVST::fPlugInList.begin(); it != JackVST::fPlugInList.end(); ++it) {
		JackVST *c = *it;
		if (c->fStatus == kIsOn) {
			for(int i = 0; i < c->fInPortsNum; i++) {
				RingBuffer_Write(&c->fRingBufferIn[i],jack_port_get_buffer(c->fInPorts[i],nframes),nframes*sizeof(float));
			}
			for(int i = 0; i < c->fOutPortsNum; i++) {
				RingBuffer_Read(&c->fRingBufferOut[i],jack_port_get_buffer(c->fOutPorts[i],nframes),nframes*sizeof(float));
			}
		}
	}
	
	return 0;
}
Пример #9
0
Файл: device.c Проект: iXit/wine
static DWORD CALLBACK hid_device_thread(void *args)
{
    DEVICE_OBJECT *device = (DEVICE_OBJECT*)args;

    IRP *irp;
    IO_STATUS_BLOCK irp_status;
    HID_XFER_PACKET *packet;
    DWORD rc;
    HANDLE events[2];
    NTSTATUS ntrc;

    BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
    events[0] = CreateEventA(NULL, TRUE, FALSE, NULL);
    events[1] = ext->halt_event;

    packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength);
    packet->reportBuffer = (BYTE *)packet + sizeof(*packet);

    if (ext->information.Polled)
    {
        while(1)
        {
            ResetEvent(events[0]);

            packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength;
            packet->reportId = 0;

            irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_INPUT_REPORT,
                device, NULL, 0, packet, sizeof(*packet), TRUE, NULL,
                &irp_status);

            IoSetCompletionRoutine(irp, read_Completion, events[0], TRUE, TRUE, TRUE);
            ntrc = IoCallDriver(device, irp);

            if (ntrc == STATUS_PENDING)
                WaitForMultipleObjects(2, events, FALSE, INFINITE);

            if (irp->IoStatus.u.Status == STATUS_SUCCESS)
            {
                RingBuffer_Write(ext->ring_buffer, packet);
                HID_Device_processQueue(device);
            }

            IoCompleteRequest(irp, IO_NO_INCREMENT );

            rc = WaitForSingleObject(ext->halt_event, ext->poll_interval ? ext->poll_interval : DEFAULT_POLL_INTERVAL);

            if (rc == WAIT_OBJECT_0)
                break;
            else if (rc != WAIT_TIMEOUT)
                ERR("Wait returned unexpected value %x\n",rc);
        }
    }
    else
    {
        INT exit_now = FALSE;

        while(1)
        {
            ResetEvent(events[0]);

            irp = IoBuildDeviceIoControlRequest(IOCTL_HID_READ_REPORT,
                device, NULL, 0, packet->reportBuffer,
                ext->preparseData->caps.InputReportByteLength, TRUE, NULL,
                &irp_status);

            IoSetCompletionRoutine(irp, read_Completion, events[0], TRUE, TRUE, TRUE);
            ntrc = IoCallDriver(device, irp);

            if (ntrc == STATUS_PENDING)
            {
                WaitForMultipleObjects(2, events, FALSE, INFINITE);
            }

            rc = WaitForSingleObject(ext->halt_event, 0);
            if (rc == WAIT_OBJECT_0)
                exit_now = TRUE;

            if (!exit_now && irp->IoStatus.u.Status == STATUS_SUCCESS)
            {
                packet->reportBufferLen = irp->IoStatus.Information;
                if (ext->preparseData->InputReports[0].reportID)
                    packet->reportId = packet->reportBuffer[0];
                else
                    packet->reportId = 0;
                RingBuffer_Write(ext->ring_buffer, packet);
                HID_Device_processQueue(device);
            }

            IoCompleteRequest(irp, IO_NO_INCREMENT );

            if (exit_now)
                break;
        }
    }

    /* FIXME: releasing packet requires IRP cancellation support */
    CloseHandle(events[0]);

    TRACE("Device thread exiting\n");
    return 1;
}
Пример #10
0
static DWORD CALLBACK hid_device_thread(void *args)
{
    DEVICE_OBJECT *device = (DEVICE_OBJECT*)args;

    IRP *irp;
    IO_STATUS_BLOCK irp_status;
    IO_STACK_LOCATION *irpsp;
    DWORD rc;
    HANDLE events[2];
    NTSTATUS ntrc;

    BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
    events[0] = CreateEventA(NULL, TRUE, FALSE, NULL);
    events[1] = ext->halt_event;

    if (ext->information.Polled)
    {
        while(1)
        {
            HID_XFER_PACKET *packet;
            ResetEvent(events[0]);

            packet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength);
            packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength;
            packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet);
            packet->reportId = 0;

            irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_INPUT_REPORT,
                device, NULL, 0, packet, sizeof(*packet), TRUE, events[0],
                &irp_status);

            irpsp = IoGetNextIrpStackLocation(irp);
            irpsp->CompletionRoutine = read_Completion;
            irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;

            ntrc = IoCallDriver(device, irp);

            if (ntrc == STATUS_PENDING)
                WaitForMultipleObjects(2, events, FALSE, INFINITE);

            if (irp->IoStatus.u.Status == STATUS_SUCCESS)
            {
                RingBuffer_Write(ext->ring_buffer, packet);
                HID_Device_processQueue(device);
            }

            IoCompleteRequest(irp, IO_NO_INCREMENT );

            rc = WaitForSingleObject(ext->halt_event, ext->poll_interval);

            if (rc == WAIT_OBJECT_0)
                break;
            else if (rc != WAIT_TIMEOUT)
                ERR("Wait returned unexpected value %x\n",rc);
        }
    }
    else
    {
        INT exit_now = FALSE;

        HID_XFER_PACKET *packet;
        packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength);
        packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength;
        packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet);
        packet->reportId = 0;

        while(1)
        {
            BYTE *buffer;

            buffer = HeapAlloc(GetProcessHeap(), 0, ext->preparseData->caps.InputReportByteLength);

            ResetEvent(events[0]);

            irp = IoBuildDeviceIoControlRequest(IOCTL_HID_READ_REPORT,
                device, NULL, 0, buffer,
                ext->preparseData->caps.InputReportByteLength, TRUE, events[0],
                &irp_status);

            irpsp = IoGetNextIrpStackLocation(irp);
            irpsp->CompletionRoutine = read_Completion;
            irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;

            ntrc = IoCallDriver(device, irp);

            if (ntrc == STATUS_PENDING)
            {
                WaitForMultipleObjects(2, events, FALSE, INFINITE);
            }

            rc = WaitForSingleObject(ext->halt_event, 0);
            if (rc == WAIT_OBJECT_0)
                exit_now = TRUE;

            if (!exit_now && irp->IoStatus.u.Status == STATUS_SUCCESS)
            {
                packet->reportId = buffer[0];
                memcpy(packet->reportBuffer, buffer, ext->preparseData->caps.InputReportByteLength);
                RingBuffer_Write(ext->ring_buffer, packet);
                HID_Device_processQueue(device);
            }

            IoCompleteRequest(irp, IO_NO_INCREMENT );

            if (exit_now)
                break;
        }

        HeapFree(GetProcessHeap(), 0, packet);
    }

    CloseHandle(events[0]);

    TRACE("Device thread exiting\n");
    return 1;
}
Пример #11
0
PaError WriteStream( PaStream* stream,
                            const void *buffer,
                            unsigned long frames )
{
    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
    char *cbuf = (char *) buffer;
    PaError ret = paNoError;
    VVDBUG(("WriteStream()\n"));

    while( frames > 0 ) {
       long avail = 0;
       long toWrite;

       do {
          avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer );
/*
          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
                  avail, blio->outputRingBuffer.bufferSize );
*/
          if( avail == 0 ) {
#ifdef PA_MAC_BLIO_MUTEX
             /*block while full*/
             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
             if( ret )
                return ret;
             while( blio->isOutputFull ) {
                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
                if( ret )
                   return ret;
             }
             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
             if( ret )
                return ret;
#else
             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
#endif
          }
       } while( avail == 0 );

       toWrite = MIN( avail, frames * blio->outputSampleSize * blio->outChan );
       toWrite -= toWrite % blio->outputSampleSize * blio->outChan ;
       RingBuffer_Write( &blio->outputRingBuffer, (void *)cbuf, toWrite );
       cbuf += toWrite;
       frames -= toWrite / ( blio->outputSampleSize * blio->outChan );

#ifdef PA_MAC_BLIO_MUTEX
       if( toWrite == avail ) {
          /* we just filled up the buffer, so we need to mark it as filled. */
          ret = blioSetIsOutputFull( blio, true );
          if( ret )
             return ret;
          /* of course, in the meantime, we may have emptied the buffer, so
             so check for that, too, to avoid a race condition. */
          if( RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ) ) {
             blioSetIsOutputFull( blio, false );
             if( ret )
                return ret;
          }
       }
#endif
    }

    /*   Report either paNoError or paOutputUnderflowed. */
    /*   may also want to report other errors, but this is non-standard. */
    ret = blio->statusFlags & paOutputUnderflow;

    /* report underflow only once: */
    if( ret ) {
      OSAtomicAnd32( ~paOutputUnderflow, &blio->statusFlags );
      ret = paOutputUnderflowed;
    }

    return ret;
}