Ejemplo n.º 1
0
int
md_get_uint16le(struct mdchain *mdp, u_int16_t *x)
{
	u_int16_t v;
	int error = md_get_uint16(mdp, &v);

	*x = letohs(v);
	return error;
}
Ejemplo n.º 2
0
static int
rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
    struct share_info **entries_listp)
{
	int error, bufsize, i, entries, total, nreturned;
	struct smb_share_info_1 *rpbuf, *ep;
	struct share_info *entry_list, *elp;
	char *cp;
	int lbound, rbound;

	bufsize = 0xffe0;	/* samba notes win2k bug for 65535 */
	rpbuf = malloc(bufsize);
	if (rpbuf == NULL)
		return (errno);

	error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &entries, &total);
	if (error &&
	    error != (ERROR_MORE_DATA | SMB_RAP_ERROR)) {
		free(rpbuf);
		return (error);
	}
	entry_list = malloc(entries * sizeof (struct share_info));
	if (entry_list == NULL) {
		error = errno;
		free(rpbuf);
		return (error);
	}
	lbound = entries * (sizeof (struct smb_share_info_1));
	rbound = bufsize;
	for (ep = rpbuf, elp = entry_list, i = 0, nreturned = 0; i < entries;
	    i++, ep++) {
		elp->type = letohs(ep->shi1_type);
		ep->shi1_pad = '\0'; /* ensure null termination */
		elp->netname = convert_wincs_to_utf8(ep->shi1_netname);
		if (elp->netname == NULL)
			continue;	/* punt on this entry */
		/*
		 * Check for validity of offset.
		 */
		if (ep->shi1_remark >= lbound && ep->shi1_remark < rbound) {
			cp = (char *)rpbuf + ep->shi1_remark;
			elp->remark = convert_wincs_to_utf8(cp);
		} else
			elp->remark = NULL;
		elp++;
		nreturned++;
	}
	*entriesp = nreturned;
	*totalp = total;
	*entries_listp = entry_list;
	free(rpbuf);
	return (0);
}
Ejemplo n.º 3
0
void
smb2fs_smb_file_id_check(struct smb_share *share, uint64_t ino,
                         char *network_name, uint32_t network_name_len)
{
    uint32_t no_file_ids = 0;
    
    /*
     * Check to see if server supports File IDs or not
     * Watch out because the ".." in every Query Dir response has File ID of 0
     * which is supposed to be illegal. Sigh.
     */
    if (SSTOVC(share)->vc_misc_flags & SMBV_HAS_FILEIDS) {
        if (ino == 0) {
            no_file_ids = 1;
            
            if ((network_name != NULL) && (network_name_len > 0)) {
                if ((network_name_len == 2 &&
                     letohs(*(uint16_t * ) network_name) == 0x002e) ||
                    (network_name_len == 4 &&
                     letohl(*(uint32_t *) network_name) == 0x002e002e)) {
                        /*
                         * Its the ".." dir so allow the File ID of 0. "." and ".."
                         * dirs are ignored by smbfs_findnext so we can safely leave
                         * their fa_ino to be 0
                         */
                        no_file_ids = 0;
                    }
            }
        }
    }
    
    if (no_file_ids == 1) {
        SMBDEBUG("Server does not support File IDs \n");
        SSTOVC(share)->vc_misc_flags &= ~SMBV_HAS_FILEIDS;
    }
}
Ejemplo n.º 4
0
int
cmd_view(int argc, char *argv[])
{
	struct smb_ctx sctx, *ctx = &sctx;
	struct smb_share_info_1 *rpbuf, *ep;
	char *cp;
	u_int16_t type;
	int error, opt, bufsize, i, entries, total;
	

	if (argc < 2)
		view_usage();
	if (smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_VC, SMB_ST_ANY) != 0)
		exit(1);
	if (smb_ctx_readrc(ctx) != 0)
		exit(1);
	if (smb_rc)
		rc_close(smb_rc);
	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
		switch(opt){
		    case STDPARAM_ARGS:
			error = smb_ctx_opt(ctx, opt, optarg);
			if (error)
				exit(1);
			break;
		    default:
			view_usage();
			/*NOTREACHED*/
		}
	}
#ifdef APPLE
	if (loadsmbvfs())
		errx(EX_OSERR, "SMB filesystem is not available");
#endif
	smb_ctx_setshare(ctx, "IPC$", SMB_ST_ANY);
	if (smb_ctx_resolve(ctx) != 0)
		exit(1);
	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
	if (error) {
		smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
		exit(1);
	}
	printf("Share        Type       Comment\n");
	printf("-------------------------------\n");
	bufsize = 0xffe0; /* samba notes win2k bug with 65535 */
	rpbuf = malloc(bufsize);
	error = smb_rap_NetShareEnum(ctx, 1, rpbuf, bufsize, &entries, &total);
	if (error &&
	    error != (SMB_ERROR_MORE_DATA | SMB_RAP_ERROR)) {
		smb_error("unable to list resources", error);
		exit(1);
	}
	for (ep = rpbuf, i = 0; i < entries; i++, ep++) {
		type = letohs(ep->shi1_type);

		cp = (char*)rpbuf + ep->shi1_remark;
		printf("%-12s %-10s %s\n", ep->shi1_netname,
		    shtype[min(type, sizeof shtype / sizeof(char *) - 1)],
		    ep->shi1_remark ? nls_str_toloc(cp, cp) : "");
	}
	printf("\n%d shares listed from %d available\n", entries, total);
	free(rpbuf);
	return 0;
}
Ejemplo n.º 5
0
/**
 * Default constructor
 */
MpRawAudioBuffer::MpRawAudioBuffer(const char* pFilePath)
{
   MpAudioAbstract* pAudioAbstract;
   long minRate, maxRate, prefRate;
   int  minChan, maxChan, prefChan;
   int  decompressionType;

   mpAudioBuffer = NULL;
   mAudioBufferLength = 0;

   // Open an IO stream to the audio file
   ifstream sourceFile(pFilePath, ios::in | ios::binary);

   pAudioAbstract = MpOpenFormat(sourceFile);
   if (pAudioAbstract == NULL) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) - Failed to load file", pFilePath);
      return;
   }

   // Now validate the format. It must be a WAV file formated as
   // unsigned 16 bit mono at 8KHz
   if (pAudioAbstract->getAudioFormat() != AUDIO_FORMAT_WAV) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Not in WAV format", pFilePath);
      return;
   }

   // Now validate the sampling rate, number of channels and decompression type
   pAudioAbstract->minMaxSamplingRate(&minRate, &maxRate, &prefRate);
   if (prefRate != 8000) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Invalid sampling rate: %d",
                    pFilePath, (int) prefRate);
      return;
   }

   pAudioAbstract->minMaxChannels(&minChan, &maxChan, &prefChan);
   if (prefChan != 1) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Invalid number of channels: %d",
                    pFilePath, prefChan);
      return;
   }

   decompressionType = pAudioAbstract->getDecompressionType();
   if (decompressionType != MpAudioWaveFileRead:: DePcm16LsbSigned) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Data not PCM 16bit Signed", pFilePath);
      return;
   }

   // Determine the audio data size and allocate storage for it
   mAudioBufferLength = pAudioAbstract->getBytesSize();
   mpAudioBuffer = new char[mAudioBufferLength];
   if (mpAudioBuffer == NULL) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) - Failed to allocate storage: new char[%d]",
                    pFilePath, (int) mAudioBufferLength);
      mAudioBufferLength = 0;
      return;
   }

   // Finally read in the data
   unsigned long readLen = pAudioAbstract->readBytes(reinterpret_cast<AudioByte*>(mpAudioBuffer), mAudioBufferLength);
   if (readLen != mAudioBufferLength) {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpRawAudioBuffer::MpRawAudioBuffer(%s) Failed to read audio data", pFilePath);
      mAudioBufferLength = 0;
      delete[] mpAudioBuffer;
   }
#ifdef __BIG_ENDIAN__
   // We are running on a big endian processor - raw audio 16-bit samples are
   // in the little endian byte order - convert them to big endian.
   unsigned short *pData = (unsigned short *)mpAudioBuffer;
   for ( unsigned long index = 0; index < ( mAudioBufferLength / 2 ); index++, pData++ )
      *pData = letohs(*pData);
#endif
}
Ejemplo n.º 6
0
UtlBoolean MprRecorder::doProcessFrame(MpBufPtr inBufs[],
                                   MpBufPtr outBufs[],
                                   int inBufsSize,
                                   int outBufsSize,
                                   UtlBoolean isEnabled,
                                   int samplesPerFrame,
                                   int samplesPerSecond)
{
   int numBytes = 0;
   int numSamples = 0;
   MpBufPtr in = NULL;
   Sample* input;

   // Lock so that mFileDescriptor and file contents cannot be changed out
   // from under us while we are updating the file.
   OsLock lock(mMutex);

   //try to pass along first input
   if (inBufsSize > 0)
   {
      in = *inBufs;
   }

   if (numOutputs() > 0)
   {
      if (inBufsSize > 0) *inBufs = NULL;
      *outBufs = in;
   }

   if (!isEnabled) {
      return TRUE;
   }

   if (mFileDescriptor < 0)
   {
      OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::doProcessFrame to disable recording because mFileDescriptor=%d, mStatus=%d",
            mFileDescriptor, mStatus);
      disable(RECORD_STOPPED); // just in case...
   }

   if (inBufsSize == 0) {
      // no input buffers, indicate config error
      disable(INVALID_SETUP);
      return TRUE;
   }

   // maximum record time reached or final silence timeout.
   if ((0 >= mFramesToRecord--) || (mSilenceLength <= mConsecutiveInactive)) {
      // Get previous MinVoiceEnergy for debug printouts, and reset it to MIN_SPEECH_ENERGY_THRESHOLD.
      unsigned long prevValue = MpBuf_setMVE(MIN_SPEECH_ENERGY_THRESHOLD);

      OsSysLog::add(FAC_MP, PRI_INFO,
         "MprRecorder::doProcessFrame to disable recording because"
         " mFramesToRecord=%d, mStatus=%d mSilenceLength=%d,"
         " mConsecutiveInactive=%d, MinVoiceEnergy=%lu", mFramesToRecord,
         mStatus, mSilenceLength, mConsecutiveInactive, prevValue);
      disable(RECORD_FINISHED);
   } else {

      int bytesWritten = 0;

      //now write the buffer out

      if (NULL == in) {
         in = MpBuf_getFgSilence();
      } else {
        MpBuf_addRef(in);
      }

      if (MpBuf_isActiveAudio(in)) {
        mConsecutiveInactive = 0;
      } else {
        mConsecutiveInactive++;
      }

      input = MpBuf_getSamples(in);
      numSamples = MpBuf_getNumSamples(in);
      numBytes = numSamples * sizeof(Sample);
      if (mFileDescriptor > -1)
      {
#ifdef __BIG_ENDIAN__
         //We are running on a big endian processor - 16-bit samples are in the big endian
         //byte order - convert them to little endian before writing them to the file.
         unsigned short *pData;
         int index;

         for ( index = 0, pData = (unsigned short *)input; index < numSamples; index++, pData++ )
             *pData = htoles(*pData);
#endif
         bytesWritten = write(mFileDescriptor, (char *)input, numBytes);
#ifdef __BIG_ENDIAN__
         if (numOutputs() > 1)
         {
             //There is more than one output - convert the samples back to big endian
             for ( index = 0, pData = (unsigned short *)input; index < numSamples; index++, pData++ )
                 *pData = letohs(*pData);
         }
#endif
      }

      if (bytesWritten != numBytes) {
         disable(WRITE_ERROR);
      } else {
         mTotalBytesWritten += numBytes;
         mTotalSamplesWritten += samplesPerFrame;
      }
      MpBuf_delRef(in);
   }
   return TRUE;
}
Ejemplo n.º 7
0
// Advances the mCurrentChunk to the next data chunk within the stream
UtlBoolean StreamWAVFormatDecoder::nextDataChunk(ssize_t& iLength)
{
   UtlBoolean bSuccess = FALSE ;
   ssize_t iRead ;
   char Header[128];
   uint32_t blockSize=0;  // 4 byte value in WAV file
   ssize_t iCurrentPosition ;
   iLength = 0 ;

   StreamDataSource* pDataSource = getDataSource() ;
   if (pDataSource != NULL)
   {
      while (!mbEnd && pDataSource->read((char*) Header, 4, iRead) == OS_SUCCESS)
      {
         pDataSource->getPosition(iCurrentPosition);
         if (iCurrentPosition == 4 && memcmp(Header, MpWaveFileFormat, 4) != 0)
         {
             //if this is true, then this file is not a wav, since
             //all wave files start with RIFF.
             mbEnd = TRUE;
             iLength = 0;

             // Search to see if this is a 404 error.
             pDataSource->read((char*) Header + 4, 123, iRead);
             Header[127] = '\0';
             if (strstr(Header, "404 Not Found") != NULL)
                syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (404 Not Found).)");
             else
                syslog(FAC_STREAMING, PRI_ERR,
                       "StreamWAVFormatDecoder::nextDataChunk (%s not detected.)",
                       MpWaveFileFormat
                       );

             // Just return successful with zero data read.
             return TRUE;
         }
         else
         if (memcmp(Header, MpWaveFileFormat, 4) == 0)
         {
             //just read the block size
            if (pDataSource->read((char*) &blockSize, sizeof(blockSize), iRead) != OS_SUCCESS)
            {
                syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error reading block size!)");
                break;
            }

         }
         else
         if (memcmp(Header, "WAVE", 4) == 0)
             ; //do nothing, doesn't even have block size
         else
         if (memcmp(Header, "fmt ", 4) == 0)
         {

            FORMATChunkInfo formatChunkInfo;
            if (pDataSource->read((char*) &blockSize, sizeof(blockSize), iRead) == OS_SUCCESS)
            {
                blockSize = letohl(blockSize);

                //save the current position, well need it for the jump
                if (pDataSource->getPosition(iCurrentPosition) != OS_SUCCESS)
                {
                   break;
                }

                if (pDataSource->read((char*) &formatChunkInfo, sizeof(formatChunkInfo), iRead) == OS_SUCCESS)
                {
                    //Make sure the read integer values are in the host byte order
                    formatChunkInfo.formatTag = letohs(formatChunkInfo.formatTag);
                    formatChunkInfo.nChannels = letohs(formatChunkInfo.nChannels);
                    formatChunkInfo.nSamplesPerSec = letohl(formatChunkInfo.nSamplesPerSec);
                    formatChunkInfo.nAvgBytesPerSec = letohl(formatChunkInfo.nAvgBytesPerSec);
                    formatChunkInfo.nBlockAlign = letohs(formatChunkInfo.nBlockAlign);
                    formatChunkInfo.nBitsPerSample = letohs(formatChunkInfo.nBitsPerSample);
                    // for streaming, we currently only support one format:
                    // 16 bit, 8khz, signed.
                    if (formatChunkInfo.nSamplesPerSec != 8000 || formatChunkInfo.nBitsPerSample != 16 ||
                        formatChunkInfo.nChannels != 1)
                    {
                        syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (File is not 16 bit, 8khz, mono, signed format!)");
                         mbEnd = TRUE;
                         break;
                    }

                    memcpy(&mFormatChunk, &formatChunkInfo, sizeof(formatChunkInfo)) ;
                    iLength = blockSize ;

                    //now move to next block
                    if (pDataSource->seek(iCurrentPosition + blockSize) != OS_SUCCESS)
                    {
                       // Kick out if we cannot seek
                       syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error seeking past block \"fmt\"!)");
                       break ;
                    }
                }
                else
                {
                    syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error reading block \"fmt\"!)");
                    break;
                }
            }
            else
            {
                syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error reading block size of fmt chunk)");
                break;
            }
             //we won't set true yet, because we'd like to get one block of data first
         }
         else
         if (memcmp(Header, "data", 4) == 0)
         {
            if (pDataSource->read((char*) &blockSize, sizeof(blockSize), iRead) == OS_SUCCESS)
            {
                 iLength = letohl(blockSize);
                 bSuccess = TRUE ;
                 break ;
            }
         }
         else
         {
            // Unsupported chunk, advance to the next one...
            //just read the block size & block
            if (pDataSource->read((char*) &blockSize, sizeof(blockSize), iRead) == OS_SUCCESS)
            {
                char tmpbuf[16000];
                int  totalLeftToRead, bytesToRead;

                blockSize = letohl(blockSize);
                for (totalLeftToRead = blockSize; totalLeftToRead > 0; totalLeftToRead -= iRead )
                {
                    bytesToRead = sizeof(tmpbuf);
                    if (totalLeftToRead < bytesToRead)
                    {
                        bytesToRead = totalLeftToRead;
                    }
                    if (pDataSource->read(tmpbuf, bytesToRead, iRead) != OS_SUCCESS)
                    {
                        syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error reading block data)");
                        break;
                    }
                }
            }
            else
            {
                syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (Error reading block size of block)");
                break;
            }
         }
      }


       //if we haven't reached the end of the stream and we are still not success
       //then fire the decoding error
       ssize_t currentPosition;
       ssize_t streamLength;

       pDataSource->getLength(streamLength);
       pDataSource->getPosition(currentPosition);

       if (!bSuccess && (currentPosition < streamLength || streamLength == 0))
       {
           syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::nextDataChunk (FireEvent DecodingErrorEvent)");
          fireEvent(DecodingErrorEvent) ;
       }
   }


   return bSuccess ;
}
Ejemplo n.º 8
0
// Thread entry point
int StreamWAVFormatDecoder::run(void* pArgs)
{
   int iSamplesInOutBuffer = 0;
   Sample        partialFrame[80] ;
   int   nSamplesPartialFrame = 0;
   int numOutSamples = 0;
   ssize_t iDataLength ;
   int nQueuedFrames = 0;

   //used if the files are aLaw or uLaw encodec
   InitG711Tables();

   StreamDataSource* pSrc = getDataSource() ;
   if (pSrc != NULL)
   {
      ssize_t iRead = 0;
      char buf[16];

      // "pre-read" 4 bytes, to see if this is a 0 length file and should
      // be skipped.  Alas, apparently one cannot just call getLength()
      // as an  http fetch might not have returned any info yet.
      if (pSrc->peek(buf, 4, iRead) != OS_SUCCESS) // empty file
      {
         // If one doesn't queue at least one frame, then it seems things stall
         // Queue one frame of a "click" to give some audible indication
         // a file was played (even if it was empty)
         Sample Click[80] = {0} ;  // one frame of "click" to give audible
                                   // indication of some problem.
         Click[39] = -200 ;
         Click[40] = 20000 ;       // An impulse should do nicely
         Click[41] = -200 ;

         queueFrame((const uint16_t*)Click);
         mbEnd = TRUE ;
      }
      while (!mbEnd && nextDataChunk(iDataLength))
      {
         //we really want 80 SAMPLES not 80 bytes
         unsigned char  InBuffer[NUM_SAMPLES*2] ;
         Sample OutBuffer[4000] = {0} ;  //make room for lots of decompression

         iSamplesInOutBuffer = 0;

         while ((iDataLength > 0) && !mbEnd)
         {
            ssize_t iRead = 0;

            UtlBoolean retval = OS_INVALID;

            if (mFormatChunk.formatTag == 1 && mFormatChunk.nBitsPerSample == 8) //8bit unsigned
            {
                //we need to read 80 samples
                iRead = __min(iDataLength, NUM_SAMPLES);

                retval = pSrc->read((char *)InBuffer, iRead, iRead);

                //now convert to 16bit unsigned, which is what we use internally
                ConvertUnsigned8ToSigned16(InBuffer,OutBuffer,iRead);
                numOutSamples = iRead;
            }
            else
            if (mFormatChunk.formatTag == 1 && mFormatChunk.nBitsPerSample == 16) //16 bit signed
            {
                iRead = __min(iDataLength, NUM_SAMPLES*2);

                //just read in the data, because it's the format we need
                retval = pSrc->read((char *)OutBuffer, iRead, iRead);
                numOutSamples = iRead/2;
#ifdef __BIG_ENDIAN__
                if (retval == OS_SUCCESS)
                {
                    //We are running on a big endian processor - 16-bit samples are
                    //in the little endian byte order - convert them to big endian.
                    unsigned short *pData = (unsigned short *)OutBuffer;
                    for ( int index = 0; index < numOutSamples; index++, pData++ )
                        *pData = letohs(*pData);
                }
#endif
            }
            else
            if (mFormatChunk.formatTag == 6 || mFormatChunk.formatTag == 7) //16 bit signed
            {
                //we need to read 80 samples
                iRead = __min(iDataLength, NUM_SAMPLES);

                retval = pSrc->read((char *)OutBuffer, iRead, iRead);
                //no conversion to 16bit will take place because we need to decompress this
            }
            else
            {
                syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::run Unsupport bit per sample rate!");
            }

            iDataLength -= iRead;

            if (retval == OS_SUCCESS)
            {
               ssize_t bytes;
               switch (mFormatChunk.formatTag)
               {
                  case 1:     // PCM
                      //NO CONVERSION NEEDED
                        break ;
                  case 6:     // G711 alaw
                     bytes = DecompressG711ALaw(OutBuffer, iRead);
                     numOutSamples = iRead;
                     break ;
                  case 7:     // G711 ulaw
                     bytes = DecompressG711MuLaw(OutBuffer,iRead);
                     numOutSamples = iRead;
                     break ;
                }


                //we now should have a buffer filled with Samples, not bytes

                int numBytes = numOutSamples * sizeof(Sample);

                //next we check if the sound file is stereo...at this point in our lives
                //we only want to support mono
                //takes bytes in and gets bytes out.  NOT samples
                if (mFormatChunk.nChannels > 1)
                {
                    numBytes = mergeChannels((char *)OutBuffer, numBytes, mFormatChunk.nChannels);

                    //now calculate how many sample we have
                    numOutSamples = numBytes/sizeof(Sample);
                }

                //in the next fucntion we must pass bytes, NOT samples as second param
                numBytes = reSample((char *)OutBuffer, numBytes, mFormatChunk.nSamplesPerSec, DESIRED_SAMPLE_RATE);

                //now calculate how many sample we have
                numOutSamples = numBytes/sizeof(Sample);

                //this next part will buffer the samples if under 80 samples
                if (numOutSamples > 0)
                {
                    int iCount = 0 ;
                    while ((iCount < numOutSamples) && !mbEnd)
                    {
                        int iToCopy = numOutSamples - iCount ;
                        if (iToCopy > 80)
                            iToCopy = 80 ;

                          if (nSamplesPartialFrame == 0)
                          {
                             if (iToCopy >= 80)
                             {
                                queueFrame((const uint16_t*)OutBuffer+iCount);
                                nQueuedFrames++ ;
                             }
                             else
                             {
                                nSamplesPartialFrame = iToCopy ;
                                memcpy(partialFrame, (const unsigned short *)OutBuffer+iCount,iToCopy*sizeof(Sample)) ;
                             }
                          }
                          else
                          {
                             if (iToCopy > (80-nSamplesPartialFrame))
                                iToCopy = 80-nSamplesPartialFrame ;

                             memcpy(&partialFrame[nSamplesPartialFrame],(const unsigned short *)OutBuffer+iCount, iToCopy*sizeof(Sample)) ;
                             nSamplesPartialFrame += iToCopy ;

                             if (nSamplesPartialFrame == 80)
                             {
                                queueFrame((const uint16_t*) partialFrame);
                                nSamplesPartialFrame = 0 ;
                                nQueuedFrames++ ;
                             }
                          }
                          iCount += iToCopy ;
                     }
                }
            }
            else
            {
               // Truncated data source?
               syslog(FAC_STREAMING, PRI_ERR, "StreamWAVFormatDecoder::run (FireEvent DecodingErrorEvent)");
               fireEvent(DecodingErrorEvent) ;
               break ;
            }
         }
      }
      pSrc->close() ;
   }


   queueEndOfFrames() ;
   syslog(FAC_STREAMING, PRI_DEBUG, "StreamWAVFormatDecoder::run queued %d frames", nQueuedFrames);
   fireEvent(DecodingCompletedEvent) ;

   mSemExited.release() ;

   return 0 ;
}