Example #1
0
int WOggDecoder::GetBitrate(int fAverage)
{
	if(fAverage)
		return c_isInfo.nFileBitrate;

	int bitrate = ov_bitrate_instant(&vf);
	if(bitrate != 0 && bitrate != c_LastBitrate)
		c_LastBitrate = bitrate;

	return c_LastBitrate;
}
Example #2
0
void VorbisLMC::DecodeWork()
{
   void          *pOutBuffer;
   Error          Err;
   int32          iValue;
   int32          section, ret;
   OutputInfo    *info;
   vorbis_info   *vi;
   uint32         bytesCopied, bytesPerFrame;
   int            bitrateLoops = 0;

   assert(m_pPmi);
   assert(m_pPmo);

   m_pSleepSem->Wait();
   m_pPmi->Wake();

   Err = CanDecode();
   if (Err == kError_Interrupt)
      return;
   if (Err != kError_NoErr)
   {
       m_pContext->log->Error("CanDecode returned false.\n");
       if (m_decodeInfo.sendInfo)
       {
           ReportStatus(szCannotDecode);
           m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError));
       }
       else
           ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent());
       return;
   }

   Err = ExtractMediaInfo();
   if (Err == kError_Interrupt)
      return;

   if (IsError(Err))
   {
       m_pContext->log->Error("ExtractMediaInfo failed: %d\n", Err);
       if (m_decodeInfo.sendInfo)
       {
           ReportStatus(szCannotDecode);
           m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError));
       }
       else
           ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent());
       return;
   }

   if (!m_bInit)
   {
       Err = InitDecoder();
       if (Err == kError_Interrupt)
          return;

       if (IsError(Err))
       {
           m_pContext->log->Error("Initializing the decoder failed: %d\n", Err);
           ReportError("Initializing the decoder failed.");
    
           return;
       }
   }

   m_pContext->prefs->GetPrefInt32(kDecoderThreadPriorityPref, &iValue);
   m_decoderThread->SetPriority(iValue);

   bytesCopied = 0;
   bytesPerFrame = 1;
   for (m_frameCounter = 0; !m_bExit;)
   {
      if (m_bPause)
      {
          m_pPauseSem->Wait();
          if (m_bExit)
              break;
      }

      if (m_newPos >= 0)
      {   
          ov_time_seek(&m_vf, (double)(m_newPos / iFramesPerSecond));
          m_frameCounter = m_newPos - 1;
          m_newPos = -1;
          bytesCopied = bytesPerFrame;
      }

      if (bytesCopied >= bytesPerFrame)
      {
          m_frameCounter += bytesCopied / bytesPerFrame;
          bytesCopied %= bytesPerFrame;
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(
             new PMOTimeInfoEvent(m_frameCounter));

          bitrateLoops++;
          if (bitrateLoops == iBitrateLoopsPerUpdate && m_decodeInfo.sendInfo)
          {
             int b;

             b = ov_bitrate_instant(&m_vf),
             vi = ov_info(&m_vf, -1);
             VorbisInfoEvent *mie = new VorbisInfoEvent(b,
                                           vi->channels, 
                                           vi->rate, 
                                           1. / (float)iFramesPerSecond);
             m_pTarget->AcceptEvent(mie);

             bitrateLoops = 0;
          }
      }

      Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize);
      if (Err == kError_Interrupt)
      {
          break;
      }
      if (Err == kError_BufferTooSmall)
      {
          if (Sleep())
             break;

          continue;
      }
      if (Err != kError_NoErr)
      {
          ReportError(szFailWrite);
          m_pContext->log->Error("LMC: Cannot write to eventbuffer: %s (%d)\n",
                                  m_szError, Err);
          break;
      } 

      section = -1;
      ret = ov_read(&m_vf, (char *)pOutBuffer, iDecodeBlockSize, 
                    0, 2, 1, &section);
      if (ret == 0)
      {
         m_pOutputBuffer->EndWrite(0);
         break;
      }

      if (section != m_section)
      { 
          vi = ov_info(&m_vf, -1);

          info = new OutputInfo;
          info->bits_per_sample = 16;
          info->number_of_channels = m_channels = vi->channels;
          info->samples_per_second = m_rate = vi->rate;
          info->samples_per_frame = vi->rate / iFramesPerSecond;
          info->max_buffer_size = 16384;
          m_frameCounter = 0;
          bytesCopied = 0;
          bytesPerFrame = (vi->rate / iFramesPerSecond) * 
                          sizeof(ogg_int16_t) * vi->channels;
          m_section = section;
       
          m_pOutputBuffer->EndWrite(0);
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOInitEvent(info));
          ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(
             new PMOTimeInfoEvent(m_frameCounter));

          Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize);
          if (Err != kError_NoErr)
          {
             assert(0);
          }

          vorbis_comment *comment;

          comment = ov_comment(&m_vf, -1);
          if (comment)
          {
              PlaylistItem *plItem = m_pContext->plm->GetCurrentItem();
              if (plItem)
              {
                  MetaData mdata = plItem->GetMetaData();
                  string iso;

                  char *temp;
                  temp = vorbis_comment_query(comment, "title", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetTitle(iso);
                  }
 
                  temp = vorbis_comment_query(comment, "artist", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetArtist(iso);
                  }

                  temp = vorbis_comment_query(comment, "album", 0);
                  if (temp)
                  {
                      iso = ConvertToISO(temp);
                      mdata.SetAlbum(iso);
                  }

                  temp = vorbis_comment_query(comment, "tracknumber", 0);
                  if (temp)
                      mdata.SetTrack(atoi(temp));

                  plItem->SetMetaData(&mdata);
                  m_pContext->target->AcceptEvent(
                             new PlaylistCurrentItemInfoEvent(plItem, 
                                                              m_pContext->plm));

              }
          }
      }
      if(ret <0) 
         ret=0; // hole/error in data - we can safely ignore this
      m_pOutputBuffer->EndWrite(ret);

      bytesCopied += ret;
   }
   ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOQuitEvent());
   ov_clear(&m_vf);

   return;
}
Example #3
0
/* public */
static void
vorbis_stream_decode(struct decoder *decoder,
		     struct input_stream *input_stream)
{
	GError *error = NULL;
	OggVorbis_File vf;
	struct vorbis_input_stream vis;
	struct audio_format audio_format;
	float total_time;
	int current_section;
	int prev_section = -1;
	long ret;
	char chunk[OGG_CHUNK_SIZE];
	long bitRate = 0;
	long test;
	const vorbis_info *vi;
	enum decoder_command cmd = DECODE_COMMAND_NONE;

	if (ogg_stream_type_detect(input_stream) != VORBIS)
		return;

	/* rewind the stream, because ogg_stream_type_detect() has
	   moved it */
	input_stream_lock_seek(input_stream, 0, SEEK_SET, NULL);

	if (!vorbis_is_open(&vis, &vf, decoder, input_stream))
		return;

	vi = ov_info(&vf, -1);
	if (vi == NULL) {
		g_warning("ov_info() has failed");
		return;
	}

	if (!audio_format_init_checked(&audio_format, vi->rate,
				       SAMPLE_FORMAT_S16,
				       vi->channels, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return;
	}

	total_time = ov_time_total(&vf, -1);
	if (total_time < 0)
		total_time = 0;

	decoder_initialized(decoder, &audio_format, vis.seekable, total_time);

	do {
		if (cmd == DECODE_COMMAND_SEEK) {
			double seek_where = decoder_seek_where(decoder);
			if (0 == ov_time_seek_page(&vf, seek_where)) {
				decoder_command_finished(decoder);
			} else
				decoder_seek_error(decoder);
		}

		ret = ov_read(&vf, chunk, sizeof(chunk),
			      OGG_DECODE_USE_BIGENDIAN, 2, 1, &current_section);
		if (ret == OV_HOLE) /* bad packet */
			ret = 0;
		else if (ret <= 0)
			/* break on EOF or other error */
			break;

		if (current_section != prev_section) {
			char **comments;

			vi = ov_info(&vf, -1);
			if (vi == NULL) {
				g_warning("ov_info() has failed");
				break;
			}

			if (vi->rate != (long)audio_format.sample_rate ||
			    vi->channels != (int)audio_format.channels) {
				/* we don't support audio format
				   change yet */
				g_warning("audio format change, stopping here");
				break;
			}

			comments = ov_comment(&vf, -1)->user_comments;
			vorbis_send_comments(decoder, input_stream, comments);

			struct replay_gain_info rgi;
			if (vorbis_comments_to_replay_gain(&rgi, comments))
				decoder_replay_gain(decoder, &rgi);

			prev_section = current_section;
		}

		if ((test = ov_bitrate_instant(&vf)) > 0)
			bitRate = test / 1000;

		cmd = decoder_data(decoder, input_stream,
				   chunk, ret,
				   bitRate);
	} while (cmd != DECODE_COMMAND_STOP);

	ov_clear(&vf);
}
Example #4
0
/////////////////////////////////////////////////////////////////////////////////////////
//Audio callback
/////////////////////////////////////////////////////////////////////////////////////////
static void oggDecodeThread(void *_buf2, unsigned int numSamples, void *pdata){
    short *_buf = (short *)_buf2;
    //static short OGG_mixBuffer[PSP_NUM_AUDIO_SAMPLES * 2 * 2]__attribute__ ((aligned(64)));
    //static unsigned long OGG_tempmixleft = 0;
	int current_section;

	if (OGG_isPlaying) {	// Playing , so mix up a buffer
        outputInProgress = 1;
		while (OGG_tempmixleft < numSamples) {	//  Not enough in buffer, so we must mix more
			unsigned long bytesRequired = (numSamples - OGG_tempmixleft) * 4;	// 2channels, 16bit = 4 bytes per sample
			unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, &current_section); //libtremor
            //unsigned long ret = ov_read(&OGG_VorbisFile, (char *) &OGG_mixBuffer[OGG_tempmixleft * 2], bytesRequired, 0, 2, 1, &current_section); //ogg-vorbis
			if (!ret) {	//EOF
                OGG_isPlaying = 0;
				OGG_eos = 1;
                outputInProgress = 0;
				return;
			} else if (ret < 0) {
				if (ret == OV_HOLE)
					continue;
                OGG_isPlaying = 0;
				OGG_eos = 1;
                outputInProgress = 0;
				return;
			}
			OGG_tempmixleft += ret / 4;	// back down to sample num
		}
        OGG_info.instantBitrate = ov_bitrate_instant(&OGG_VorbisFile);
		OGG_milliSeconds = ov_time_tell(&OGG_VorbisFile);

        //Check for playing speed:
        if (OGG_playingSpeed){
            if (ov_raw_seek(&OGG_VorbisFile, ov_raw_tell(&OGG_VorbisFile) + OGG_playingDelta) != 0)
                OGG_setPlayingSpeed(0);
        }

		if (OGG_tempmixleft >= numSamples) {	//  Buffer has enough, so copy across
			int count, count2;
			short *_buf2;
			for (count = 0; count < numSamples; count++) {
				count2 = count + count;
				_buf2 = _buf + count2;
                //Volume boost:
                if (OGG_volume_boost){
                    *(_buf2) = volume_boost(&OGG_mixBuffer[count2], &OGG_volume_boost);
                    *(_buf2 + 1) = volume_boost(&OGG_mixBuffer[count2 + 1], &OGG_volume_boost);
                }else{
                    // Double up for stereo
                    *(_buf2) = OGG_mixBuffer[count2];
                    *(_buf2 + 1) = OGG_mixBuffer[count2 + 1];
                }
			}
			//  Move the pointers
			OGG_tempmixleft -= numSamples;
			//  Now shuffle the buffer along
			for (count = 0; count < OGG_tempmixleft * 2; count++)
			    OGG_mixBuffer[count] = OGG_mixBuffer[numSamples * 2 + count];

		}
        outputInProgress = 0;
    } else {			//  Not Playing , so clear buffer
        int count;
        for (count = 0; count < numSamples * 2; count++)
            *(_buf + count) = 0;
	}
}
Example #5
0
/* public */
static void
vorbis_stream_decode(struct decoder *decoder,
		     struct input_stream *input_stream)
{
	GError *error = NULL;

	if (ogg_codec_detect(decoder, input_stream) != OGG_CODEC_VORBIS)
		return;

	/* rewind the stream, because ogg_codec_detect() has
	   moved it */
	input_stream_lock_seek(input_stream, 0, SEEK_SET, NULL);

	struct vorbis_input_stream vis;
	OggVorbis_File vf;
	if (!vorbis_is_open(&vis, &vf, decoder, input_stream))
		return;

	const vorbis_info *vi = ov_info(&vf, -1);
	if (vi == NULL) {
		g_warning("ov_info() has failed");
		return;
	}

	struct audio_format audio_format;
	if (!audio_format_init_checked(&audio_format, vi->rate,
#ifdef HAVE_TREMOR
				       SAMPLE_FORMAT_S16,
#else
				       SAMPLE_FORMAT_FLOAT,
#endif
				       vi->channels, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return;
	}

	float total_time = ov_time_total(&vf, -1);
	if (total_time < 0)
		total_time = 0;

	decoder_initialized(decoder, &audio_format, vis.seekable, total_time);

	enum decoder_command cmd = decoder_get_command(decoder);

#ifdef HAVE_TREMOR
	char buffer[4096];
#else
	float buffer[2048];
	const int frames_per_buffer =
		G_N_ELEMENTS(buffer) / audio_format.channels;
	const unsigned frame_size = sizeof(buffer[0]) * audio_format.channels;
#endif

	int prev_section = -1;
	unsigned kbit_rate = 0;

	do {
		if (cmd == DECODE_COMMAND_SEEK) {
			double seek_where = decoder_seek_where(decoder);
			if (0 == ov_time_seek_page(&vf, seek_where)) {
				decoder_command_finished(decoder);
			} else
				decoder_seek_error(decoder);
		}

		int current_section;

#ifdef HAVE_TREMOR
		long nbytes = ov_read(&vf, buffer, sizeof(buffer),
				      VORBIS_BIG_ENDIAN, 2, 1,
				      &current_section);
#else
		float **per_channel;
		long nframes = ov_read_float(&vf, &per_channel,
					     frames_per_buffer,
					     &current_section);
		long nbytes = nframes;
		if (nframes > 0) {
			vorbis_interleave(buffer,
					  (const float*const*)per_channel,
					  nframes, audio_format.channels);
			nbytes *= frame_size;
		}
#endif

		if (nbytes == OV_HOLE) /* bad packet */
			nbytes = 0;
		else if (nbytes <= 0)
			/* break on EOF or other error */
			break;

		if (current_section != prev_section) {
			vi = ov_info(&vf, -1);
			if (vi == NULL) {
				g_warning("ov_info() has failed");
				break;
			}

			if (vi->rate != (long)audio_format.sample_rate ||
			    vi->channels != (int)audio_format.channels) {
				/* we don't support audio format
				   change yet */
				g_warning("audio format change, stopping here");
				break;
			}

			char **comments = ov_comment(&vf, -1)->user_comments;
			vorbis_send_comments(decoder, input_stream, comments);

			struct replay_gain_info rgi;
			if (vorbis_comments_to_replay_gain(&rgi, comments))
				decoder_replay_gain(decoder, &rgi);

			prev_section = current_section;
		}

		long test = ov_bitrate_instant(&vf);
		if (test > 0)
			kbit_rate = test / 1000;

		cmd = decoder_data(decoder, input_stream,
				   buffer, nbytes,
				   kbit_rate);
	} while (cmd != DECODE_COMMAND_STOP);

	ov_clear(&vf);
}