예제 #1
0
파일: codec_speex.c 프로젝트: mtulio/mtulio
/*! \brief convert and store into outbuf */
static int speextolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
{
	struct speex_coder_pvt *tmp = pvt->pvt;

	/* Assuming there's space left, decode into the current buffer at
	   the tail location.  Read in as many frames as there are */
	int x;
	int res;
	int16_t *dst = pvt->outbuf.i16;
	/* XXX fout is a temporary buffer, may have different types */
#ifdef _SPEEX_TYPES_H
	spx_int16_t fout[1024];
#else
	float fout[1024];
#endif

	if (f->datalen == 0) {  /* Native PLC interpolation */
		if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
			ast_log(LOG_WARNING, "Out of buffer space\n");
			return -1;
		}
#ifdef _SPEEX_TYPES_H
		speex_decode_int(tmp->speex, NULL, dst + pvt->samples);
#else
		speex_decode(tmp->speex, NULL, fout);
		for (x=0;x<tmp->framesize;x++) {
			dst[pvt->samples + x] = (int16_t)fout[x];
		}
#endif
		pvt->samples += tmp->framesize;
		pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
		return 0;
	}

	/* Read in bits */
	speex_bits_read_from(&tmp->bits, f->data.ptr, f->datalen);
	for (;;) {
#ifdef _SPEEX_TYPES_H
		res = speex_decode_int(tmp->speex, &tmp->bits, fout);
#else
		res = speex_decode(tmp->speex, &tmp->bits, fout);
#endif
		if (res < 0)
			break;
		if (pvt->samples + tmp->framesize > BUFFER_SAMPLES) {
			ast_log(LOG_WARNING, "Out of buffer space\n");
			return -1;
		}
		for (x = 0 ; x < tmp->framesize; x++)
			dst[pvt->samples + x] = (int16_t)fout[x];
		pvt->samples += tmp->framesize;
		pvt->datalen += 2 * tmp->framesize; /* 2 bytes/sample */
	}
	return 0;
}
예제 #2
0
// renyang - 替音訊解碼
void Call::decodeAudioData(char *buf, int len)
{
#ifdef REN_DEBUG
	qWarning("Call::decodeAudioData()");
#endif
	if (dec_state)
	{
		// renyang - Initializes the bit-stream from the data in an area of memory
		// renyang - 把一連串的buf轉到bit-stream
		speex_bits_read_from(&bits, buf, len);
		// renyang - 把bits解碼到outBuffer(為float型態)
		// renyang - 當<0表示解碼失敗
		if (speex_decode(dec_state, &bits, outBuffer) < 0)
		{
			emit warning("Warning: wrong decryption key or stream corrupted!");
			disableDecrypt();
		}
		else
		{
			// renyang - 來到這裡表示解碼成功
			// renyang - 把解碼之後的音訊(outBuffer)放到soundBuffer中
			putData(outBuffer, frame_size);
		}
	}
}
예제 #3
0
int main(int argc, char **argv)
{
   char *outFile;
   FILE *fout;
   /*Holds the audio that will be written to file (16 bits per sample)*/
   short out[FRAME_SIZE];
   /*Speex handle samples as float, so we need an array of floats*/
   float output[FRAME_SIZE];
   char cbits[200];
   int nbBytes;
   /*Holds the state of the decoder*/
   void *state;
   /*Holds bits so they can be read and written to by the Speex routines*/
   SpeexBits bits;
   int i, tmp;

   /*Create a new decoder state in narrowband mode*/
   state = speex_decoder_init(&speex_nb_mode);

   /*Set the perceptual enhancement on*/
   tmp=1;
   speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);

   outFile = argv[1];
   fout = fopen(outFile, "w");

   /*Initialization of the structure that holds the bits*/
   speex_bits_init(&bits);
   while (1)
   {
      /*Read the size encoded by sampleenc, this part will likely be
        different in your application*/
      fread(&nbBytes, sizeof(int), 1, stdin);
      fprintf (stderr, "nbBytes: %d\n", nbBytes);
      if (feof(stdin))
         break;

      /*Read the "packet" encoded by sampleenc*/
      fread(cbits, 1, nbBytes, stdin);
      /*Copy the data into the bit-stream struct*/
      speex_bits_read_from(&bits, cbits, nbBytes);

      /*Decode the data*/
      speex_decode(state, &bits, output);

      /*Copy from float to short (16 bits) for output*/
      for (i=0;i<FRAME_SIZE;i++)
         out[i]=output[i];

      /*Write the decoded audio to file*/
      fwrite(out, sizeof(short), FRAME_SIZE, fout);
   }

   /*Destroy the decoder state*/
   speex_decoder_destroy(state);
   /*Destroy the bit-stream truct*/
   speex_bits_destroy(&bits);
   fclose(fout);
   return 0;
}
예제 #4
0
void decode(int header) {
  FILE * fin = fopen("audiopacket2.spx", "r");
  FILE * fout = fopen("decoded_audio.raw", "w");
  int i;
  short out[FRAME_SIZE];
  float output[FRAME_SIZE];
  char cbits[331-20];

  SpeexBits bits;
  void * state;
  
  state = speex_decoder_init(&speex_nb_mode);
  speex_bits_init(&bits);

  while(1) {
    if(feof(fin))
      break;

    /* on lit 307 octets (un paquet) vers cbits */
    fread(cbits, 1, 331-20, fin);
    /* on le copie vers une structure bit-stream */
    speex_bits_read_from(&bits, cbits+header, 331-20-header);
    /* on decode */
    speex_decode(state, &bits, output);

    for(i=0 ; i< FRAME_SIZE ; i++)
      out[i]= output[i];

    fwrite(out, sizeof(short), FRAME_SIZE, fout);
  }
}
예제 #5
0
Boolean CASpeexDecoder::GenerateFrames()
{
    Boolean ret = true;
    int result;

    mBDCStatus = kBDCStatusOK;
    SpeexFramePacket &sfp = mSpeexFPList.front();

    speex_bits_read_from(&mSpeexBits, reinterpret_cast<char*> (mBDCBuffer.GetData()), sfp.bytes);

    if (sfp.frames > 0 && (sfp.frames - mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet > 0)) {
        UInt32 zeroBytes = mOutputFormat.FramesToBytes(sfp.frames - mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet);
        memset(mOutBuffer + mOutBufferUsedSize, 0, zeroBytes);
        mOutBufferUsedSize += zeroBytes;
    }

    for (SInt32 i = 0; i < mSpeexHeader.frames_per_packet; i++) {
        if (mOutputFormat.mFormatFlags & kAudioFormatFlagsNativeFloatPacked != 0)
            result = speex_decode(mSpeexDecoderState, &mSpeexBits, reinterpret_cast<float*> (mOutBuffer + mOutBufferUsedSize));
        else
            result = speex_decode_int(mSpeexDecoderState, &mSpeexBits, reinterpret_cast<spx_int16_t*> (mOutBuffer + mOutBufferUsedSize));

        if (result < 0) {
            mBDCStatus = kBDCStatusAbort;
            return false;
        }

        if (mSpeexHeader.nb_channels == 2) {
            if (mOutputFormat.mFormatFlags & kAudioFormatFlagsNativeFloatPacked != 0)
                speex_decode_stereo(reinterpret_cast<float*> (mOutBuffer + mOutBufferUsedSize), mSpeexHeader.frame_size, &mSpeexStereoState);
            else
                speex_decode_stereo_int(reinterpret_cast<spx_int16_t*> (mOutBuffer + mOutBufferUsedSize), mSpeexHeader.frame_size, &mSpeexStereoState);
        }
        mOutBufferUsedSize += mOutputFormat.FramesToBytes(mSpeexHeader.frame_size);
    }

    if (sfp.frames == 0) {
        mNumFrames += mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet;
    } else if (sfp.frames > 0) {
        mNumFrames += sfp.frames;
        if (mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet - sfp.frames != 0)
            mOutBufferStart += mOutputFormat.FramesToBytes(mSpeexHeader.frame_size * mSpeexHeader.frames_per_packet - sfp.frames);
    } else {
        mNumFrames -= sfp.frames;
    }

    mBDCBuffer.Zap(sfp.bytes);
    mSpeexFPList.erase(mSpeexFPList.begin());

    return ret;
}
예제 #6
0
void *os_sound_start_thread(void *_ca)
{
  jcall_t *ca = (jcall_t*)_ca;
  char data_in[160];
  short sp_data_in_s[640];
  float sp_data_in_f[640];
  int have_more;
  int timestamp = 0;
  int i;

  while (ca->enable_audio != -1)
    {
      memset(data_in, 0, 160);
      /* receive ONE packet */
      i = rtp_session_recv_with_ts(ca->rtp_session, data_in, 160, timestamp, &have_more);

      speex_bits_reset(&ca->dec_speex_bits);
      speex_bits_read_from(&ca->dec_speex_bits, data_in, i);

      while(1)
	{
	  int k;
	  k = speex_decode(ca->speex_dec, &ca->dec_speex_bits, sp_data_in_f);
	  if (k==-2)
	    {
	      exit(0);
	    }
	  else if (k==-1)
	    {
	      break;
	    }
	  else if (k==0)
	    {
	      int j;
	      for (j=0;j<ca->speex_fsize;j++)
		{
		  if (sp_data_in_f[j]>32767)
		    sp_data_in_f[j]=32767;
		  if (sp_data_in_f[j]<-32767)
		    sp_data_in_f[j]=-32767;
		  sp_data_in_s[j] = (short) sp_data_in_f[j];
		}
	      write(fd, sp_data_in_s, ca->speex_fsize);
	    }
	}
      timestamp += 160;
    }
  return NULL;
}
예제 #7
0
void gviSpeexDecodeSet(GVSample * out, const GVByte * in, GVDecoderData data)
{
	int rcode;
	int i;

	// read the data into the bits
	speex_bits_read_from(&gviSpeexBits, (char *)in, gviSpeexEncodedFrameSize);

	// decode it
	rcode = speex_decode((void *)data, &gviSpeexBits, gviSpeexBuffer);
	GS_ASSERT(rcode == 0);

	// convert the output from floats
	for(i = 0 ; i < gviSpeexSamplesPerFrame ; i++)
		out[i] = (GVSample)gviSpeexBuffer[i];
}
예제 #8
0
void gviSpursSpeexDecodeAdd(SpursSpeexTaskOutput *spuTaskOut)
{
	char *inBuffer;
	float *speexBuffer;
	short *outBuffer;
	int rcode;
	unsigned int i;
	
	//spuDebugPrintf("[Speex][SPU] allocating buffers for decoding\n");
	speexBuffer = (float *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float));
	outBuffer = (short *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short));
	inBuffer = (char *)memalign(16, gviSpursSpeexTaskDesc.mInputBufferSize);

	memset(speexBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float));
	memset(outBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize);
	memset(inBuffer, 0, gviSpursSpeexTaskDesc.mInputBufferSize * sizeof(short));
	
	
	//spuDebugPrintf("[Speex][SPU] done allocating, getting input data, inbuffer size: %d\n", gSpuSampleTaskDesc.mInputBufferSize);
	cellDmaGet(inBuffer, (uint64_t)gviSpursSpeexTaskDesc.mInputBuffer, gviSpursSpeexTaskDesc.mInputBufferSize, DMA_TAG(1), 0,0);
	cellDmaWaitTagStatusAll(DMA_MASK(1));
	// spuDebugPrintf("[Speex][SPU] done getting input data, preparing for speex to decode\n");
	// read the data into the bits
	// (re)initialize the bits struct
	speex_bits_init_buffer(&gviSpursSpeexBits,gviSpursSpeexBitsBuffer,sizeof(gviSpursSpeexBitsBuffer));

	speex_bits_read_from(&gviSpursSpeexBits, (char *)inBuffer, gviSpursSpeexTaskDesc.mEncodedFrameSize);

	// decode it
	rcode = speex_decode((void *)gviSpursSpeexStateBuffer, &gviSpursSpeexBits, speexBuffer);
	assert(rcode == 0);
	//spuDebugPrintf("[Speex][SPU] done with speex decode\n");
	// convert the output from floats
	for(i = 0 ; i < gviSpursSpeexTaskDesc.mOutputBufferSize ; i++)
		outBuffer[i] = (short)speexBuffer[i];
	
	//spuDebugPrintf("[Speex][SPU] transferring data back\n");
	cellDmaPut(outBuffer, (uint64_t)gviSpursSpeexTaskDesc.mOutputBuffer, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short), DMA_TAG(1), 0, 0);
	cellDmaWaitTagStatusAll(DMA_MASK(1));
	//spuDebugPrintf("[Speex][SPU] done transferring data back\n");
	free(speexBuffer);
	free(inBuffer);
	free(outBuffer);
	spuTaskOut->mSpeexReturnCode = 0;
}
예제 #9
0
hsBool plSpeex::Decode(uint8_t *data, int size, int numFrames, int *numOutputBytes, short *out)
{
    if(!fInitialized) return false;
    *numOutputBytes = 0;

    hsReadOnlyStream stream( size, data );
    float *speexOutput = new float[fFrameSize];     // holds output from speex
    short *pOut = out;                              // pointer to output short buffer
    
    // create buffer for input data
    uint8_t *frameData = new uint8_t[fFrameSize];         // holds the current frames data to be decoded
    uint8_t frameLen;                                  // holds the length of the current frame being decoded.
    

    // Decode data
    for (int i = 0; i < numFrames; i++)
    {
        stream.ReadLE( &frameLen );           // read the length of the current frame to be decoded
        stream.Read( frameLen, frameData );     // read the data

        memset(speexOutput, 0, fFrameSize * sizeof(float));
        speex_bits_read_from(fBits, (char *)frameData, frameLen);   // give data to speex
        speex_decode(fDecoderState, fBits, speexOutput);                    // decode data 

        for(int j = 0; j < fFrameSize; j++)
        {
            pOut[j] = (short)(speexOutput[j]);          // convert floats to shorts
        }
        
        pOut += fFrameSize;                  
    }
    
    delete[] frameData;
    delete[] speexOutput;
    
    *numOutputBytes = (numFrames * fFrameSize) * sizeof(short);     // length of decoded voice data(out) in bytes
    if(*numOutputBytes == 0) 
        return false;

    return true;
}
예제 #10
0
void gviSpursSpeexDecodeSet(SpursSpeexTaskOutput *spuTaskOut)
{
	char *inBuffer;
	float *speexBuffer;
	short *outBuffer;
	int rcode;
	unsigned int i;

	speexBuffer = (float *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float));
	outBuffer = (short *)memalign(16, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short));
	inBuffer = (char *)memalign(16, gviSpursSpeexTaskDesc.mInputBufferSize);

	memset(speexBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(float));
	memset(inBuffer, 0, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short));
	memset(outBuffer, 0, gviSpursSpeexTaskDesc.mInputBufferSize);

	cellDmaGet(inBuffer, (uint64_t)gviSpursSpeexTaskDesc.mInputBuffer, gviSpursSpeexTaskDesc.mInputBufferSize, DMA_TAG(1), 0,0);
	cellDmaWaitTagStatusAll(DMA_MASK(1));

	// read the data into the bits
	speex_bits_read_from(&gviSpursSpeexBits, (char *)inBuffer, gviSpursSpeexTaskDesc.mEncodedFrameSize);

	// decode it
	rcode = speex_decode((void *)gviSpursSpeexStateBuffer, &gviSpursSpeexBits, speexBuffer);
	assert(rcode == 0);

	// convert the output from floats
	for(i = 0 ; i < gviSpursSpeexTaskDesc.mOutputBufferSize ; i++)
		// Expanded to remove warnings in VS2K5
		outBuffer[i] = (short)speexBuffer[i];

	cellDmaPut(outBuffer, (uint64_t)gviSpursSpeexTaskDesc.mOutputBuffer, gviSpursSpeexTaskDesc.mOutputBufferSize * sizeof(short), DMA_TAG(1), 0, 0);
	cellDmaWaitTagStatusAll(DMA_MASK(1));
	free(speexBuffer);
	free(inBuffer);
	free(outBuffer);
	spuTaskOut->mSpeexReturnCode = 0;
}
예제 #11
0
int main(int argc, char **argv)
{
   char *inFile, *outFile, *bitsFile;
   FILE *fin, *fout, *fbits=NULL;
   short in[FRAME_SIZE];
   float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE];
   char cbits[200];
   int nbBits;
   int i;
   void *st;
   void *dec;
   SpeexBits bits;
   int tmp;
   int bitCount=0;
   SpeexCallback callback;

   for (i=0;i<FRAME_SIZE;i++)
      bak2[i]=0;
   st = speex_encoder_init(&speex_nb_mode);
   dec = speex_decoder_init(&speex_nb_mode);

   callback.callback_id = SPEEX_INBAND_CHAR;
   callback.func = speex_std_char_handler;
   callback.data = stderr;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
   callback.func = speex_std_mode_request_handler;
   callback.data = st;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   tmp=0;
   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
   tmp=0;
   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   tmp=8;
   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
   tmp=1;
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);

   speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
   fprintf (stderr, "frame size: %d\n", tmp);

   if (argc != 4 && argc != 3)
   {
      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
      exit(1);
   }
   inFile = argv[1];
   fin = fopen(inFile, "r");
   outFile = argv[2];
   fout = fopen(outFile, "w");
   if (argc==4)
   {
      bitsFile = argv[3];
      fbits = fopen(bitsFile, "w");
   }
   speex_bits_init(&bits);
   while (!feof(fin))
   {
      fread(in, sizeof(short), FRAME_SIZE, fin);
      if (feof(fin))
         break;
      for (i=0;i<FRAME_SIZE;i++)
         bak[i]=input[i]=in[i];
      speex_bits_reset(&bits);
      /*
      speex_bits_pack(&bits, 14, 5);
      speex_bits_pack(&bits, SPEEX_INBAND_CHAR, 4);
      speex_bits_pack(&bits, 'A', 8);
      
      speex_bits_pack(&bits, 14, 5);
      speex_bits_pack(&bits, SPEEX_INBAND_MODE_REQUEST, 4);
      speex_bits_pack(&bits, 7, 4);

      speex_bits_pack(&bits, 15, 5);
      speex_bits_pack(&bits, 2, 4);
      speex_bits_pack(&bits, 0, 16);
      */
      speex_encode(st, input, &bits);
      nbBits = speex_bits_write(&bits, cbits, 200);
      bitCount+=bits.nbBits;
      printf ("Encoding frame in %d bits\n", nbBits*8);
      if (argc==4)
         fwrite(cbits, 1, nbBits, fbits);
      {
         float enoise=0, esig=0, snr;
         for (i=0;i<FRAME_SIZE;i++)
         {
            enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]);
            esig += bak2[i]*bak2[i];
         }
         snr = 10*log10((esig+1)/(enoise+1));
         printf ("real SNR = %f\n", snr);
      }
      speex_bits_rewind(&bits);
      
      speex_decode(dec, &bits, input);
      
      /* Save the bits here */
      for (i=0;i<FRAME_SIZE;i++)
      {
         if (input[i]>32000)
            input[i]=32000;
         else if (input[i]<-32000)
            input[i]=-32000;
      }
      speex_bits_reset(&bits);
      for (i=0;i<FRAME_SIZE;i++)
         in[i]=(short)input[i];
      for (i=0;i<FRAME_SIZE;i++)
         bak2[i]=bak[i];
      fwrite(in, sizeof(short), FRAME_SIZE, fout);
   }
   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
   
   speex_encoder_destroy(st);
   speex_decoder_destroy(dec);
   return 1;
}
예제 #12
0
void speex_jitter_get(SpeexJitter *jitter, short *out)
{
   int i;
   int ret;
   
   /* Handle frame interpolation (receiving too fast) */
   if (jitter->interp_frame)
   {
      speex_decode(jitter->dec, NULL, out);
      jitter->interp_frame = 0;
      return;
   }

   /* Increment timestamp */
   jitter->pointer_timestamp += jitter->frame_time;

   /* Handle frame dropping (receiving too fast) */
   if (jitter->drop_frame)
   {
      jitter->pointer_timestamp += jitter->frame_time;
      jitter->drop_frame = 0;
   }

   /* Send zeros while we fill in the buffer */
   if (jitter->pointer_timestamp<0)
   {
      for (i=0;i<jitter->frame_size;i++)
         out[i]=0;
      return;
   }
   
   /* Search the buffer for a packet with the right timestamp */
   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
   {
      if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp)
         break;
   }
   
   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
   {
      /* No packet found */
      if (jitter->valid_bits)
      {
         /* Try decoding last received packet */
         ret = speex_decode(jitter->dec, &jitter->current_packet, out);
         if (ret == 0)
            return;
         else
            jitter->valid_bits = 0;
      }

      /*Packet is late or lost*/
      speex_decode(jitter->dec, NULL, out);
   } else {
      /* Found the right packet */
      speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
      jitter->len[i]=-1;
      /* Decode packet */
      ret = speex_decode(jitter->dec, &jitter->current_packet, out);
      if (ret == 0)
      {
         jitter->valid_bits = 1;
      } else {
         /* Error while decoding */
         for (i=0;i<jitter->frame_size;i++)
            out[i]=0;
      }
   }


}
예제 #13
0
static gint
xmms_speex_read (xmms_xform_t *xform, gpointer buf, gint len,
                 xmms_error_t *err)
{
	gint ret = 0, n;
	gfloat outfloat [2000];
	gint16 *outbuf = (gint16 *) buf;
	xmms_speex_data_t *data;
	xmms_error_t error;
	SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;

	g_return_val_if_fail (xform, -1);

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	/* convert from bytes to samples */
	len /= 2;

	/* first, copy already decoded samples over if we have any. */
	if (data->samples_count) {
		n = MIN (data->samples_count, len);

		memcpy (outbuf, data->samples_start, n * 2);
		data->samples_count -= n;

		if (!data->samples_count) {
			data->samples_start = data->samples_buf;
		} else {
			data->samples_start += n;
		}

		/* convert from samples to bytes */
		return n * 2;
	}

	while (42) {
		gint samples_per_frame;

		samples_per_frame = data->speexheader->frame_size *
		                    data->speexheader->nb_channels;

		while (ogg_stream_packetout (&data->stream_state, &data->ogg_packet) == 1) {
			gint frame;

			speex_bits_read_from (&data->speex_bits,
			                      (char *)data->ogg_packet.packet,
			                      data->ogg_packet.bytes);

			for (frame = 0; frame < data->speexheader->frames_per_packet; frame++) {
				gint cnt;

				speex_decode (data->speex_state, &data->speex_bits, outfloat);

				if (data->speexheader->nb_channels == 2) {
					speex_decode_stereo (outfloat, data->speexheader->frame_size,&stereo);
				}

				n = MIN (samples_per_frame, len);

				/* copy as many samples to the output buffer as
				 * possible.
				 */
				for (cnt = 0; cnt < n; cnt++) {
					*outbuf++ = outfloat[cnt];
					len--;
					ret += 2;
				}

				/* store the remaining samples for later use */
				for (; cnt < samples_per_frame; cnt++) {
					data->samples_buf[data->samples_count++] =
						outfloat[cnt];
				}
			}

			return ret;
		}

		/* Need more data */

		do {
			gint ret;

			data->ogg_data = ogg_sync_buffer (&data->sync_state, 200);
			ret = xmms_xform_read (xform, data->ogg_data, 200, &error);
			ogg_sync_wrote (&data->sync_state, ret);

			if (ret <= 0) {
				return ret;
			}
		} while (ogg_sync_pageout (&data->sync_state, &data->ogg_page) != 1);

		ogg_stream_pagein (&data->stream_state, &data->ogg_page);
	}
}
예제 #14
0
int main(int argc, char **argv)
{
   char *inFile, *outFile, *bitsFile;
   FILE *fin, *fout, *fbits=NULL;
   short in[FRAME_SIZE];
   float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE];
   char cbits[200];
   int nbBits;
   int i;
   void *st;
   void *dec;
   SpeexBits bits;
   int tmp;
   int bitCount=0;

   for (i=0;i<FRAME_SIZE;i++)
      bak2[i]=0;
   st = speex_encoder_init(&speex_uwb_mode);
   dec = speex_decoder_init(&speex_uwb_mode);
   
   tmp=0;
   /*speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
   tmp=0;
   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   tmp=10;
   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
   tmp=3;
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
   tmp=3;
   speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
   tmp=6;
   speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
   */
   if (argc != 4 && argc != 3)
   { 
      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
      exit(1);
   }
   inFile = argv[1];
   fin = fopen(inFile, "r");
   outFile = argv[2];
   fout = fopen(outFile, "w");
   if (argc==4)
   {
      bitsFile = argv[3];
      fbits = fopen(bitsFile, "w");
   }
   speex_bits_init(&bits);
   while (!feof(fin))
   {
      fread(in, sizeof(short), FRAME_SIZE, fin);
      if (feof(fin))
         break;
      for (i=0;i<FRAME_SIZE;i++)
         bak[i]=input[i]=in[i];
      speex_bits_reset(&bits);
      speex_encode(st, input, &bits);
      nbBits = speex_bits_write(&bits, cbits, 200);
      bitCount+=bits.nbBits;
      printf ("Encoding frame in %d bits\n", nbBits*8);
      if (argc==4)
         fwrite(cbits, 1, nbBits, fbits);
      {
         float enoise=0, esig=0, snr;
         for (i=0;i<FRAME_SIZE;i++)
         {
            enoise+=(bak2[i]-input[i])*(bak2[i]-input[i]);
            esig += bak2[i]*bak2[i];
         }
         snr = 10*log10((esig+1)/(enoise+1));
         printf ("real SNR = %f\n", snr);
      }
      speex_bits_rewind(&bits);
      
      speex_decode(dec, &bits, input);

      /* Save the bits here */
      for (i=0;i<FRAME_SIZE;i++)
      {
         if (input[i]>32000)
            input[i]=32000;
         else if (input[i]<-32000)
            input[i]=-32000;
      }
      speex_bits_reset(&bits);
      for (i=0;i<FRAME_SIZE;i++)
         in[i]=(short)input[i];
      for (i=0;i<FRAME_SIZE;i++)
         bak2[i]=bak[i];
      fwrite(in, sizeof(short), FRAME_SIZE, fout);
   }
   
   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
   speex_encoder_destroy(st);
   speex_decoder_destroy(dec);
   speex_bits_destroy(&bits);
   fclose(fin);
   fclose(fout);
   return 1;
}
예제 #15
0
int main(int argc, char **argv)
{
   char *inFile, *outFile, *bitsFile;
   FILE *fin, *fout, *fbits=NULL;
   short in_short[FRAME_SIZE];
   short out_short[FRAME_SIZE];
   float in_float[FRAME_SIZE];
   float sigpow,errpow,snr, seg_snr=0;
   int snr_frames = 0;
   char cbits[200];
   int nbBits;
   int i;
   void *st;
   void *dec;
   SpeexBits bits;
   int tmp;
   int bitCount=0;
   int skip_group_delay;
   SpeexCallback callback;

   sigpow = 0;
   errpow = 0;

   st = speex_encoder_init(&speex_uwb_mode);
   dec = speex_decoder_init(&speex_uwb_mode);

   callback.callback_id = SPEEX_INBAND_CHAR;
   callback.func = speex_std_char_handler;
   callback.data = stderr;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
   callback.func = speex_std_mode_request_handler;
   callback.data = st;
   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);

   tmp=0;
   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
   tmp=0;
   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   tmp=7;
   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
   tmp=1;
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);

   speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
   fprintf (stderr, "frame size: %d\n", tmp);
   skip_group_delay = 509;

   if (argc != 4 && argc != 3)
   {
      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
      exit(1);
   }
   inFile = argv[1];
   fin = fopen(inFile, "r");
   outFile = argv[2];
   fout = fopen(outFile, "w+");
   if (argc==4)
   {
      bitsFile = argv[3];
      fbits = fopen(bitsFile, "w");
   }
   speex_bits_init(&bits);
   while (!feof(fin))
   {
      fread(in_short, sizeof(short), FRAME_SIZE, fin);
      if (feof(fin))
         break;
      for (i=0;i<FRAME_SIZE;i++)
         in_float[i]=in_short[i];
      speex_bits_reset(&bits);

      speex_encode(st, in_short, &bits);
      nbBits = speex_bits_write(&bits, cbits, 200);
      bitCount+=bits.nbBits;

      if (argc==4)
         fwrite(cbits, 1, nbBits, fbits);
      speex_bits_rewind(&bits);

      speex_decode(dec, &bits, out_short);
      speex_bits_reset(&bits);

      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
      skip_group_delay = 0;
   }
   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
   speex_encoder_destroy(st);
   speex_decoder_destroy(dec);

   rewind(fin);
   rewind(fout);

   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
           &&
           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
   {
	float s=0, e=0;
        for (i=0;i<FRAME_SIZE;++i) {
            s += (float)in_short[i] * in_short[i];
            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
        }
	seg_snr += 10*log10((s+1)/(e+1));
	sigpow += s;
	errpow += e;
	snr_frames++;
   }
   fclose(fin);
   fclose(fout);

   snr = 10 * log10( sigpow / errpow );
   seg_snr /= snr_frames;
   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);

#ifdef FIXED_DEBUG
   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
#endif
   
   return 1;
}
예제 #16
0
UInt32 OggSpeexDecoder::ReadAudio(AudioBufferList *bufferList, UInt32 frameCount)
{
	if(!IsOpen() || NULL == bufferList || bufferList->mNumberBuffers != mFormat.mChannelsPerFrame || 0 == frameCount)
		return 0;

	UInt32 framesRead = 0;
	
	// Reset output buffer data size
	for(UInt32 i = 0; i < bufferList->mNumberBuffers; ++i)
		bufferList->mBuffers[i].mDataByteSize = 0;

	for(;;) {
		
		UInt32	framesRemaining	= frameCount - framesRead;
		UInt32	framesToSkip	= static_cast<UInt32>(bufferList->mBuffers[0].mDataByteSize / sizeof(float));
		UInt32	framesInBuffer	= static_cast<UInt32>(mBufferList->mBuffers[0].mDataByteSize / sizeof(float));
		UInt32	framesToCopy	= std::min(framesInBuffer, framesRemaining);
		
		// Copy data from the buffer to output
		for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) {
			float *floatBuffer = static_cast<float *>(bufferList->mBuffers[i].mData);
			memcpy(floatBuffer + framesToSkip, mBufferList->mBuffers[i].mData, framesToCopy * sizeof(float));
			bufferList->mBuffers[i].mDataByteSize += static_cast<UInt32>(framesToCopy * sizeof(float));
			
			// Move remaining data in buffer to beginning
			if(framesToCopy != framesInBuffer) {
				floatBuffer = static_cast<float *>(mBufferList->mBuffers[i].mData);
				memmove(floatBuffer, floatBuffer + framesToCopy, (framesInBuffer - framesToCopy) * sizeof(float));
			}
			
			mBufferList->mBuffers[i].mDataByteSize -= static_cast<UInt32>(framesToCopy * sizeof(float));
		}
		
		framesRead += framesToCopy;
		
		// All requested frames were read
		if(framesRead == frameCount)
			break;
		
		// EOS reached
		if(mSpeexEOSReached)
			break;

		// Attempt to process the desired number of packets
		unsigned packetsDesired = 1;
		while(0 < packetsDesired && !mSpeexEOSReached) {

			// Process any packets in the current page
			while(0 < packetsDesired && !mSpeexEOSReached) {

				// Grab a packet from the streaming layer
				ogg_packet oggPacket;
				int result = ogg_stream_packetout(&mOggStreamState, &oggPacket);
				if(-1 == result) {
					LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding error: Ogg loss of streaming");
					break;
				}
				
				// If result is 0, there is insufficient data to assemble a packet
				if(0 == result)
					break;

				// Otherwise, we got a valid packet for processing
				if(1 == result) {
					if(5 <= oggPacket.bytes && !memcmp(oggPacket.packet, "Speex", 5))
						mSpeexSerialNumber = mOggStreamState.serialno;
					
					if(-1 == mSpeexSerialNumber || mOggStreamState.serialno != mSpeexSerialNumber)
						break;
					
					// Ignore the following:
					//  - Speex comments in packet #2
					//  - Extra headers (optionally) in packets 3+
					if(1 != mOggPacketCount && 1 + mExtraSpeexHeaderCount <= mOggPacketCount) {
						// Detect Speex EOS
						if(oggPacket.e_o_s && mOggStreamState.serialno == mSpeexSerialNumber)
							mSpeexEOSReached = true;

						// SPEEX_GET_FRAME_SIZE is in samples
						spx_int32_t speexFrameSize;
						speex_decoder_ctl(mSpeexDecoder, SPEEX_GET_FRAME_SIZE, &speexFrameSize);
						float buffer [(2 == mFormat.mChannelsPerFrame) ? 2 * speexFrameSize : speexFrameSize];
						
						// Copy the Ogg packet to the Speex bitstream
						speex_bits_read_from(&mSpeexBits, (char *)oggPacket.packet, static_cast<int>(oggPacket.bytes));
						
						// Decode each frame in the Speex packet
						for(spx_int32_t i = 0; i < mSpeexFramesPerOggPacket; ++i) {
							
							result = speex_decode(mSpeexDecoder, &mSpeexBits, buffer);

							// -1 indicates EOS
							if(-1 == result)
								break;
							else if(-2 == result) {
								LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding error: possible corrupted stream");
								break;
							}
							
							if(0 > speex_bits_remaining(&mSpeexBits)) {
								LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Ogg Speex decoding overflow: possible corrupted stream");
								break;
							}
							
							// Normalize the values
							float maxSampleValue = 1u << 15;
							vDSP_vsdiv(buffer, 1, &maxSampleValue, buffer, 1, speexFrameSize);

							// Copy the frames from the decoding buffer to the output buffer, skipping over any frames already decoded
							framesInBuffer = static_cast<UInt32>(mBufferList->mBuffers[0].mDataByteSize / sizeof(float));
							memcpy(static_cast<float *>(mBufferList->mBuffers[0].mData) + framesInBuffer, buffer, speexFrameSize * sizeof(float));
							mBufferList->mBuffers[0].mDataByteSize += static_cast<UInt32>(speexFrameSize * sizeof(float));
							
							// Process stereo channel, if present
							if(2 == mFormat.mChannelsPerFrame) {
								speex_decode_stereo(buffer, speexFrameSize, mSpeexStereoState);
								vDSP_vsdiv(buffer + speexFrameSize, 1, &maxSampleValue, buffer + speexFrameSize, 1, speexFrameSize);

								memcpy(static_cast<float *>(mBufferList->mBuffers[1].mData) + framesInBuffer, buffer + speexFrameSize, speexFrameSize * sizeof(float));
								mBufferList->mBuffers[1].mDataByteSize += static_cast<UInt32>(speexFrameSize * sizeof(float));
							}
							
							// Packet processing finished
							--packetsDesired;
						}
					}

					++mOggPacketCount;
				}
			}
			
			// Grab a new Ogg page for processing, if necessary
			if(!mSpeexEOSReached && 0 < packetsDesired) {
				while(1 != ogg_sync_pageout(&mOggSyncState, &mOggPage)) {
					// Get the ogg buffer for writing
					char *data = ogg_sync_buffer(&mOggSyncState, READ_SIZE_BYTES);
					
					// Read bitstream from input file
					ssize_t bytesRead = GetInputSource()->Read(data, READ_SIZE_BYTES);
					if(-1 == bytesRead) {
						LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Unable to read from the input file");
						break;
					}
					
					ogg_sync_wrote(&mOggSyncState, bytesRead);

					// No more data available from input file
					if(0 == bytesRead)
						break;
				}
				
				// Ensure all Ogg streams are read
				if(ogg_page_serialno(&mOggPage) != mOggStreamState.serialno)
					ogg_stream_reset_serialno(&mOggStreamState, ogg_page_serialno(&mOggPage));

				// Get the resultant Ogg page
				int result = ogg_stream_pagein(&mOggStreamState, &mOggPage);
				if(0 != result) {
					LOGGER_ERR("org.sbooth.AudioEngine.AudioDecoder.OggSpeex", "Error reading Ogg page");
					break;
				}
			}
		}
	}
	
	mCurrentFrame += framesRead;

	if(0 == framesRead && mSpeexEOSReached)
		mTotalFrames = mCurrentFrame;

	return framesRead;
}
예제 #17
0
static int
read_ogg_packet(OGGZ * oggz, oggz_packet * zp, long serialno, void * user_data) {

	ogg_packet * op = &zp->op;
	decoder_t * dec = (decoder_t *)user_data;
	speex_pdata_t * pd = (speex_pdata_t *)dec->pdata;

	if (pd->exploring && (pd->packetno == 0)) {
		/* Speex header */

		int i;
                int ptr = 0;
                char speex_string[9];
		int enh = 1;

                SpeexHeader * header;


                for (i = 0; i < 8; i++) {
                        speex_string[i] = op->packet[ptr++];
                }
                speex_string[i] = '\0';

                if (strcmp(speex_string, "Speex   ") != 0) {
			printf("read_ogg_packet(): Not a Speex stream\n");
                        pd->error = 1;
			return 0;
                }

                speex_bits_init(&(pd->bits));

                header = speex_packet_to_header((char *)op->packet, op->bytes);
                if (!header) {
                        printf("Cannot read Speex header\n");
			pd->error = 1;
                        return 0;
                }

                pd->mode = speex_mode_list[header->mode];

                if (pd->mode->bitstream_version > header->mode_bitstream_version) {
                        fprintf(stderr, "Unknown bitstream version! The file was encoded with an older version of Speex.\n"
                                "You need to downgrade Speex in order to play it.\n");
			pd->error = 1;
                        return 0;
                }

                if (pd->mode->bitstream_version < header->mode_bitstream_version) {
                        fprintf(stderr, "Unknown bitstream version! The file was encoded with a newer version of Speex.\n"
                                "You need to upgrade Speex in order to play it.\n");
			pd->error = 1;
                        return 0;
                }

		pd->sample_rate = header->rate;
		pd->channels = header->nb_channels;
		pd->vbr = header->vbr;

                if (header->frames_per_packet != 0)
                        pd->nframes = header->frames_per_packet;

                pd->decoder = speex_decoder_init(pd->mode);
                speex_decoder_ctl(pd->decoder, SPEEX_GET_FRAME_SIZE, &(pd->frame_size));
                speex_decoder_ctl(pd->decoder, SPEEX_SET_ENH, &enh);

	} else if (pd->packetno >= 2) {

		int j;
		float output_frame[SPEEX_BUFSIZE];

		pd->granulepos = op->granulepos;

		if (!pd->exploring) {
			speex_bits_read_from(&(pd->bits), (char *)op->packet, op->bytes);
			
			for (j = 0; j < pd->nframes; j++) {
				
				int k;
				
				speex_decode(pd->decoder, &(pd->bits), output_frame);
				
				for (k = 0; k < pd->frame_size * pd->channels; k++) {
					output_frame[k] /= 32768.0f;
					if (output_frame[k] > 1.0f) {
						output_frame[k] = 1.0f;
					} else if (output_frame[k] < -1.0f) {
						output_frame[k] = -1.0f;
					}
				}
				
				rb_write(pd->rb, (char *)output_frame,
						      pd->channels * pd->frame_size * sample_size);
			}
		}
	}
	
	++pd->packetno;
	return 0;
}