示例#1
0
uint32 nuiAiffReader::ReadIN(void* pBuffer, uint32 SampleFrames, nuiSampleBitFormat format)
{
  if (!SampleFrames)
    return 0;
  SetPosition((uint32)mPosition);
  const uint32 channels = mInfo.GetChannels();
  uint32 length = mInfo.GetSampleFrames();
  if (mPosition >= length)
    return 0;
  SampleFrames = MIN(SampleFrames, length - mPosition);
  
  const uint64 SamplePointsToRead = SampleFrames * channels;
  uint32 SampleFramesRead = 0;
  
  switch(format)
  {
    case eSampleInt16 :
    {
      switch (mInfo.GetBitsPerSample())
      {
        case 8 :
        {
          int16* pTempInt16 = (int16*)pBuffer;
          uint32 sizeRead = mrStream.ReadUInt8( ((uint8*)pTempInt16) + SamplePointsToRead , SamplePointsToRead);
          SampleFramesRead = sizeRead / channels;
          nuiAudioConvert_Signed8bitsBufferTo16Bits(pTempInt16, sizeRead);
        }
          break;
          
        case 16 :
        {
          uint32 sizeRead = mrStream.ReadInt16( (int16*)pBuffer, SamplePointsToRead);
          SampleFramesRead = sizeRead / channels;
        }
          break;
          
        case 24 :
        case 32 :
        default:
          SampleFramesRead = 0;
          break;
      }
    }
      break;
      
    case eSampleFloat32 :
    {
      switch ( mInfo.GetBitsPerSample() )
      {
        case 8 :
        {
          float* pTempFloat = (float*)pBuffer;
          uint32 sizeRead = mrStream.ReadUInt8( (uint8*)pTempFloat + 3 * SamplePointsToRead , SamplePointsToRead);
          SampleFramesRead = sizeRead / channels;
          nuiAudioConvert_Signed8bitsBufferToFloat(pTempFloat, sizeRead);
        }
          break;
          
        case 16 :
        {
          float* pTempFloat = (float*)pBuffer;
          uint32 sizeRead = mrStream.ReadInt16( (int16*)pTempFloat + SamplePointsToRead, SamplePointsToRead);
          SampleFramesRead = sizeRead / channels;
          nuiAudioConvert_16bitsBufferToFloat(pTempFloat, SamplePointsToRead);
        }
          break;
          
        case 24 :
        {
          float* pTempFloat = (float*)pBuffer;
          uint8* pTempBuffer;
          pTempBuffer = new uint8[SamplePointsToRead * 3]; //nb of sample points * 3 bytes (24 bits) = nb of bytes to read
          
          uint32 sizeRead = mrStream.ReadUInt8(pTempBuffer, SamplePointsToRead * 3);
          SampleFramesRead = sizeRead / channels / 3;
          for (uint32 i = 0; i < sizeRead / 3; i++)
          {
            pTempFloat[i] = nuiAudioConvert_24bitsToFloatFromBigEndian(pTempBuffer + (3 * i));
          }
          
          delete[] pTempBuffer;
        }
          break;
          
        case 32 :
        {
          uint32 sizeRead = mrStream.ReadFloat((float*)pBuffer, SamplePointsToRead);
          SampleFramesRead = sizeRead / channels;
          mPosition += SampleFramesRead;
        }
          break;
          
        default:
          SampleFramesRead = 0;
          break;
      }
    }
      break;
      
    default :
      SampleFramesRead = 0;
      break;
  }
  
  mPosition += SampleFramesRead;
  return SampleFramesRead;
}
示例#2
0
int32 nuiAudioDecoder::ReadIN(void* pBuffer, int32 sampleframes, nuiSampleBitFormat format)
{
    if (!mInitialized)
        return 0;

    SetPosition(mPosition);

    int32 BitsPerSample  = mInfo.GetBitsPerSample();
    int32 channels       = mInfo.GetChannels();
    int32 frameSize      = channels * (mInfo.GetBitsPerSample() / 8.f);
    int32 outBytes       = sampleframes * frameSize;

    unsigned char* pTemp;
    bool allocated = false;

    if (BitsPerSample != 16 && BitsPerSample != 32)
    {
        NGL_ASSERT(0);
        return 0;
    }
    else if ( ((format == eSampleFloat32) && (BitsPerSample == 32)) || ((format == eSampleInt16) && (BitsPerSample == 16)) )
    {
        pTemp = (unsigned char*)pBuffer;
    }
    else
    {
        pTemp = new unsigned char[outBytes];
        allocated = true;
    }

    unsigned char* pIn = NULL;

    int32 bytesDone = 0;
    int err = MPG123_OK;
    int32 bytesRead = -1;
    while (outBytes && err != MPG123_DONE && bytesRead != 0)
    {
        size_t outBytesDone = 0;
        unsigned char* pOut = pTemp + bytesDone;
        err = mpg123_decode(mpPrivate->mpHandle, NULL, 0, pOut, outBytes, &outBytesDone);
        outBytes  -= outBytesDone;
        bytesDone += outBytesDone;

        if (err == MPG123_NEW_FORMAT)
        {
            long r;
            int c;
            int e;
            mpg123_getformat(mpPrivate->mpHandle, &r, &c, &e);
        }

        // feed decoder if needed
        bytesRead = -1;
        while (err == MPG123_NEED_MORE && bytesRead != 0)
        {
            int32 inBytes = DECODER_INPUT_SIZE;
            if (!pIn)
            {
                pIn = new unsigned char[inBytes];
            }
            bytesRead = mrStream.ReadUInt8(pIn, inBytes);
            err = mpg123_decode(mpPrivate->mpHandle, pIn, bytesRead, NULL, 0, &outBytesDone);
        }

        if (err != MPG123_OK && err != MPG123_DONE)
        {
            NGL_LOG("nuiAudioDecoder", NGL_LOG_INFO, "mpg123 error while decoding: %s", mpg123_strerror(mpPrivate->mpHandle));
        }
    }

    int32 frames = bytesDone / frameSize;

    if (format == eSampleFloat32 && BitsPerSample == 16)
    {
        // convert '16 bits int' samples in pTemp to '32 bits float' samples in pBuffer
        int16* pSrc = (int16*)pTemp;
        float* pCopy  = (float*)( ((int16*)pBuffer) + frames * channels );
        float* pFloat = (float*)pBuffer;

        // copy int16 data to the second half of the output buffer
        // => nuiAudioConvert_16bitsBufferToFloat converts in place
        // 'int16' samples atored in the second half of the buffer are converted in 'float' samples filling all the buffer (sizeof(float) == 2 * sizeof(int16))
        memcpy(pCopy, pSrc, frames * channels * sizeof(int16));

        nuiAudioConvert_16bitsBufferToFloat(pFloat, frames * channels); // convert in place (int16 to float)
    }
    else if (format == eSampleInt16 && BitsPerSample == 32)
    {
        // convert '32 bits float' samples in pTemp to '16 bits int' samples in pBuffer
        float* pFloat = (float*)pTemp;
        int16* pInt16 = (int16*)pBuffer;

        nuiAudioConvert_FloatBufferTo16bits(pFloat, pInt16, frames * channels);
    }

    if (allocated)
    {
        delete[] pTemp;
    }
    if (pIn)
    {
        delete[] pIn;
    }

    mPosition += frames;
    return frames;
}