Exemple #1
0
static PyObject * py_ogg_ogg_page_packets(PyObject *self, PyObject *args) {
  int size;
  int c_out;
  ogg_page * og;
  PyArg_ParseTuple(args, "s#", &og, &size);
  c_out = ogg_page_packets(og);
  return Py_BuildValue("i", c_out);
};
Exemple #2
0
static ChainState *
validate_ogg_page (ogg_page * page)
{
  gulong serialno;
  gint64 granule;
  ChainState *state;

  serialno = ogg_page_serialno (page);
  granule = ogg_page_granulepos (page);
  state = g_hash_table_lookup (eos_chain_states, GINT_TO_POINTER (serialno));

  fail_if (ogg_page_packets (page) == 0 && granule != -1,
      "Must have granulepos -1 when page has no packets, has %" G_GINT64_FORMAT,
      granule);

  if (ogg_page_bos (page)) {
    fail_unless (state == NULL, "Extraneous BOS flag on chain %u", serialno);

    state = g_new0 (ChainState, 1);
    g_hash_table_insert (eos_chain_states, GINT_TO_POINTER (serialno), state);
    state->serialno = serialno;
    state->last_granule = granule;
    state->codec = get_page_codec (page);

    /* check for things like BOS ordering, etc */
    switch (state->codec) {
      case CODEC_THEORA:
        /* check we have no vorbis/speex chains yet */
        g_hash_table_foreach (eos_chain_states, (GHFunc) fail_if_audio, NULL);
        break;
      case CODEC_VORBIS:
      case CODEC_SPEEX:
        /* no checks (yet) */
        break;
      case CODEC_UNKNOWN:
      default:
        break;
    }
  } else if (ogg_page_eos (page)) {
    fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno);
    state->eos = TRUE;
  } else {
    fail_unless (state != NULL, "Missing BOS flag on chain %u", serialno);
    fail_unless (!state->eos, "Data after EOS flag on chain %u", serialno);
  }

  if (granule != -1) {
    fail_unless (granule >= state->last_granule,
        "Granulepos out-of-order for chain %u: old=%" G_GINT64_FORMAT ", new="
        G_GINT64_FORMAT, serialno, state->last_granule, granule);
    state->last_granule = granule;
  }

  return state;
}
void SndSysSpeexSoundData::Initialize()
{
  ogg_sync_state oy;
  ogg_page og;
  ogg_packet op;
  ogg_stream_state os;

  // Process enough to get the header.
  ogg_sync_init(&oy);
  oy.data = m_DataStore.data;
  oy.storage = (int)m_DataStore.length;
  ogg_sync_wrote(&oy, (long)m_DataStore.length);
  ogg_sync_pageout(&oy, &og);
  ogg_stream_init(&os, ogg_page_serialno(&og));
  ogg_stream_pagein(&os, &og);
  ogg_stream_packetout(&os, &op);

  SpeexHeader* header = speex_packet_to_header((char*)op.packet, op.bytes);
  m_SoundFormat.Channels = header->nb_channels;
  m_SoundFormat.Freq = header->rate;

  // Is there a better way to do this?
  // Get number of packets (-1 as the second contains misc info).
  int count = -1;
  while(ogg_sync_pageout(&oy, &og)==1)
  {
    ogg_stream_pagein(&os, &og);
    count += ogg_page_packets(&og);
  }

  m_FrameCount = header->frames_per_packet * count;

  // Free memory.
  speex_header_free(header);
  ogg_stream_clear(&os);

  // No need to call this again.
  m_bInfoReady=true;
}
Exemple #4
0
void CAOggFLACDecoder::InPacket(const void* inInputData, const AudioStreamPacketDescription* inPacketDescription)
{
    if (!mCompressionInitialized)
        CODEC_THROW(kAudioCodecUnspecifiedError);

    ogg_page op;

    if (!WrapOggPage(&op, inInputData, inPacketDescription->mDataByteSize + inPacketDescription->mStartOffset, inPacketDescription->mStartOffset))
        CODEC_THROW(kAudioCodecUnspecifiedError);

    dbg_printf("[ oFD]   : [%08lx] InPacket() [%4.4s] %ld\n", (UInt32) this, (char *) (static_cast<const Byte*> (inInputData) + inPacketDescription->mStartOffset),
               ogg_page_pageno(&op));

    ogg_packet opk;
    SInt32 packet_count = 0;
    int oret;
    AudioStreamPacketDescription flac_packet_desc = {0, 0, 0};
    UInt32 page_packets = ogg_page_packets(&op);

    ogg_stream_pagein(&mO_st, &op);
    while ((oret = ogg_stream_packetout(&mO_st, &opk)) != 0) {
        if (oret < 0) {
            page_packets--;
            continue;
        }

        packet_count++;

        flac_packet_desc.mDataByteSize = opk.bytes;

        CAFLACDecoder::InPacket(opk.packet, &flac_packet_desc);
    }

    if (packet_count > 0)
        complete_pages += 1;

    mFramesBufferedList.push_back(OggPagePacket(packet_count, inPacketDescription->mVariableFramesInPacket));
}
Exemple #5
0
static void _ready_page(StreamInfoPtr si)
{
    UInt32 len = si->og.header_len + si->og.body_len;
    Float64 pos;

    if (si->og_buffer_size < len) {
        si->og_buffer = realloc(si->og_buffer, len);
        si->og_buffer_size = len;
    }
    BlockMoveData(si->og.header, si->og_buffer, si->og.header_len);
    BlockMoveData(si->og.body, si->og_buffer + si->og.header_len,
                  si->og.body_len);
    si->og.header = si->og_buffer;
    si->og.body = si->og_buffer + si->og.header_len;
    si->og_ready = true;
    si->acc_packets -= ogg_page_packets(&si->og);
    if (ogg_page_granulepos(&si->og) != -1) {
        si->og_grpos = ogg_page_granulepos(&si->og);
        if (si->si_v.grpos_shift > 0) {
            /* with theora, si->og_grpos represents total number of frames */
            ogg_int64_t frames = si->og_grpos >> si->si_v.grpos_shift;
            si->og_grpos = frames + si->og_grpos -
                (frames << si->si_v.grpos_shift);
        }
Exemple #6
0
static int
spx_read_header (SF_PRIVATE * psf)
{	static SpeexStereoState STEREO_INIT = SPEEX_STEREO_STATE_INIT ;

	OGG_PRIVATE* odata = psf->container_data ;
	SPX_PRIVATE* spx = psf->codec_data ;

	ogg_int64_t page_granule = 0 ;
	int stream_init = 0 ;
	int	page_nb_packets = 0 ;
	int packet_count = 0 ;
	int enh_enabled = 1 ;
	int force_mode = -1 ;
	char * data ;
	int nb_read ;
	int lookahead ;

printf ("%s %d\n", __func__, __LINE__) ;

	psf_log_printf (psf, "Speex header\n") ;
	odata->eos = 0 ;

	/* Reset ogg stuff which has already been used in src/ogg.c. */
	ogg_stream_reset (&odata->ostream) ;
	ogg_sync_reset (&odata->osync) ;

	/* Seek to start of stream. */
	psf_fseek (psf, 0, SEEK_SET) ;

	/* Initialize. */
	ogg_sync_init (&odata->osync) ;
	speex_bits_init (&spx->bits) ;

	/* Set defaults. */
	psf->sf.channels = -1 ;
	psf->sf.samplerate = 0 ;
	spx->stereo = STEREO_INIT ;

	/* Get a pointer to the ogg buffer and read data into it. */
	data = ogg_sync_buffer (&odata->osync, OGG_SPX_READ_SIZE) ;
	nb_read = psf_fread (data, 1, OGG_SPX_READ_SIZE, psf) ;
	ogg_sync_wrote (&odata->osync, nb_read) ;

	/* Now we chew on Ogg packets. */
	while (ogg_sync_pageout (&odata->osync, &odata->opage) == 1)
	{	if (stream_init == 0)
		{	ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
			stream_init = 1 ;
			} ;

		if (ogg_page_serialno (&odata->opage) != odata->ostream.serialno)
		{	/* so all streams are read. */
			ogg_stream_reset_serialno (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
			} ;

		/*Add page to the bitstream*/
		ogg_stream_pagein (&odata->ostream, &odata->opage) ;
		page_granule = ogg_page_granulepos (&odata->opage) ;
		page_nb_packets = ogg_page_packets (&odata->opage) ;

		/*Extract all available packets*/
		while (odata->eos == 0 && ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1)
		{	if (odata->opacket.bytes >= 8 && memcmp (odata->opacket.packet, "Speex   ", 8) == 0)
			{	spx->serialno = odata->ostream.serialno ;
				} ;

			if (spx->serialno == -1 || odata->ostream.serialno != spx->serialno)
				break ;

			if (packet_count == 0)
			{	spx->state = spx_header_read (psf, &odata->opacket, enh_enabled, force_mode) ;
				if (! spx->state)
					break ;

				speex_decoder_ctl (spx->state, SPEEX_GET_LOOKAHEAD, &lookahead) ;
				if (spx->nframes == 0)
					spx->nframes = 1 ;
				}
			else if (packet_count == 1)
			{	spx_print_comments ((const char*) odata->opacket.packet, odata->opacket.bytes) ;
				}
			else if (packet_count < 2 + spx->header.extra_headers)
			{	/* Ignore extra headers */
				}
			packet_count ++ ;
			} ;
		} ;

	psf_log_printf (psf, "End\n") ;

	psf_log_printf (psf, "packet_count %d\n", packet_count) ;
	psf_log_printf (psf, "page_nb_packets %d\n", page_nb_packets) ;
	psf_log_printf (psf, "page_granule %lld\n", page_granule) ;

	return 0 ;
} /* spx_read_header */
Exemple #7
0
int main(int argc, char **argv)
{
   int c;
   int option_index = 0;
   char *inFile, *outFile;
   FILE *fin, *fout=NULL;
   short out[MAX_FRAME_SIZE];
   short output[MAX_FRAME_SIZE];
   int frame_size=0, granule_frame_size=0;
   void *st=NULL;
   CELTMode *mode=NULL;
   int packet_count=0;
   int stream_init = 0;
   int quiet = 0;
   ogg_int64_t page_granule=0, last_granule=0;
   int skip_samples=0, page_nb_packets;
   struct option long_options[] =
   {
      {"help", no_argument, NULL, 0},
      {"quiet", no_argument, NULL, 0},
      {"version", no_argument, NULL, 0},
      {"version-short", no_argument, NULL, 0},
      {"rate", required_argument, NULL, 0},
      {"mono", no_argument, NULL, 0},
      {"stereo", no_argument, NULL, 0},
      {"packet-loss", required_argument, NULL, 0},
      {0, 0, 0, 0}
   };
   ogg_sync_state oy;
   ogg_page       og;
   ogg_packet     op;
   ogg_stream_state os;
   int enh_enabled;
   int nframes=2;
   int print_bitrate=0;
   int close_in=0;
   int eos=0;
   int forceMode=-1;
   int audio_size=0;
   float loss_percent=-1;
   int channels=-1;
   int rate=0;
   int extra_headers=0;
   int wav_format=0;
   int lookahead=0;
   int celt_serialno = -1;
   int firstpacket = 1;

   enh_enabled = 1;

   /*Process options*/
   while(1)
   {
      c = getopt_long (argc, argv, "hvV",
                       long_options, &option_index);
      if (c==-1)
         break;
      
      switch(c)
      {
      case 0:
         if (strcmp(long_options[option_index].name,"help")==0)
         {
            usage();
            exit(0);
         } else if (strcmp(long_options[option_index].name,"quiet")==0)
         {
            quiet = 1;
         } else if (strcmp(long_options[option_index].name,"version")==0)
         {
            version();
            exit(0);
         } else if (strcmp(long_options[option_index].name,"version-short")==0)
         {
            version_short();
            exit(0);
         } else if (strcmp(long_options[option_index].name,"mono")==0)
         {
            channels=1;
         } else if (strcmp(long_options[option_index].name,"stereo")==0)
         {
            channels=2;
         } else if (strcmp(long_options[option_index].name,"rate")==0)
         {
            rate=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"packet-loss")==0)
         {
            loss_percent = atof(optarg);
         }
         break;
      case 'h':
         usage();
         exit(0);
         break;
      case 'v':
         version();
         exit(0);
         break;
      case 'V':
         print_bitrate=1;
         break;
      case '?':
         usage();
         exit(1);
         break;
      }
   }
   if (argc-optind!=2 && argc-optind!=1)
   {
      usage();
      exit(1);
   }
   inFile=argv[optind];

   if (argc-optind==2)
      outFile=argv[optind+1];
   else
      outFile = "";
   wav_format = strlen(outFile)>=4 && (
                                       strcmp(outFile+strlen(outFile)-4,".wav")==0
                                       || strcmp(outFile+strlen(outFile)-4,".WAV")==0);
   /*Open input file*/
   if (strcmp(inFile, "-")==0)
   {
#if defined WIN32 || defined _WIN32
      _setmode(_fileno(stdin), _O_BINARY);
#endif
      fin=stdin;
   }
   else 
   {
      fin = fopen(inFile, "rb");
      if (!fin)
      {
         perror(inFile);
         exit(1);
      }
      close_in=1;
   }


   /*Init Ogg data struct*/
   ogg_sync_init(&oy);
   
   /*Main decoding loop*/
   
   while (1)
   {
      char *data;
      int i, nb_read;
      /*Get the ogg buffer for writing*/
      data = ogg_sync_buffer(&oy, 200);
      /*Read bitstream from input file*/
      nb_read = fread(data, sizeof(char), 200, fin);      
      ogg_sync_wrote(&oy, nb_read);

      /*Loop for all complete pages we got (most likely only one)*/
      while (ogg_sync_pageout(&oy, &og)==1)
      {
         if (stream_init == 0) {
            ogg_stream_init(&os, ogg_page_serialno(&og));
            stream_init = 1;
         }
	 if (ogg_page_serialno(&og) != os.serialno) {
	    /* so all streams are read. */
	    ogg_stream_reset_serialno(&os, ogg_page_serialno(&og));
	 }
         /*Add page to the bitstream*/
         ogg_stream_pagein(&os, &og);
         page_granule = ogg_page_granulepos(&og);
         page_nb_packets = ogg_page_packets(&og);
         if (page_granule>0 && frame_size)
         {
            /* FIXME: shift the granule values if --force-* is specified */
            skip_samples = frame_size*(page_nb_packets*granule_frame_size*nframes - (page_granule-last_granule))/granule_frame_size;
            if (ogg_page_eos(&og))
               skip_samples = -skip_samples;
            /*else if (!ogg_page_bos(&og))
               skip_samples = 0;*/
         } else
         {
            skip_samples = 0;
         }
         /*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/
         last_granule = page_granule;
         /*Extract all available packets*/
         while (!eos && ogg_stream_packetout(&os, &op) == 1 && op.bytes>=8)
         {
	    if (!memcmp(op.packet, "CELT    ", 8)) {
	       celt_serialno = os.serialno;
	    }
	    if (celt_serialno == -1 || os.serialno != celt_serialno)
	       break;
            /*If first packet, process as CELT header*/
            if (packet_count==0)
            {
               st = process_header(&op, enh_enabled, &frame_size, &granule_frame_size, &rate, &nframes, forceMode, &channels, &lookahead, &extra_headers, quiet, &mode);
               if (!st)
                  exit(1);
               if (!nframes)
                  nframes=1;
               fout = out_file_open(outFile, rate, &channels);

            } else if (packet_count==1)
            {
               if (!quiet)
                  print_comments((char*)op.packet, op.bytes);
            } else if (packet_count<=1+extra_headers)
            {
               /* Ignore extra headers */
            } else {
               int lost=0;
               if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent)
                  lost=1;

               /*End of stream condition*/
               if (op.e_o_s && os.serialno == celt_serialno) /* don't care for anything except celt eos */
                  eos=1;
	       
               {
                  int ret;
                  /*Decode frame*/
                  if (!lost)
                     ret = celt_decode(st, (unsigned char*)op.packet, op.bytes, output);
                  else
                     ret = celt_decode(st, NULL, 0, output);

                  /*for (i=0;i<frame_size*channels;i++)
                    printf ("%d\n", (int)output[i]);*/

                  if (ret!=0)
                  {
                     fprintf (stderr, "Decoding error: corrupted stream?\n");
                     break;
                  }

                  if (print_bitrate) {
                     celt_int32 tmp=op.bytes;
                     char ch=13;
                     fputc (ch, stderr);
                     fprintf (stderr, "Bitrate in use: %d bytes/packet     ", tmp);
                  }
                  /*Convert to short and save to output file*/
                  if (strlen(outFile)!=0)
                  {
                     for (i=0;i<frame_size*channels;i++)
                        out[i]=le_short(output[i]);
                  } else {
                     for (i=0;i<frame_size*channels;i++)
                        out[i]=output[i];
                  }
                  {
                     int frame_offset = 0;
                     int new_frame_size = frame_size;
                     /*printf ("packet %d %d\n", packet_no, skip_samples);*/
                     /*fprintf (stderr, "packet %d %d %d\n", packet_no, skip_samples, lookahead);*/
                     if (firstpacket == 1)
                     {
                        /*printf ("chopping first packet\n");*/
                        new_frame_size -= lookahead;
                        frame_offset = lookahead;
                        firstpacket = 0;
                     }
                     if (new_frame_size>0)
                     {  
#if defined WIN32 || defined _WIN32
                        if (strlen(outFile)==0)
                           WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels);
                        else
#endif
                           fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout);
                  
                        audio_size+=sizeof(short)*new_frame_size*channels;
                     }
                  }
               }
            }
            packet_count++;
         }
      }
      if (feof(fin))
         break;

   }

   if (fout && wav_format)
   {
      if (fseek(fout,4,SEEK_SET)==0)
      {
         int tmp;
         tmp = le_int(audio_size+36);
         fwrite(&tmp,4,1,fout);
         if (fseek(fout,32,SEEK_CUR)==0)
         {
            tmp = le_int(audio_size);
            fwrite(&tmp,4,1,fout);
         } else
         {
            fprintf (stderr, "First seek worked, second didn't\n");
         }
      } else {
         fprintf (stderr, "Cannot seek on wave file, size will be incorrect\n");
      }
   }

   if (st)
   {
      celt_decoder_destroy(st);
      celt_mode_destroy(mode);
   } else {
      fprintf (stderr, "This doesn't look like a CELT file\n");
   }
   if (stream_init)
      ogg_stream_clear(&os);
   ogg_sync_clear(&oy);

#if defined WIN32 || defined _WIN32
   if (strlen(outFile)==0)
      WIN_Audio_close ();
#endif

   if (close_in)
      fclose(fin);
   if (fout != NULL)
      fclose(fout);   

   return 0;
}
Exemple #8
0
int writeFrame(uint8_t *framePcmBytes, unsigned int frameByteCount) {
    int cur_frame_size = frame_size;
    _packetId++;

    opus_int32 nb_samples = frameByteCount / 2;
    total_samples += nb_samples;
    if (nb_samples < frame_size) {
        op.e_o_s = 1;
    } else {
        op.e_o_s = 0;
    }

    int nbBytes = 0;

    if (nb_samples != 0) {
        uint8_t *paddedFrameBytes = framePcmBytes;
        int freePaddedFrameBytes = 0;

        if (nb_samples < cur_frame_size) {
            paddedFrameBytes = malloc(cur_frame_size * 2);
            freePaddedFrameBytes = 1;
            memcpy(paddedFrameBytes, framePcmBytes, frameByteCount);
            memset(paddedFrameBytes + nb_samples * 2, 0, cur_frame_size * 2 - nb_samples * 2);
        }

        nbBytes = opus_encode(_encoder, (opus_int16 *)paddedFrameBytes, cur_frame_size, _packet, max_frame_bytes / 10);
        if (freePaddedFrameBytes) {
            free(paddedFrameBytes);
            paddedFrameBytes = NULL;
        }

        if (nbBytes < 0) {
            LOGE("Encoding failed: %s. Aborting.", opus_strerror(nbBytes));
            return 0;
        }

        enc_granulepos += cur_frame_size * 48000 / coding_rate;
        size_segments = (nbBytes + 255) / 255;
        min_bytes = min(nbBytes, min_bytes);
    }

    while ((((size_segments <= 255) && (last_segments + size_segments > 255)) || (enc_granulepos - last_granulepos > max_ogg_delay)) && ogg_stream_flush_fill(&os, &og, 255 * 255)) {
        if (ogg_page_packets(&og) != 0) {
            last_granulepos = ogg_page_granulepos(&og);
        }

        last_segments -= og.header[26];
        int writtenPageBytes = writeOggPage(&og, _fileOs);
        if (writtenPageBytes != og.header_len + og.body_len) {
            LOGE("Error: failed writing data to output stream");
            return 0;
        }
        bytes_written += writtenPageBytes;
        pages_out++;
    }

    op.packet = (unsigned char *)_packet;
    op.bytes = nbBytes;
    op.b_o_s = 0;
    op.granulepos = enc_granulepos;
    if (op.e_o_s) {
        op.granulepos = ((total_samples * 48000 + rate - 1) / rate) + header.preskip;
    }
    op.packetno = 2 + _packetId;
    ogg_stream_packetin(&os, &op);
    last_segments += size_segments;

    while ((op.e_o_s || (enc_granulepos + (frame_size * 48000 / coding_rate) - last_granulepos > max_ogg_delay) || (last_segments >= 255)) ? ogg_stream_flush_fill(&os, &og, 255 * 255) : ogg_stream_pageout_fill(&os, &og, 255 * 255)) {
        if (ogg_page_packets(&og) != 0) {
            last_granulepos = ogg_page_granulepos(&og);
        }
        last_segments -= og.header[26];
        int writtenPageBytes = writeOggPage(&og, _fileOs);
        if (writtenPageBytes != og.header_len + og.body_len) {
            LOGE("Error: failed writing data to output stream");
            return 0;
        }
        bytes_written += writtenPageBytes;
        pages_out++;
    }

    return 1;
}
Exemple #9
0
int AudioStreamPlaybackSpeex::mix(int16_t *p_buffer, int p_frames) {

	//printf("update, loops %i, read ofs %i\n", (int)loops, read_ofs);
	//printf("playing %i, paused %i\n", (int)playing, (int)paused);

	if (!active || !playing || !data.size())
		return 0;

	/*
	if (read_ofs >= data.size()) {
		if (loops) {
			reload();
			++loop_count;
		} else {
			return;
		};
	};
	*/

	int todo = p_frames;
	if (todo < page_size) {
		return 0;
	};

	int eos = 0;

	while (todo > page_size) {

		int ret = 0;
		while ((todo > page_size && packets_available && !eos) || (ret = ogg_sync_pageout(&oy, &og)) == 1) {

			if (!packets_available) {
				/*Add page to the bitstream*/
				ogg_stream_pagein(&os, &og);
				page_granule = ogg_page_granulepos(&og);
				page_nb_packets = ogg_page_packets(&og);
				packet_no = 0;
				if (page_granule > 0 && frame_size) {
					skip_samples = page_nb_packets * frame_size * nframes - (page_granule - last_granule);
					if (ogg_page_eos(&og))
						skip_samples = -skip_samples;
					/*else if (!ogg_page_bos(&og))
					skip_samples = 0;*/
				} else {
					skip_samples = 0;
				}

				last_granule = page_granule;
				packets_available = true;
			}
			/*Extract all available packets*/
			while (todo > page_size && !eos) {

				if (ogg_stream_packetout(&os, &op) != 1) {
					packets_available = false;
					break;
				}

				packet_no++;

				/*End of stream condition*/
				if (op.e_o_s)
					eos = 1;

				/*Copy Ogg packet to Speex bitstream*/
				speex_bits_read_from(&bits, (char *)op.packet, op.bytes);

				for (int j = 0; j != nframes; j++) {

					int16_t *out = p_buffer;

					int ret;
					/*Decode frame*/
					ret = speex_decode_int(st, &bits, out);

					/*for (i=0;i<frame_size*channels;i++)
					  printf ("%d\n", (int)output[i]);*/

					if (ret == -1) {
						printf("decode returned -1\n");
						break;
					};
					if (ret == -2) {
						OS::get_singleton()->printerr("Decoding error: corrupted stream?\n");
						break;
					}
					if (speex_bits_remaining(&bits) < 0) {
						OS::get_singleton()->printerr("Decoding overflow: corrupted stream?\n");
						break;
					}
					//if (channels==2)
					//	speex_decode_stereo_int(output, frame_size, &stereo);

					/*Convert to short and save to output file*/
					for (int i = 0; i < frame_size * stream_channels; i++) {
						out[i] = le_short(out[i]);
					}

					{

						int new_frame_size = frame_size;

						/*printf ("packet %d %d\n", packet_no, skip_samples);*/
						if (packet_no == 1 && j == 0 && skip_samples > 0) {
							/*printf ("chopping first packet\n");*/
							new_frame_size -= skip_samples;
						}
						if (packet_no == page_nb_packets && skip_samples < 0) {
							int packet_length = nframes * frame_size + skip_samples;
							new_frame_size = packet_length - j * frame_size;
							if (new_frame_size < 0)
								new_frame_size = 0;
							if (new_frame_size > frame_size)
								new_frame_size = frame_size;
							/*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/
						}

						p_buffer += new_frame_size * stream_channels;
						todo -= new_frame_size;
					}
				}
			};
		};
		//todo = get_todo();

		//todo is still greater than page size, can write more
		if (todo > page_size || eos) {
			if (read_ofs < data.size()) {

				//char *buf;
				int nb_read = MIN(data.size() - read_ofs, READ_CHUNK);

				/*Get the ogg buffer for writing*/
				char *ogg_dst = ogg_sync_buffer(&oy, nb_read);
				/*Read bitstream from input file*/
				copymem(ogg_dst, &data[read_ofs], nb_read);
				read_ofs += nb_read;
				ogg_sync_wrote(&oy, nb_read);
			} else {
				if (loops) {
					reload();
					++loop_count;
					//break;
				} else {
					playing = false;
					unload();
					break;
				};
			}
		};
	};

	return p_frames - todo;
};
Exemple #10
0
void AudioStreamPlaybackSpeex::reload() {

	if (active)
		unload();

	if (!data.size())
		return;

	ogg_sync_init(&oy);
	speex_bits_init(&bits);

	read_ofs = 0;
	//	char *buf;

	int packet_count = 0;
	int extra_headers = 0;
	int stream_init = 0;

	page_granule = 0;
	last_granule = 0;
	skip_samples = 0;
	page_nb_packets = 0;
	packets_available = false;
	packet_no = 0;

	int eos = 0;

	do {

		/*Get the ogg buffer for writing*/
		int nb_read = MIN(data.size() - read_ofs, READ_CHUNK);
		char *ogg_dst = ogg_sync_buffer(&oy, nb_read);
		/*Read bitstream from input file*/
		copymem(ogg_dst, &data[read_ofs], nb_read);
		read_ofs += nb_read;
		ogg_sync_wrote(&oy, nb_read);

		/*Loop for all complete pages we got (most likely only one)*/
		while (ogg_sync_pageout(&oy, &og) == 1) {

			if (stream_init == 0) {
				ogg_stream_init(&os, ogg_page_serialno(&og));
				stream_init = 1;
			}
			/*Add page to the bitstream*/
			ogg_stream_pagein(&os, &og);
			page_granule = ogg_page_granulepos(&og);
			page_nb_packets = ogg_page_packets(&og);
			if (page_granule > 0 && frame_size) {
				skip_samples = page_nb_packets * frame_size * nframes - (page_granule - last_granule);
				if (ogg_page_eos(&og))
					skip_samples = -skip_samples;
				/*else if (!ogg_page_bos(&og))
				  skip_samples = 0;*/
			} else {
				skip_samples = 0;
			}

			last_granule = page_granule;
			/*Extract all available packets*/
			while (!eos && ogg_stream_packetout(&os, &op) == 1) {
				/*If first packet, process as Speex header*/
				if (packet_count == 0) {
					int rate = 0;
					int channels;
					st = process_header(&op, &frame_size, &rate, &nframes, &channels, &extra_headers);
					if (!nframes)
						nframes = 1;
					if (!st) {
						unload();
						return;
					};

					page_size = nframes * frame_size;
					stream_srate = rate;
					stream_channels = channels;
					stream_minbuff_size = page_size;

				} else if (packet_count == 1) {
				} else if (packet_count <= 1 + extra_headers) {
					/* Ignore extra headers */
				};
			};
			++packet_count;
		};

	} while (packet_count <= extra_headers);

	active = true;
}
Exemple #11
0
static int
init_vorbis(mm_file *mf, ogg_page *pg)
{
    int pkts = 0;
    int res = 0;
    int rval = 0;
    vorbis_block *vo_blk = NULL;
    vorbis_info *vo_info = NULL;
    vorbis_comment vo_comm;
    ogg_packet pkt;
    ogg_stream_state stream;

    assert(mf);
    vo_info = (vorbis_info *)xmalloc(sizeof(*vo_info));
    vorbis_info_init(vo_info);
    vorbis_comment_init(&vo_comm);
    ogg_stream_init(&stream, ogg_page_serialno(pg));

    if (ogg_page_packets(pg) != 1 || ogg_page_granulepos(pg) != 0) {
        goto end;
    }

    if (ogg_stream_pagein(&stream, pg) < 0)
        /* should not happen */
    {
        goto end;
    }

    /*
     * Three first packets must go successfully through the loop.
     */
    for (pkts = 0; pkts < 3; ++pkts) {
        while ((res = ogg_stream_packetpeek(&stream, &pkt)) != 1) {
            if (res < 0
                || get_page(mf, pg) <= 0
                || ogg_stream_pagein(&stream, pg) < 0) {
                rval = -1;
                goto end;
            }
        }

        switch (vorbis_synthesis_headerin(vo_info, &vo_comm, &pkt)) {
        case 0:
            break;

        case OV_EBADHEADER:
            INFO1("bad vorbis header");

        case OV_ENOTVORBIS:
        default:
            goto end;
        }

        /* decode successful so grab packet */
        ogg_stream_packetout(&stream, &pkt);
    }

    /* maybe print something about comment or etc? */

    mf->audio_ctx = (vorbis_dsp_state *)xmalloc(sizeof(*mf->audio_ctx));
    mf->audio = (ogg_stream_state *)xmalloc(sizeof(*mf->audio));
    vo_blk = (vorbis_block *)xmalloc(sizeof(*vo_blk));
    memcpy(mf->audio, &stream, sizeof(stream));
    vorbis_synthesis_init(mf->audio_ctx, vo_info);
    vorbis_block_init(mf->audio_ctx, vo_blk);
    mf->audio_info = vo_info;
    mf->audio_blk = vo_blk;
    rval = 1;
end:
    vorbis_comment_clear(&vo_comm);

    if (rval <= 0) {
        ogg_stream_clear(&stream);
        vorbis_info_clear(vo_info);
        free(vo_info);
    }

    return rval;
}
Exemple #12
0
static int
init_theora(mm_file *mf, ogg_page *pg)
{
    int pkts = 0;
    int res = 0;
    int rval = 0;
    theora_info *th_info = NULL;
    theora_comment th_comm;
    ogg_packet pkt;
    ogg_stream_state stream;

    assert(mf);
    th_info = (theora_info *)xmalloc(sizeof(*mf->video_info));
    theora_info_init(th_info);
    theora_comment_init(&th_comm);
    ogg_stream_init(&stream, ogg_page_serialno(pg));

    if (ogg_page_packets(pg) != 1 || ogg_page_granulepos(pg) != 0) {
        goto end;
    }

    if (ogg_stream_pagein(&stream, pg))
        /* should not happen */
    {
        goto end;
    }

    /* Three first packets must go successfully through the loop. */
    for (pkts = 0; pkts < 3; ++pkts) {
        while ((res = ogg_stream_packetpeek(&stream, &pkt)) != 1) {
            if (res < 0
                || get_page(mf, pg) <= 0
                || ogg_stream_pagein(&stream, pg) < 0) {
                rval = -1;
                goto end;
            }
        }

        switch (theora_decode_header(th_info, &th_comm, &pkt)) {
        case 0:
            break;

        case OC_VERSION:
        case OC_NEWPACKET:
            INFO1("incompatible theora file");

            /* fall through */
        case OC_BADHEADER:
        default:
            goto end;
        }

        /* decode successful so grab packet */
        ogg_stream_packetout(&stream, &pkt);
    }

    mf->video_ctx = (theora_state *)xmalloc(sizeof(*mf->video_ctx));
    mf->video = (ogg_stream_state *)xmalloc(sizeof(*mf->video));
    memcpy(mf->video, &stream, sizeof(stream));
    theora_decode_init(mf->video_ctx, th_info);
    mf->video_info = th_info;
    rval = 1;
end:
    theora_comment_clear(&th_comm);

    if (rval <= 0) {
        ogg_stream_clear(&stream);
        theora_info_clear(th_info);
        free(th_info);
        mf->video_info = NULL;
    }

    return rval;
}
Exemple #13
0
int main () {
  ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
  ogg_stream_state os; /* take physical pages, weld into a logical
                          stream of packets */
  ogg_page         og; /* one Ogg bitstream page. Vorbis packets are inside */
  ogg_packet       op; /* one raw packet of data for decode */

  struct stream *st = NULL;

  int r;
  char *buffer;
  int  bytes;
  int eos = 0;
  int i;
  int bufferSize = 4096;

  r = ogg_sync_init(&oy); /* Now we can read pages */
  assert(r == 0);

  while (1) { /* we repeat if the bitstream is chained */

    /* submit a 4k block to the libogg sync layer */
    buffer = ogg_sync_buffer(&oy, bufferSize);
    bytes = fread(buffer, 1, bufferSize, stdin);
    if (bytes == 0) {
      fprintf(stderr, "Got stdin EOF.\n");
      r = 0; break;
    }

    r = ogg_sync_wrote(&oy, bytes);
    assert(r == 0);

    /* Get the first page. */
    r = ogg_sync_pageout(&oy, &og);
    if (r == 0) {
      fprintf(stderr, "Need more data.\n");
      continue;
    } else if (r < 1) {
      /* have we simply run out of data?  If so, we're done. */
      if (bytes < bufferSize) break;

      /* error case.  Must not be Vorbis data */
      fprintf(stderr, "Input does not appear to be an Ogg bitstream.\n");
      r = 1; break;
    }
    assert(r == 1);

    /* Get the serial number and set up the rest of decode. */
    /* serialno first; use it to set up a logical stream */
    int serialno = ogg_page_serialno(&og);
    int packets = ogg_page_packets(&og);
    fprintf(stderr, "version: %d\n", ogg_page_version(&og));
    fprintf(stderr, "continued: %d\n", ogg_page_continued(&og));
    fprintf(stderr, "pageno: %ld\n", ogg_page_pageno(&og));
    fprintf(stderr, "serialno: %d\n", serialno);
    fprintf(stderr, "packets: %d\n", packets);
    fprintf(stderr, "granulepos: %lld\n", ogg_page_granulepos(&og));
    fprintf(stderr, "eos: %d\n", ogg_page_eos(&og));
    fprintf(stderr, "bos: %d\n", ogg_page_bos(&og));


    /* we need to get the correct "ogg_stream_state" struct based on the serialno */
    struct stream *s = st;
    while (1) {
      if (s == NULL) {
        fprintf(stderr, "creating struct stream for %d\n", serialno);
        s = malloc(sizeof(struct stream));
        s->next = NULL;
        s->serialno = serialno;
        ogg_stream_init(&s->os, serialno);
        if (st == NULL) {
          st = s;
        } else {
          /* have to set "s" to the last element of the "st" linked list */
          struct stream *t = st;
          while (1) {
            if (t->next == NULL) {
              t->next = s;
              break;
            } else {
              t = t->next;
            }
          }
        }
        break;
      }
      if (s->serialno == serialno) {
        break;
      }
      s = s->next;
    }
    assert(s->serialno == serialno);
    fprintf(stderr, "using struct stream %d\n", s->serialno);
    /* holy shit that sucked... */


    if (ogg_stream_pagein(&s->os, &og) < 0) {
      /* error; stream version mismatch perhaps */
      fprintf(stderr, "Error reading page of Ogg bitstream data.\n");
      r = 1; break;
    }

    /* iterate though the "packets" in the page */
    for (i=0; i<packets; i++) {
      fprintf(stderr, "  Reading packet %d.\n", i);
      r = ogg_stream_packetout(&s->os, &op);
      fprintf(stderr, "  Reading packet result %d.\n", r);
      if (r != 1) {
        /* no page? must not be vorbis */
        fprintf(stderr, "  Error reading packet.\n");
        r = 1; break;
      }

      /**
       * At this point, you'd pass the raw packet data to the vorbis decoder or
       * whatever your destination is....
       */
      fprintf(stderr, "    bytes: %ld\n", op.bytes);
      fprintf(stderr, "    b_o_s: %ld\n", op.b_o_s);
      fprintf(stderr, "    e_o_s: %ld\n", op.e_o_s);
      fprintf(stderr, "    granulepos: %lld\n", op.granulepos);
      fprintf(stderr, "    packetno: %lld\n", op.packetno);
    }

    fprintf(stderr, "\n");
  }

  /* OK, clean up the framer */
  ogg_sync_clear(&oy);

  fprintf(stderr,"\nDone.\n");
  return r;
}
Exemple #14
0
void OggOpusFile::EncodeChunks(void* pcmBuf, int numSamples, bool lastChunk)
{
    int numFrames = numSamples/PCM_SAMPLES_IN_FRAME;
    bool flush = false;
    for(int j = 0; j < numFrames; j++)
    {        
        if(j == (numFrames -1) && (lastChunk == true))
        {
            flush =true;
        }
        nb_samples=PCM_SAMPLES_IN_FRAME;//make it 160
        id++;
        int size_segments,cur_frame_size;
        ////frame_size=160 for 8k
        cur_frame_size=frame_size;

        /*Encode current frame*/          
        //Stereo: each pcm samples will have 2 short samples(L/R interlaced) so the num of bytes for each frame will be double to mono
        nbBytes=opus_multistream_encode	(st, (short*)pcmBuf + (j*PCM_SAMPLES_IN_FRAME*chan), cur_frame_size, m_outBuf, max_frame_bytes);
        if(nbBytes<0){
            fprintf(stderr, "Encoding failed: %s. Aborting.\n", opus_strerror(nbBytes));
            return;
        }

        nb_encoded+=cur_frame_size;
        enc_granulepos+=cur_frame_size*48000/coding_rate;
        total_bytes+=nbBytes;
        size_segments=(nbBytes+255)/255;
        peak_bytes=IMAX(nbBytes,peak_bytes);
        min_bytes=IMIN(nbBytes,min_bytes);                      
        //printf("TotalByes:%d\n", total_bytes);

        /*Flush early if adding this packet would make us end up with a
            continued page which we wouldn't have otherwise.*/
        while((((size_segments<=255)&&(last_segments+size_segments>255))|| (enc_granulepos-last_granulepos>max_ogg_delay)) 
                && ogg_stream_flush_fill(&os, &og,255*255)){
            if(ogg_page_packets(&og)!=0)  last_granulepos=ogg_page_granulepos(&og);

            last_segments-=og.header[26];
            ret=oe_write_page(&og);
            if(ret!=og.header_len+og.body_len){
                fprintf(stderr,"Error: failed writing data to output stream\n");
                exit(1);
            }
            bytes_written+=ret;
            pages_out++;
        }

        /*The downside of early reading is if the input is an exact
        multiple of the frame_size you'll get an extra frame that needs
        to get cropped off. The downside of late reading is added delay.
        If your ogg_delay is 120ms or less we'll assume you want the
        low delay behavior.*/
        // if(max_ogg_delay>5760){
        //     nb_samples = inopt.read_samples(inopt.readdata,input,frame_size);
        //     total_samples+=nb_samples;
        //     if(nb_samples==0)op.e_o_s=1;
        // } else nb_samples=-1;

        op.packet=(unsigned char *)m_outBuf;
        op.bytes=nbBytes;
        op.b_o_s=0;
        op.granulepos=enc_granulepos;
        if(flush == true){
            /*We compute the final GP as ceil(len*48k/input_rate)+preskip. When a
            resampling decoder does the matching floor((len-preskip)*input_rate/48k)
            conversion, the resulting output length will exactly equal the original
            input length when 0<input_rate<=48000.*/
            op.granulepos=((original_samples*48000+rate-1)/rate)+header.preskip;
        }
        op.packetno=2+id;
        ogg_stream_packetin(&os, &op);
        last_segments+=size_segments;

        /*If the stream is over or we're sure that the delayed flush will fire,
            go ahead and flush now to avoid adding delay.*/
        while(((flush == true) || (enc_granulepos+(frame_size*48000/coding_rate)-last_granulepos>max_ogg_delay)||
                (last_segments>=255))?
                ogg_stream_flush_fill(&os, &og,255*255):
                ogg_stream_pageout_fill(&os, &og,255*255)){

            if(ogg_page_packets(&og)!=0)last_granulepos=ogg_page_granulepos(&og);
            last_segments-=og.header[26];
            ret=oe_write_page(&og);
            if(ret!=og.header_len+og.body_len){
                fprintf(stderr,"Error: failed writing data to output stream\n");
                exit(1);
            }
            bytes_written+=ret;
            pages_out++;
        }
    }
}