Пример #1
0
void OggOpusFile::WriteHeader()
{  
    /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
    mapping families other than 0. The Channel Mapping Table is 2 bytes +
    1 byte per channel. Because the maximum number of channels is 255, the
    maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
    unsigned char header_data[276];
    const char         *opus_version;
    opus_version=opus_get_version_string();
    comment_init(&inopt.comments, &inopt.comments_length, opus_version);
//    snprintf(ENCODER_string, sizeof(ENCODER_string), "opusenc from %s %s",PACKAGE_NAME,"1.5");
    CStdString encode_string;
    encode_string.Format("opusenc from %s 1.5", PACKAGE_NAME);
    strcpy(ENCODER_string, encode_string.c_str());
    comment_add(&inopt.comments, &inopt.comments_length, "ENCODER", ENCODER_string);

    int packet_size=opus_header_to_packet(&header, header_data, sizeof(header_data));
    op.packet=header_data;
    op.bytes=packet_size;
    op.b_o_s=1;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=0;
    ogg_stream_packetin(&os, &op);

    while((ret=ogg_stream_flush(&os, &og))){
        if(!ret)break;
        
        ret=oe_write_page(&og);
        if(ret!=og.header_len+og.body_len){
            fprintf(stderr,"Error: failed writing header to output stream\n");
            exit(1);
        }
        bytes_written+=ret;
        pages_out++;
    }

    comment_pad(&inopt.comments, &inopt.comments_length, comment_padding);
    op.packet=(unsigned char *)inopt.comments;
    op.bytes=inopt.comments_length;
    op.b_o_s=0;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=1;
    ogg_stream_packetin(&os, &op);
    
    /* writing the rest of the Opus header packets */
    while((ret=ogg_stream_flush(&os, &og))){
        if(!ret)break;
        ret=oe_write_page(&og);
        if(ret!=og.header_len + og.body_len){
            fprintf(stderr,"Error: failed writing header to output stream\n");
            exit(1);
        }
            bytes_written+=ret;
            pages_out++;
    }    
}
Пример #2
0
void Ihu2Spx::process(char *cbits, int len)
{
	if (fout)
	{
		id++;
		
		total_samples += frame_size;
		
		op.packet = (unsigned char *)cbits;
		op.bytes = len;
		if (len)
			op.e_o_s = 0;
		else
			op.e_o_s = 1;
		op.b_o_s = 0;
		
		op.granulepos = (id+1)*frame_size;
		if (op.granulepos>total_samples)
			op.granulepos = total_samples;
		
		op.packetno = 2+id;
		ogg_stream_packetin(&os, &op);
		
		while (ogg_stream_pageout(&os,&og))
		{
			ret = oe_write_page(&og, fout);
			if(ret != og.header_len + og.body_len)
				throw Error(QString("failed writing header to output stream"));
			else
				bytes_written += ret;
		}
	}
}
Пример #3
0
void Ihu2Spx::setup(QString filename, const SpeexMode *mode, int rate, int fsize)
{
	if (fout)
		fclose(fout);
	filename.append(IHU_SPX_EXT);
	fout = fopen(filename.ascii(), "wb");
	if (fout)
	{
		total_samples = 0;
		bytes_written = 0;
		id = -1;
		frame_size = fsize;
		
		if (ogg_stream_init(&os, rand())==-1)
			throw Error(QString("stream init failed"));
	
		speex_init_header(&header, rate, 1, mode);
		header.frames_per_packet = 1;
		
		op.packet = (unsigned char *)speex_header_to_packet(&header, (int*)&(op.bytes));
		op.b_o_s = 1;
		op.e_o_s = 0;
		op.granulepos = 0;
		op.packetno = 0;
		ogg_stream_packetin(&os, &op);
		free(op.packet);
		
		op.packet = (unsigned char *)comments;
		op.bytes = comments_length;
		op.b_o_s = 0;
		op.e_o_s = 0;
		op.granulepos = 0;
		op.packetno = 1;
		ogg_stream_packetin(&os, &op);
		
		while((result = ogg_stream_flush(&os, &og)))
		{
			if(!result) break;
			ret = oe_write_page(&og, fout);
			if(ret != og.header_len + og.body_len)
				throw Error(QString("failed writing header to output stream"));
			else
				bytes_written += ret;
		}
	}
	else
	{
		throw Error(QString("%1: %2").arg(filename).arg(strerror(errno)));
}
}
Пример #4
0
void Ihu2Spx::end()
{
	if (total_samples)
	{
		process(NULL, 0); // Last empty packet with EOS = 1
		while (ogg_stream_flush(&os, &og))
		{
			ret = oe_write_page(&og, fout);
			if(ret != og.header_len + og.body_len)
				throw Error(QString("failed writing header to output stream"));
			else
				bytes_written += ret;
		}	
		ogg_stream_clear(&os);
		total_samples = 0;
	}
}
Пример #5
0
/*
  Write header (format will change)
  code from speexenc.c
*/
int write_ogg_header(Speex_ctx *ctx, int fd, char *comments)
{
  int ret, result;
  char *vendor_string = "Encoded with Timidity++-" VERSION "(compiled " __DATE__ ")";
  int comments_length = strlen(comments);

  comment_init(&comments, &comments_length, vendor_string);

  ctx->op.packet = (unsigned char *)speex_header_to_packet(&ctx->header, (int*)&(ctx->op.bytes));
  ctx->op.b_o_s = 1;
  ctx->op.e_o_s = 0;
  ctx->op.granulepos = 0;
  ctx->op.packetno = 0;
  ogg_stream_packetin(&ctx->os, &ctx->op);
  free(ctx->op.packet);

  ctx->op.packet = (unsigned char *)comments;
  ctx->op.bytes = comments_length;

  ctx->op.b_o_s = 0;
  ctx->op.e_o_s = 0;
  ctx->op.granulepos = 0;
  ctx->op.packetno = 1;
  ogg_stream_packetin(&ctx->os, &ctx->op);

  while((result = ogg_stream_flush(&ctx->os, &ctx->og))) {
    if(!result) break;
    ret = oe_write_page(&ctx->og, fd);
    if(ret != ctx->og.header_len + ctx->og.body_len) {
      ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output Ogg stream\n");
      return 1;
    }
    else
      ctx->out_bytes += ret;
  }
  return 0;
}
Пример #6
0
static void close_output(void)
{
  int i;
  char cbits[MAX_FRAME_BYTES];
  Speex_ctx *ctx = speex_ctx;
  int nbBytes;
  int ret;

  if (ctx == NULL)
    return;

  if (dpm.fd < 0)
    return;

  /*
    Write last frame
  */
  if (speex_ctx != NULL) {
    if ((ctx->ogg_packetid + 1) % ctx->nframes != 0) {
      while ((ctx->ogg_packetid + 1) % ctx->nframes != 0) {
	ctx->ogg_packetid++;
	speex_bits_pack(&ctx->bits, 15, 5);
      }
      nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES);
      ctx->op.packet = (unsigned char *)cbits;
      ctx->op.bytes = nbBytes;
      ctx->op.b_o_s = 0;
      ctx->op.e_o_s = 1;
      ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size;
      ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes;
      ogg_stream_packetin(&ctx->os, &ctx->op);
    }
    for (i = ctx->input_idx; i < ctx->frame_size * ctx->channels; i++) {
      /* left is zero-cleaned */
      ctx->input[i] = 0;
    }
    if (ctx->channels == 2)
      speex_encode_stereo(ctx->input, ctx->frame_size, &ctx->bits);
    /* Encode the frame */
    speex_encode(ctx->state, ctx->input, &ctx->bits);
    speex_bits_insert_terminator(&ctx->bits);
    /* Copy the bits to an array of char that can be written */
    nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES);
    
    /* Flush all the bits in the struct so we can encode a new frame */
    speex_bits_reset(&ctx->bits);

    /* ogg packet setup */
    ctx->op.packet = (unsigned char *)cbits;
    ctx->op.bytes = nbBytes;
    ctx->op.b_o_s = 0;
    ctx->op.e_o_s = 1;

    ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size;
    ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes;
    ogg_stream_packetin(&ctx->os, &ctx->op);

    /* Write all new pages (most likely 0 or 1) */
    while (ogg_stream_pageout(&ctx->os, &ctx->og)) {
      ret = oe_write_page(&ctx->og, dpm.fd);
      if (ret != ctx->og.header_len + ctx->og.body_len) {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output stream");
	return;
      }
      else
	ctx->out_bytes += ret;
    }

    ogg_stream_clear(&speex_ctx->os);
    speex_bits_destroy(&speex_ctx->bits);
    speex_encoder_destroy(speex_ctx->state);
    close(dpm.fd);
    dpm.fd = -1;
    free(speex_ctx->input);

    ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Wrote %lu/%lu bytes(%g%% compressed)",
	      ctx->out_bytes, ctx->in_bytes, ((double)ctx->out_bytes / (double)ctx->in_bytes)) * 100.;


    speex_ctx->input = NULL;
    free(speex_ctx);
    speex_ctx = NULL;
  }
  return;
}
Пример #7
0
static int output_data(char *buf, int32 nbytes)
{
  char cbits[MAX_FRAME_BYTES];
  Speex_ctx *ctx = speex_ctx;
  int nbBytes;
  int16 *s;
  int i, j;
  int ret;
  int nbytes_left;

  if (dpm.fd < 0)
    return 0;

  ctx->in_bytes += nbytes;

  /*
    Main encoding loop (one frame per iteration)
  */
  nbytes_left = nbytes;
  s = (int16 *)buf;
  while (1) {
    ctx->ogg_packetid++;
    /*
      packing 16 bit -> float sample
    */
    for (i = ctx->input_idx; i < ctx->frame_size * ctx->channels; i++) {
      /* stream is ended, and buffer is not full. wait next spooling */
      if (nbytes_left < 0) {
	/* canceling ogg packet */
	ctx->ogg_packetid--;
	return 0;
      }
      ctx->input[i] = *s++;
      nbytes_left -= 2; /* -16 bit*/
      ctx->input_idx++;
    }
    /*
      buffer is full. encode now.
    */
    ctx->input_idx = 0;

    if (ctx->channels == 2)
      speex_encode_stereo(ctx->input, ctx->frame_size, &ctx->bits);
    /* Encode the frame */
    speex_encode(ctx->state, ctx->input, &ctx->bits);

    if ((ctx->ogg_packetid + 1) % ctx->nframes != 0)
      continue;

    speex_bits_insert_terminator(&ctx->bits);
    /* Copy the bits to an array of char that can be written */
    nbBytes = speex_bits_write(&ctx->bits, cbits, MAX_FRAME_BYTES);
    
    /* Flush all the bits in the struct so we can encode a new frame */
    speex_bits_reset(&ctx->bits);

    /* ogg packet setup */
    ctx->op.packet = (unsigned char *)cbits;
    ctx->op.bytes = nbBytes;
    ctx->op.b_o_s = 0;
    ctx->op.e_o_s = 0;

    ctx->op.granulepos = (ctx->ogg_packetid + ctx->nframes) * ctx->frame_size;
    ctx->op.packetno = 2 + ctx->ogg_packetid / ctx->nframes;
    ogg_stream_packetin(&ctx->os, &ctx->op);

    /* Write all new pages (most likely 0 or 1) */
    while (ogg_stream_pageout(&ctx->os, &ctx->og)) {
      ret = oe_write_page(&ctx->og, dpm.fd);
      if (ret != ctx->og.header_len + ctx->og.body_len) {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "failed writing header to output stream");
	return -1;
      }
      else
	ctx->out_bytes += ret;
    }
  }
  
  return 0;
}
int oe_encode ( oe_enc_opt* opt )
{
	ogg_stream_state os;
	ogg_page 		 og;
	ogg_packet 		 op;

	vorbis_dsp_state vd;
	vorbis_block     vb;
	vorbis_info      vi;

	long	samplesdone   = 0;
    int		eos;
	long	bytes_written = 0;
	long	packetsdone   = 0;
	int		ret           = 0;
	
	vorbis_info_init ( &vi );

	if ( opt->quality >= 0.0f )
	{
		if ( vorbis_encode_init_vbr ( &vi, opt->channels, opt->rate, opt->quality ) )
		{
			vorbis_info_clear ( &vi );
			return 1;
		}
	}
	else
	{
		if ( vorbis_encode_init ( 
									&vi,
									opt->channels,
									opt->rate,
									opt->max_bitrate > 0 ? opt->max_bitrate * 1000 : -1,
									opt->bitrate * 1000, 
									opt->min_bitrate > 0 ? opt->min_bitrate * 1000 : -1
								) )
		{
			vorbis_info_clear ( &vi );
			return 1;
		}
	}

	vorbis_analysis_init ( &vd, &vi );
	vorbis_block_init    ( &vd, &vb );

	ogg_stream_init ( &os, opt->serialno );

	ogg_packet header_main;
	ogg_packet header_comments;
	ogg_packet header_codebooks;
	int result;

	vorbis_analysis_headerout ( &vd,opt->comments, &header_main, &header_comments, &header_codebooks );

	ogg_stream_packetin ( &os, &header_main );
	ogg_stream_packetin ( &os, &header_comments );
	ogg_stream_packetin ( &os, &header_codebooks );

	while ( ( result = ogg_stream_flush ( &os, &og ) ) )
	{
		if ( !result )
			break;
		
		ret = oe_write_page ( &og, opt->out );

		if ( ret != og.header_len + og.body_len )
		{
			ret = 1;
			goto cleanup;
		}
		else
			bytes_written += ret;
	}
	
	eos = 0;

	while ( !eos )
	{
		float** buffer       = vorbis_analysis_buffer ( &vd, READSIZE );
		long    samples_read = opt->read_samples ( opt->readdata, buffer, READSIZE );

		if ( samples_read == 0 )
			vorbis_analysis_wrote ( &vd, 0 );
		else
		{
			samplesdone += samples_read;

			vorbis_analysis_wrote ( &vd, samples_read );
		}

		while ( vorbis_analysis_blockout ( &vd, &vb ) == 1 )
		{
			vorbis_analysis         ( &vb, NULL );
			vorbis_bitrate_addblock ( &vb );

			while ( vorbis_bitrate_flushpacket ( &vd, &op ) )
			{
				ogg_stream_packetin ( &os,&op );
				packetsdone++;

				while ( !eos )
				{
					int result = ogg_stream_pageout ( &os, &og );

					if ( !result )
						break;

					ret = oe_write_page ( &og, opt->out );

					if ( ret != og.header_len + og.body_len )
					{
						ret = 1;
						goto cleanup;
					}
					else
						bytes_written += ret; 
	
					if ( ogg_page_eos ( &og ) )
						eos = 1;
				}
			}
		}
	}

	ret = 0;

cleanup:

	ogg_stream_clear ( &os );

	vorbis_block_clear ( &vb );
	vorbis_dsp_clear   ( &vd );
	vorbis_info_clear  ( &vi );

	return ret;
}
Пример #9
0
int main(int argc, char **argv)
{
   int nb_samples, total_samples=0, nb_encoded;
   int c;
   int option_index = 0;
   char *inFile, *outFile;
   FILE *fin, *fout;
   short input[MAX_FRAME_SIZE];
   celt_int32 frame_size = 960;
   int quiet=0;
   int nbBytes;
   CELTMode *mode;
   void *st;
   unsigned char bits[MAX_FRAME_BYTES];
   int with_cbr = 0;
   int with_cvbr = 0;
   int with_skeleton = 0;
   int total_bytes = 0;
   int peak_bytes = 0;
   struct option long_options[] =
   {
      {"bitrate", required_argument, NULL, 0},
      {"cbr",no_argument,NULL, 0},
      {"cvbr",no_argument,NULL, 0},
      {"comp", required_argument, NULL, 0},
      {"nopf", no_argument, NULL, 0},
      {"independent", no_argument, NULL, 0},
      {"framesize", required_argument, NULL, 0},
      {"skeleton",no_argument,NULL, 0},
      {"help", no_argument, NULL, 0},
      {"quiet", no_argument, NULL, 0},
      {"le", no_argument, NULL, 0},
      {"be", no_argument, NULL, 0},
      {"8bit", no_argument, NULL, 0},
      {"16bit", no_argument, NULL, 0},
      {"mono", no_argument, NULL, 0},
      {"stereo", no_argument, NULL, 0},
      {"rate", required_argument, NULL, 0},
      {"version", no_argument, NULL, 0},
      {"version-short", no_argument, NULL, 0},
      {"comment", required_argument, NULL, 0},
      {"author", required_argument, NULL, 0},
      {"title", required_argument, NULL, 0},
      {0, 0, 0, 0}
   };
   int print_bitrate=0;
   celt_int32 rate=48000;
   celt_int32 size;
   int chan=1;
   int fmt=16;
   int lsb=1;
   ogg_stream_state os;
   ogg_stream_state so; /* ogg stream for skeleton bitstream */
   ogg_page 		 og;
   ogg_packet 		 op;
   int bytes_written=0, ret, result;
   int id=-1;
   CELTHeader header;
   char vendor_string[64];
   char *comments;
   int comments_length;
   int close_in=0, close_out=0;
   int eos=0;
   float bitrate=-1;
   char first_bytes[12];
   int wave_input=0;
   celt_int32 lookahead = 0;
   int bytes_per_packet=-1;
   int complexity=-127;
   int prediction=2;


   /*Process command-line 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,"bitrate")==0)
         {
            bitrate = atof (optarg);
         } else if (strcmp(long_options[option_index].name,"cbr")==0)
         {
            with_cbr=1;
         } else if (strcmp(long_options[option_index].name,"cvbr")==0)
         {
            with_cvbr=1;
         } else if (strcmp(long_options[option_index].name,"skeleton")==0)
         {
            with_skeleton=1;
         } else 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,"le")==0)
         {
            lsb=1;
         } else if (strcmp(long_options[option_index].name,"be")==0)
         {
            lsb=0;
         } else if (strcmp(long_options[option_index].name,"8bit")==0)
         {
            fmt=8;
         } else if (strcmp(long_options[option_index].name,"16bit")==0)
         {
            fmt=16;
         } else if (strcmp(long_options[option_index].name,"stereo")==0)
         {
            chan=2;
         } else if (strcmp(long_options[option_index].name,"mono")==0)
         {
            chan=1;
         } else if (strcmp(long_options[option_index].name,"rate")==0)
         {
            rate=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"comp")==0)
         {
            complexity=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"framesize")==0)
         {
            frame_size=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"nopf")==0)
         {
            if (prediction>1)
              prediction=1;
         } else if (strcmp(long_options[option_index].name,"independent")==0)
         {
              prediction=0;
         } else if (strcmp(long_options[option_index].name,"comment")==0)
         {
	   if (!strchr(optarg, '='))
	   {
	     fprintf (stderr, "Invalid comment: %s\n", optarg);
	     fprintf (stderr, "Comments must be of the form name=value\n");
	     exit(1);
	   }
           comment_add(&comments, &comments_length, NULL, optarg); 
         } else if (strcmp(long_options[option_index].name,"author")==0)
         {
           comment_add(&comments, &comments_length, "author=", optarg); 
         } else if (strcmp(long_options[option_index].name,"title")==0)
         {
           comment_add(&comments, &comments_length, "title=", 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)
   {
      usage();
      exit(1);
   }
   inFile=argv[optind];
   outFile=argv[optind+1];

   /*Initialize Ogg stream struct*/
   srand(time(NULL));
   if (ogg_stream_init(&os, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }
   if (with_skeleton && ogg_stream_init(&so, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }

   if (strcmp(inFile, "-")==0)
   {
#if defined WIN32 || defined _WIN32
         _setmode(_fileno(stdin), _O_BINARY);
#elif defined OS2
         _fsetmode(stdin,"b");
#endif
      fin=stdin;
   }
   else 
   {
      fin = fopen(inFile, "rb");
      if (!fin)
      {
         perror(inFile);
         exit(1);
      }
      close_in=1;
   }

   {
      fread(first_bytes, 1, 12, fin);
      if (strncmp(first_bytes,"RIFF",4)==0 && strncmp(first_bytes,"RIFF",4)==0)
      {
         if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
            exit(1);
         wave_input=1;
         lsb=1; /* CHECK: exists big-endian .wav ?? */
      }
   }

   if (bitrate<=0.005)
     if (chan==1)
       bitrate=64.0;
     else
       bitrate=128.0;
     
   bytes_per_packet = MAX_FRAME_BYTES;
   
   mode = celt_mode_create(rate, frame_size, NULL);
   if (!mode)
      return 1;

   snprintf(vendor_string, sizeof(vendor_string), "Encoded with CELT %s\n",CELT_VERSION);
   comment_init(&comments, &comments_length, vendor_string);

   /*celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);*/
   
   celt_header_init(&header, mode, frame_size, chan);
   header.nb_channels = chan;

   {
      char *st_string="mono";
      if (chan==2)
         st_string="stereo";
      if (!quiet)
         if (with_cbr)
           fprintf (stderr, "Encoding %.0f kHz %s audio in %.0fms packets at %0.3fkbit/sec (%d bytes per packet, CBR)\n",
               header.sample_rate/1000., st_string, frame_size/(float)header.sample_rate*1000., bitrate, bytes_per_packet);
         else      
           fprintf (stderr, "Encoding %.0f kHz %s audio in %.0fms packets at %0.3fkbit/sec (%d bytes per packet maximum)\n",
               header.sample_rate/1000., st_string, frame_size/(float)header.sample_rate*1000., bitrate, bytes_per_packet);
   }

   /*Initialize CELT encoder*/
   st = celt_encoder_create_custom(mode, chan, NULL);

   {
      int tmp = (bitrate*1000);
      if (celt_encoder_ctl(st, CELT_SET_BITRATE(tmp)) != CELT_OK)
      {
         fprintf (stderr, "bitrate request failed\n");
         return 1;
      }
   }
   if (!with_cbr)
   {
     if (celt_encoder_ctl(st, CELT_SET_VBR(1)) != CELT_OK)
     {
        fprintf (stderr, "VBR request failed\n");
        return 1;
     }
     if (!with_cvbr)
     {
        if (celt_encoder_ctl(st, CELT_SET_VBR_CONSTRAINT(0)) != CELT_OK)
        {
           fprintf (stderr, "VBR constraint failed\n");
           return 1;
        }
     }
   }

   if (celt_encoder_ctl(st, CELT_SET_PREDICTION(prediction)) != CELT_OK)
   {
      fprintf (stderr, "Prediction request failed\n");
      return 1;
   }

   if (complexity!=-127) {
     if (celt_encoder_ctl(st, CELT_SET_COMPLEXITY(complexity)) != CELT_OK)
     {
        fprintf (stderr, "Only complexity 0 through 10 is supported\n");
        return 1;
     }
   }

   if (strcmp(outFile,"-")==0)
   {
#if defined WIN32 || defined _WIN32
      _setmode(_fileno(stdout), _O_BINARY);
#endif
      fout=stdout;
   }
   else 
   {
      fout = fopen(outFile, "wb");
      if (!fout)
      {
         perror(outFile);
         exit(1);
      }
      close_out=1;
   }

   if (with_skeleton) {
      fprintf (stderr, "Warning: Enabling skeleton output may cause some decoders to fail.\n");
   }

   /* first packet should be the skeleton header. */
   if (with_skeleton) {
      add_fishead_packet(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
	 fprintf (stderr,"Error: failed skeleton (fishead) header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }

   /*Write header*/
   {
      unsigned char header_data[100];
      int packet_size = celt_header_to_packet(&header, header_data, 100);
      op.packet = header_data;
      op.bytes = packet_size;
      op.b_o_s = 1;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 0;
      ogg_stream_packetin(&os, &op);

      while((result = ogg_stream_flush(&os, &og)))
      {
         if(!result) break;
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }

      op.packet = (unsigned char *)comments;
      op.bytes = comments_length;
      op.b_o_s = 0;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 1;
      ogg_stream_packetin(&os, &op);
   }

   /* fisbone packet should be write after all bos pages */
   if (with_skeleton) {
      add_fisbone_packet(&so, os.serialno, &header);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
	 fprintf (stderr,"Error: failed writing skeleton (fisbone )header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }

   /* writing the rest of the celt header packets */
   while((result = ogg_stream_flush(&os, &og)))
   {
      if(!result) break;
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   free(comments);

   /* write the skeleton eos packet */
   if (with_skeleton) {
      add_eos_packet_to_stream(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
         fprintf (stderr,"Error: failed writing skeleton header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }


   if (!wave_input)
   {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL);
   } else {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
   }
   if (nb_samples==0)
      eos=1;
   total_samples += nb_samples;
   nb_encoded = -lookahead;
   /*Main encoding loop (one frame per iteration)*/
   while (!eos || total_samples>nb_encoded)
   {
      id++;
      /*Encode current frame*/

      nbBytes = celt_encode(st, input, frame_size, bits, bytes_per_packet);
      if (nbBytes<0)
      {
         fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);
         break;
      }
      nb_encoded += frame_size;
      total_bytes += nbBytes;
      peak_bytes=IMAX(nbBytes,peak_bytes);

      if (wave_input)
      {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
      } else {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL);
      }
      if (nb_samples==0)
      {
         eos=1;
      }
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      total_samples += nb_samples;

      op.packet = (unsigned char *)bits;
      op.bytes = nbBytes;
      op.b_o_s = 0;
      /*Is this redundent?*/
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      op.granulepos = (id+1)*frame_size-lookahead;
      if (op.granulepos>total_samples)
         op.granulepos = total_samples;
      /*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/
      op.packetno = 2+id;
      ogg_stream_packetin(&os, &op);

      /*Write all new pages (most likely 0 or 1)*/
      while (ogg_stream_pageout(&os,&og))
      {
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }
   }
   /*Flush all pages left to be written*/
   while (ogg_stream_flush(&os, &og))
   {
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   if (!with_cbr && !quiet)
     fprintf (stderr, "Average rate %0.3fkbit/sec, %d peak bytes per packet\n", (total_bytes*8.0/((float)nb_encoded/header.sample_rate))/1000.0, peak_bytes);

   celt_encoder_destroy(st);
   celt_mode_destroy(mode);
   ogg_stream_clear(&os);

   if (close_in)
      fclose(fin);
   if (close_out)
      fclose(fout);
   return 0;
}
Пример #10
0
int main(int argc, char **argv)
{
   int nb_samples, total_samples=0, nb_encoded;
   int c;
   int option_index = 0;
   char *inFile, *outFile;
   FILE *fin, *fout;
   short input[MAX_FRAME_SIZE];
   celt_int32_t frame_size;
   int quiet=0;
   int nbBytes;
   CELTMode *mode;
   void *st;
   unsigned char bits[MAX_FRAME_BYTES];
   int with_skeleton = 0;
   struct option long_options[] =
   {
      {"bitrate", required_argument, NULL, 0},
      {"comp", required_argument, NULL, 0},
      {"skeleton",no_argument,NULL, 0},
      {"help", no_argument, NULL, 0},
      {"quiet", no_argument, NULL, 0},
      {"le", no_argument, NULL, 0},
      {"be", no_argument, NULL, 0},
      {"8bit", no_argument, NULL, 0},
      {"16bit", no_argument, NULL, 0},
      {"mono", no_argument, NULL, 0},
      {"stereo", no_argument, NULL, 0},
      {"rate", required_argument, NULL, 0},
      {"version", no_argument, NULL, 0},
      {"version-short", no_argument, NULL, 0},
      {"comment", required_argument, NULL, 0},
      {"author", required_argument, NULL, 0},
      {"title", required_argument, NULL, 0},
      {0, 0, 0, 0}
   };
   int print_bitrate=0;
   celt_int32_t rate=44100;
   celt_int32_t size;
   int chan=1;
   int fmt=16;
   int lsb=1;
   ogg_stream_state os;
   ogg_stream_state so; /* ogg stream for skeleton bitstream */
   ogg_page 		 og;
   ogg_packet 		 op;
   int bytes_written=0, ret, result;
   int id=-1;
   CELT051Header header;
   char vendor_string[64];
   char *comments;
   int comments_length;
   int close_in=0, close_out=0;
   int eos=0;
   celt_int32_t bitrate=-1;
   char first_bytes[12];
   int wave_input=0;
   celt_int32_t lookahead = 0;
   int bytes_per_packet=48;
   int complexity=-127;
   
   snprintf(vendor_string, sizeof(vendor_string), "Encoded with CELT\n");
   
   comment_init(&comments, &comments_length, vendor_string);

   /*Process command-line 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,"bitrate")==0)
         {
            bitrate = atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"skeleton")==0)
         {
            with_skeleton=1;
         } else 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,"le")==0)
         {
            lsb=1;
         } else if (strcmp(long_options[option_index].name,"be")==0)
         {
            lsb=0;
         } else if (strcmp(long_options[option_index].name,"8bit")==0)
         {
            fmt=8;
         } else if (strcmp(long_options[option_index].name,"16bit")==0)
         {
            fmt=16;
         } else if (strcmp(long_options[option_index].name,"stereo")==0)
         {
            chan=2;
         } else if (strcmp(long_options[option_index].name,"mono")==0)
         {
            chan=1;
         } else if (strcmp(long_options[option_index].name,"rate")==0)
         {
            rate=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"comp")==0)
         {
            complexity=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"comment")==0)
         {
	   if (!strchr(optarg, '='))
	   {
	     fprintf (stderr, "Invalid comment: %s\n", optarg);
	     fprintf (stderr, "Comments must be of the form name=value\n");
	     exit(1);
	   }
           comment_add(&comments, &comments_length, NULL, optarg); 
         } else if (strcmp(long_options[option_index].name,"author")==0)
         {
           comment_add(&comments, &comments_length, "author=", optarg); 
         } else if (strcmp(long_options[option_index].name,"title")==0)
         {
           comment_add(&comments, &comments_length, "title=", 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;
      }
   }

   fprintf(stderr,"\nWARNING: This encoder is a CELT *PRERELEASE*. It produces streams that are\n"
           "         not decodable by ANY OTHER VERSION.  These streams will NOT be\n"
           "         supported or decodable by any future CELT release.\n\n");

   if (argc-optind!=2)
   {
      usage();
      exit(1);
   }
   inFile=argv[optind];
   outFile=argv[optind+1];

   /*Initialize Ogg stream struct*/
   srand(time(NULL));
   if (ogg_stream_init(&os, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }
   if (with_skeleton && ogg_stream_init(&so, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }

   if (strcmp(inFile, "-")==0)
   {
#if defined WIN32 || defined _WIN32
         _setmode(_fileno(stdin), _O_BINARY);
#elif defined OS2
         _fsetmode(stdin,"b");
#endif
      fin=stdin;
   }
   else 
   {
      fin = fopen(inFile, "rb");
      if (!fin)
      {
         perror(inFile);
         exit(1);
      }
      close_in=1;
   }

   {
      fread(first_bytes, 1, 12, fin);
      if (strncmp(first_bytes,"RIFF",4)==0 && strncmp(first_bytes,"RIFF",4)==0)
      {
         if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
            exit(1);
         wave_input=1;
         lsb=1; /* CHECK: exists big-endian .wav ?? */
      }
   }

   if (chan == 1)
   {
      if (bitrate < 0)
         bitrate = 64;
      if (bitrate < 32)
         bitrate = 32;
      if (bitrate > 110)
         bitrate = 110;
   }
   else if (chan == 2)
   {
      if (bitrate < 0)
         bitrate = 128;
      if (bitrate < 64)
         bitrate = 64;
      if (bitrate > 150)
         bitrate = 150;
   } else {
      fprintf (stderr, "Only mono and stereo are supported\n");
      return 1;
   }

   mode = celt051_mode_create(rate, chan, 256, NULL);
   if (!mode)
      return 1;
   celt051_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);
   
   bytes_per_packet = (bitrate*1000*frame_size/rate+4)/8;
   
   celt051_header_init(&header, mode);
   header.nb_channels = chan;

   {
      char *st_string="mono";
      if (chan==2)
         st_string="stereo";
      if (!quiet)
         fprintf (stderr, "Encoding %d Hz audio using %s (%d bytes per packet)\n", 
               header.sample_rate, st_string, bytes_per_packet);
   }
   /*fprintf (stderr, "Encoding %d Hz audio at %d bps using %s mode\n", 
     header.rate, mode->bitrate, mode->modeName);*/

   /*Initialize CELT encoder*/
   st = celt051_encoder_create(mode);

   if (complexity!=-127) {
     if (celt051_encoder_ctl(st, CELT_SET_COMPLEXITY(complexity)) != CELT_OK)
     {
        fprintf (stderr, "Only complexity 0 through 10 is supported\n");
        return 1;
     }
   }

   if (strcmp(outFile,"-")==0)
   {
#if defined WIN32 || defined _WIN32
      _setmode(_fileno(stdout), _O_BINARY);
#endif
      fout=stdout;
   }
   else 
   {
      fout = fopen(outFile, "wb");
      if (!fout)
      {
         perror(outFile);
         exit(1);
      }
      close_out=1;
   }

   if (with_skeleton) {
      fprintf (stderr, "Warning: Enabling skeleton output may cause some decoders to fail.\n");
   }

   /* first packet should be the skeleton header. */
   if (with_skeleton) {
      add_fishead_packet(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
	 fprintf (stderr,"Error: failed skeleton (fishead) header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }

   /*Write header*/
   {
      unsigned char header_data[100];
      int packet_size = celt051_header_to_packet(&header, header_data, 100);
      op.packet = header_data;
      op.bytes = packet_size;
      op.b_o_s = 1;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 0;
      ogg_stream_packetin(&os, &op);

      while((result = ogg_stream_flush(&os, &og)))
      {
         if(!result) break;
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }

      op.packet = (unsigned char *)comments;
      op.bytes = comments_length;
      op.b_o_s = 0;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 1;
      ogg_stream_packetin(&os, &op);
   }

   /* fisbone packet should be write after all bos pages */
   if (with_skeleton) {
      add_fisbone_packet(&so, os.serialno, &header);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
	 fprintf (stderr,"Error: failed writing skeleton (fisbone )header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }

   /* writing the rest of the celt header packets */
   while((result = ogg_stream_flush(&os, &og)))
   {
      if(!result) break;
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   free(comments);

   /* write the skeleton eos packet */
   if (with_skeleton) {
      add_eos_packet_to_stream(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
         fprintf (stderr,"Error: failed writing skeleton header to output stream\n");
         exit(1);
      } else
	 bytes_written += ret;
   }


   if (!wave_input)
   {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL);
   } else {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
   }
   if (nb_samples==0)
      eos=1;
   total_samples += nb_samples;
   nb_encoded = -lookahead;
   /*Main encoding loop (one frame per iteration)*/
   while (!eos || total_samples>nb_encoded)
   {
      id++;
      /*Encode current frame*/

      nbBytes = celt051_encode(st, input, NULL, bits, bytes_per_packet);
      if (nbBytes<0)
      {
         fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);
         break;
      }
      nb_encoded += frame_size;

      if (wave_input)
      {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
      } else {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL);
      }
      if (nb_samples==0)
      {
         eos=1;
      }
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      total_samples += nb_samples;

      op.packet = (unsigned char *)bits;
      op.bytes = nbBytes;
      op.b_o_s = 0;
      /*Is this redundent?*/
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      op.granulepos = (id+1)*frame_size-lookahead;
      if (op.granulepos>total_samples)
         op.granulepos = total_samples;
      /*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/
      op.packetno = 2+id;
      ogg_stream_packetin(&os, &op);

      /*Write all new pages (most likely 0 or 1)*/
      while (ogg_stream_pageout(&os,&og))
      {
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }
   }
   /*Flush all pages left to be written*/
   while (ogg_stream_flush(&os, &og))
   {
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   celt051_encoder_destroy(st);
   celt051_mode_destroy(mode);
   ogg_stream_clear(&os);

   if (close_in)
      fclose(fin);
   if (close_out)
      fclose(fout);
   return 0;
}
Пример #11
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++;
        }
    }
}
Пример #12
0
int main(int argc, char **argv)
{
   int nb_samples, total_samples=0, nb_encoded;
   int c;
   int option_index = 0;
   char *inFile, *outFile;
   FILE *fin, *fout;
   short input[MAX_FRAME_SIZE];
   spx_int32_t frame_size;
   int quiet=0;
   spx_int32_t vbr_enabled=0;
   spx_int32_t vbr_max=0;
   int abr_enabled=0;
   spx_int32_t vad_enabled=0;
   spx_int32_t dtx_enabled=0;
   int nbBytes;
   const SpeexMode *mode=NULL;
   int modeID = -1;
   void *st;
   SpeexBits bits;
   char cbits[MAX_FRAME_BYTES];
   int with_skeleton = 0;
   struct option long_options[] =
   {
      {"wideband", no_argument, NULL, 0},
      {"ultra-wideband", no_argument, NULL, 0},
      {"narrowband", no_argument, NULL, 0},
      {"vbr", no_argument, NULL, 0},
      {"vbr-max-bitrate", required_argument, NULL, 0},
      {"abr", required_argument, NULL, 0},
      {"vad", no_argument, NULL, 0},
      {"dtx", no_argument, NULL, 0},
      {"quality", required_argument, NULL, 0},
      {"bitrate", required_argument, NULL, 0},
      {"nframes", required_argument, NULL, 0},
      {"comp", required_argument, NULL, 0},
#ifdef USE_SPEEXDSP
      {"denoise", no_argument, NULL, 0},
      {"agc", no_argument, NULL, 0},
#endif
      {"no-highpass", no_argument, NULL, 0},
      {"skeleton",no_argument,NULL, 0},
      {"help", no_argument, NULL, 0},
      {"quiet", no_argument, NULL, 0},
      {"le", no_argument, NULL, 0},
      {"be", no_argument, NULL, 0},
      {"8bit", no_argument, NULL, 0},
      {"16bit", no_argument, NULL, 0},
      {"stereo", no_argument, NULL, 0},
      {"rate", required_argument, NULL, 0},
      {"version", no_argument, NULL, 0},
      {"version-short", no_argument, NULL, 0},
      {"comment", required_argument, NULL, 0},
      {"author", required_argument, NULL, 0},
      {"title", required_argument, NULL, 0},
      {"print-rate", no_argument, NULL, 0},
      {0, 0, 0, 0}
   };
   int print_bitrate=0;
   spx_int32_t rate=0;
   spx_int32_t size;
   int chan=1;
   int fmt=16;
   spx_int32_t quality=-1;
   float vbr_quality=-1;
   int lsb=1;
   ogg_stream_state os;
   ogg_stream_state so; /* ogg stream for skeleton bitstream */
   ogg_page og;
   ogg_packet op;
   int bytes_written=0, ret, result;
   int id=-1;
   SpeexHeader header;
   int nframes=1;
   spx_int32_t complexity=3;
   const char* speex_version;
   char vendor_string[64];
   char *comments;
   int comments_length;
   int close_in=0, close_out=0;
   int eos=0;
   spx_int32_t bitrate=0;
   double cumul_bits=0, enc_frames=0;
   char first_bytes[12];
   int wave_input=0;
   spx_int32_t tmp;
#ifdef USE_SPEEXDSP
   SpeexPreprocessState *preprocess = NULL;
   int denoise_enabled=0, agc_enabled=0;
#endif
   int highpass_enabled=1;
   int output_rate=0;
   spx_int32_t lookahead = 0;

   speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
   snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version);

   comment_init(&comments, &comments_length, vendor_string);

   /*Process command-line options*/
   while(1)
   {
      c = getopt_long (argc, argv, "nwuhvV",
                       long_options, &option_index);
      if (c==-1)
         break;

      switch(c)
      {
      case 0:
         if (strcmp(long_options[option_index].name,"narrowband")==0)
         {
            modeID = SPEEX_MODEID_NB;
         } else if (strcmp(long_options[option_index].name,"wideband")==0)
         {
            modeID = SPEEX_MODEID_WB;
         } else if (strcmp(long_options[option_index].name,"ultra-wideband")==0)
         {
            modeID = SPEEX_MODEID_UWB;
         } else if (strcmp(long_options[option_index].name,"vbr")==0)
         {
            vbr_enabled=1;
         } else if (strcmp(long_options[option_index].name,"vbr-max-bitrate")==0)
         {
            vbr_max=atoi(optarg);
            if (vbr_max<1)
            {
               fprintf (stderr, "Invalid VBR max bit-rate value: %d\n", vbr_max);
               exit(1);
            }
         } else if (strcmp(long_options[option_index].name,"abr")==0)
         {
            abr_enabled=atoi(optarg);
            if (!abr_enabled)
            {
               fprintf (stderr, "Invalid ABR value: %d\n", abr_enabled);
               exit(1);
            }
         } else if (strcmp(long_options[option_index].name,"vad")==0)
         {
            vad_enabled=1;
         } else if (strcmp(long_options[option_index].name,"dtx")==0)
         {
            dtx_enabled=1;
         } else if (strcmp(long_options[option_index].name,"quality")==0)
         {
            quality = atoi (optarg);
            vbr_quality=atof(optarg);
         } else if (strcmp(long_options[option_index].name,"bitrate")==0)
         {
            bitrate = atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"nframes")==0)
         {
            nframes = atoi (optarg);
            if (nframes<1)
               nframes=1;
            if (nframes>10)
               nframes=10;
         } else if (strcmp(long_options[option_index].name,"comp")==0)
         {
            complexity = atoi (optarg);
#ifdef USE_SPEEXDSP
         } else if (strcmp(long_options[option_index].name,"denoise")==0)
         {
            denoise_enabled=1;
         } else if (strcmp(long_options[option_index].name,"agc")==0)
         {
            agc_enabled=1;
#endif
         } else if (strcmp(long_options[option_index].name,"no-highpass")==0)
         {
            highpass_enabled=0;
         } else if (strcmp(long_options[option_index].name,"skeleton")==0)
         {
            with_skeleton=1;
         } else 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,"print-rate")==0)
         {
            output_rate=1;
         } else if (strcmp(long_options[option_index].name,"le")==0)
         {
            lsb=1;
         } else if (strcmp(long_options[option_index].name,"be")==0)
         {
            lsb=0;
         } else if (strcmp(long_options[option_index].name,"8bit")==0)
         {
            fmt=8;
         } else if (strcmp(long_options[option_index].name,"16bit")==0)
         {
            fmt=16;
         } else if (strcmp(long_options[option_index].name,"stereo")==0)
         {
            chan=2;
         } else if (strcmp(long_options[option_index].name,"rate")==0)
         {
            rate=atoi (optarg);
         } else if (strcmp(long_options[option_index].name,"comment")==0)
         {
            if (!strchr(optarg, '='))
            {
               fprintf (stderr, "Invalid comment: %s\n", optarg);
               fprintf (stderr, "Comments must be of the form name=value\n");
               exit(1);
            }
           comment_add(&comments, &comments_length, NULL, optarg);
         } else if (strcmp(long_options[option_index].name,"author")==0)
         {
           comment_add(&comments, &comments_length, "author=", optarg);
         } else if (strcmp(long_options[option_index].name,"title")==0)
         {
           comment_add(&comments, &comments_length, "title=", optarg);
         }

         break;
      case 'n':
         modeID = SPEEX_MODEID_NB;
         break;
      case 'h':
         usage();
         exit(0);
         break;
      case 'v':
         version();
         exit(0);
         break;
      case 'V':
         print_bitrate=1;
         break;
      case 'w':
         modeID = SPEEX_MODEID_WB;
         break;
      case 'u':
         modeID = SPEEX_MODEID_UWB;
         break;
      case '?':
         usage();
         exit(1);
         break;
      }
   }
   if (argc-optind!=2)
   {
      usage();
      exit(1);
   }
   inFile=argv[optind];
   outFile=argv[optind+1];

   /*Initialize Ogg stream struct*/
   srand(time(NULL));
   if (ogg_stream_init(&os, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }
   if (with_skeleton && ogg_stream_init(&so, rand())==-1)
   {
      fprintf(stderr,"Error: stream init failed\n");
      exit(1);
   }

   if (strcmp(inFile, "-")==0)
   {
#if defined WIN32 || defined _WIN32
         _setmode(_fileno(stdin), _O_BINARY);
#elif defined OS2
         _fsetmode(stdin,"b");
#endif
      fin=stdin;
   }
   else
   {
      fin = fopen(inFile, "rb");
      if (!fin)
      {
         perror(inFile);
         exit(1);
      }
      close_in=1;
   }

   {
      if (fread(first_bytes, 1, 12, fin) != 12)
      {
         perror("short file");
         exit(1);
      }
      if (strncmp(first_bytes,"RIFF",4)==0 || strncmp(first_bytes,"riff",4)==0)
      {
         if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
            exit(1);
         wave_input=1;
         lsb=1; /* CHECK: exists big-endian .wav ?? */
      }
   }

   if (modeID==-1 && !rate)
   {
      /* By default, use narrowband/8 kHz */
      modeID = SPEEX_MODEID_NB;
      rate=8000;
   } else if (modeID!=-1 && rate)
   {
      mode = speex_lib_get_mode (modeID);
      if (rate>48000)
      {
         fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-sampling\n", rate);
         exit(1);
      } else if (rate>25000)
      {
         if (modeID != SPEEX_MODEID_UWB)
         {
            fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try ultra-wideband instead\n", mode->modeName , rate);
         }
      } else if (rate>12500)
      {
         if (modeID != SPEEX_MODEID_WB)
         {
            fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try wideband instead\n", mode->modeName , rate);
         }
      } else if (rate>=6000)
      {
         if (modeID != SPEEX_MODEID_NB)
         {
            fprintf (stderr, "Warning: Trying to encode in %s at %d Hz. I'll do it but I suggest you try narrowband instead\n", mode->modeName , rate);
         }
      } else {
         fprintf (stderr, "Error: sampling rate too low: %d Hz\n", rate);
         exit(1);
      }
   } else if (modeID==-1)
   {
      if (rate>48000)
      {
         fprintf (stderr, "Error: sampling rate too high: %d Hz, try down-sampling\n", rate);
         exit(1);
      } else if (rate>25000)
      {
         modeID = SPEEX_MODEID_UWB;
      } else if (rate>12500)
      {
         modeID = SPEEX_MODEID_WB;
      } else if (rate>=6000)
      {
         modeID = SPEEX_MODEID_NB;
      } else {
         fprintf (stderr, "Error: Sampling rate too low: %d Hz\n", rate);
         exit(1);
      }
   } else if (!rate)
   {
      if (modeID == SPEEX_MODEID_NB)
         rate=8000;
      else if (modeID == SPEEX_MODEID_WB)
         rate=16000;
      else if (modeID == SPEEX_MODEID_UWB)
         rate=32000;
   }

   if (!quiet)
      if (rate!=8000 && rate!=16000 && rate!=32000)
         fprintf (stderr, "Warning: Speex is only optimized for 8, 16 and 32 kHz. It will still work at %d Hz but your mileage may vary\n", rate);

   if (!mode)
      mode = speex_lib_get_mode (modeID);

   speex_init_header(&header, rate, 1, mode);
   header.frames_per_packet=nframes;
   header.vbr=vbr_enabled;
   header.nb_channels = chan;

   {
      char *st_string="mono";
      if (chan==2)
         st_string="stereo";
      if (!quiet)
         fprintf (stderr, "Encoding %d Hz audio using %s mode (%s)\n",
               header.rate, mode->modeName, st_string);
   }
   /*fprintf (stderr, "Encoding %d Hz audio at %d bps using %s mode\n",
     header.rate, mode->bitrate, mode->modeName);*/

   /*Initialize Speex encoder*/
   st = speex_encoder_init(mode);

   if (strcmp(outFile,"-")==0)
   {
#if defined WIN32 || defined _WIN32
      _setmode(_fileno(stdout), _O_BINARY);
#endif
      fout=stdout;
   }
   else
   {
      fout = fopen(outFile, "wb");
      if (!fout)
      {
         perror(outFile);
         exit(1);
      }
      close_out=1;
   }

   speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
   speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate);

   if (quality >= 0)
   {
      if (vbr_enabled)
      {
         if (vbr_max>0)
            speex_encoder_ctl(st, SPEEX_SET_VBR_MAX_BITRATE, &vbr_max);
         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_quality);
      }
      else
         speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality);
   }
   if (bitrate)
   {
      if (quality >= 0 && vbr_enabled)
         fprintf (stderr, "Warning: --bitrate option is overriding --quality\n");
      speex_encoder_ctl(st, SPEEX_SET_BITRATE, &bitrate);
   }
   if (vbr_enabled)
   {
      tmp=1;
      speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
   } else if (vad_enabled)
   {
      tmp=1;
      speex_encoder_ctl(st, SPEEX_SET_VAD, &tmp);
   }
   if (dtx_enabled)
      speex_encoder_ctl(st, SPEEX_SET_DTX, &tmp);
   if (dtx_enabled && !(vbr_enabled || abr_enabled || vad_enabled))
   {
      fprintf (stderr, "Warning: --dtx is useless without --vad, --vbr or --abr\n");
   } else if ((vbr_enabled || abr_enabled) && (vad_enabled))
   {
      fprintf (stderr, "Warning: --vad is already implied by --vbr or --abr\n");
   }
   if (with_skeleton) {
      fprintf (stderr, "Warning: Enabling skeleton output may cause some decoders to fail.\n");
   }

   if (abr_enabled)
   {
      speex_encoder_ctl(st, SPEEX_SET_ABR, &abr_enabled);
   }

   speex_encoder_ctl(st, SPEEX_SET_HIGHPASS, &highpass_enabled);

   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);

#ifdef USE_SPEEXDSP
   if (denoise_enabled || agc_enabled)
   {
      preprocess = speex_preprocess_state_init(frame_size, rate);
      speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_DENOISE, &denoise_enabled);
      speex_preprocess_ctl(preprocess, SPEEX_PREPROCESS_SET_AGC, &agc_enabled);
      lookahead += frame_size;
   }
#endif
   /* first packet should be the skeleton header. */

   if (with_skeleton) {
      add_fishead_packet(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
         fprintf (stderr,"Error: failed skeleton (fishead) header to output stream\n");
         exit(1);
      } else
         bytes_written += ret;
   }

   /*Write header*/
   {
      int packet_size;
      op.packet = (unsigned char *)speex_header_to_packet(&header, &packet_size);
      op.bytes = packet_size;
      op.b_o_s = 1;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 0;
      ogg_stream_packetin(&os, &op);
      free(op.packet);

      while((result = ogg_stream_flush(&os, &og)))
      {
         if(!result) break;
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }

      op.packet = (unsigned char *)comments;
      op.bytes = comments_length;
      op.b_o_s = 0;
      op.e_o_s = 0;
      op.granulepos = 0;
      op.packetno = 1;
      ogg_stream_packetin(&os, &op);
   }

   /* fisbone packet should be write after all bos pages */
   if (with_skeleton) {
      add_fisbone_packet(&so, os.serialno, &header);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
         fprintf (stderr,"Error: failed writing skeleton (fisbone )header to output stream\n");
         exit(1);
      } else
         bytes_written += ret;
   }

   /* writing the rest of the speex header packets */
   while((result = ogg_stream_flush(&os, &og)))
   {
      if(!result) break;
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   free(comments);

   /* write the skeleton eos packet */
   if (with_skeleton) {
      add_eos_packet_to_stream(&so);
      if ((ret = flush_ogg_stream_to_file(&so, fout))) {
         fprintf (stderr,"Error: failed writing skeleton header to output stream\n");
         exit(1);
      } else
         bytes_written += ret;
   }


   speex_bits_init(&bits);

   if (!wave_input)
   {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes, NULL);
   } else {
      nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
   }
   if (nb_samples==0)
      eos=1;
   total_samples += nb_samples;
   nb_encoded = -lookahead;
   /*Main encoding loop (one frame per iteration)*/
   while (!eos || total_samples>nb_encoded)
   {
      id++;
      /*Encode current frame*/
      if (chan==2)
         speex_encode_stereo_int(input, frame_size, &bits);

#ifdef USE_SPEEXDSP
      if (preprocess)
         speex_preprocess(preprocess, input, NULL);
#endif
      speex_encode_int(st, input, &bits);

      nb_encoded += frame_size;
      if (print_bitrate) {
         int tmp;
         char ch=13;
         speex_encoder_ctl(st, SPEEX_GET_BITRATE, &tmp);
         fputc (ch, stderr);
         cumul_bits += tmp;
         enc_frames += 1;
         if (!quiet)
         {
            if (vad_enabled || vbr_enabled || abr_enabled)
               fprintf (stderr, "Bitrate is use: %d bps  (average %d bps)   ", tmp, (int)(cumul_bits/enc_frames));
            else
               fprintf (stderr, "Bitrate is use: %d bps     ", tmp);
            if (output_rate)
               printf ("%d\n", tmp);
         }

      }

      if (wave_input)
      {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, &size);
      } else {
         nb_samples = read_samples(fin,frame_size,fmt,chan,lsb,input, NULL, NULL);
      }
      if (nb_samples==0)
      {
         eos=1;
      }
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      total_samples += nb_samples;

      if ((id+1)%nframes!=0)
         continue;
      speex_bits_insert_terminator(&bits);
      nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES);
      speex_bits_reset(&bits);
      op.packet = (unsigned char *)cbits;
      op.bytes = nbBytes;
      op.b_o_s = 0;
      /*Is this redundent?*/
      if (eos && total_samples<=nb_encoded)
         op.e_o_s = 1;
      else
         op.e_o_s = 0;
      op.granulepos = (id+1)*frame_size-lookahead;
      if (op.granulepos>total_samples)
         op.granulepos = total_samples;
      /*printf ("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, nframes, lookahead, 5, 6);*/
      op.packetno = 2+id/nframes;
      ogg_stream_packetin(&os, &op);

      /*Write all new pages (most likely 0 or 1)*/
      while (ogg_stream_pageout(&os,&og))
      {
         ret = oe_write_page(&og, fout);
         if(ret != og.header_len + og.body_len)
         {
            fprintf (stderr,"Error: failed writing header to output stream\n");
            exit(1);
         }
         else
            bytes_written += ret;
      }
   }
   if ((id+1)%nframes!=0)
   {
      while ((id+1)%nframes!=0)
      {
         id++;
         speex_bits_pack(&bits, 15, 5);
      }
      nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES);
      op.packet = (unsigned char *)cbits;
      op.bytes = nbBytes;
      op.b_o_s = 0;
      op.e_o_s = 1;
      op.granulepos = (id+1)*frame_size-lookahead;
      if (op.granulepos>total_samples)
         op.granulepos = total_samples;

      op.packetno = 2+id/nframes;
      ogg_stream_packetin(&os, &op);
   }
   /*Flush all pages left to be written*/
   while (ogg_stream_flush(&os, &og))
   {
      ret = oe_write_page(&og, fout);
      if(ret != og.header_len + og.body_len)
      {
         fprintf (stderr,"Error: failed writing header to output stream\n");
         exit(1);
      }
      else
         bytes_written += ret;
   }

   speex_encoder_destroy(st);
   speex_bits_destroy(&bits);
   ogg_stream_clear(&os);

   if (close_in)
      fclose(fin);
   if (close_out)
      fclose(fout);
   return 0;
}
Пример #13
0
int SpeexEncoder::Initialize(const char* filename, char* modeInput, int channels, int pcmRate)
{
	char *comments;
	int comments_length;
	fprintf(stderr, "SpeexEncoder: Initialize\n");
	SpeexHeader header;
	fprintf(stderr, "modeInput: %s\n", modeInput);
	if (modeInput != NULL){
		if (strcmp(modeInput, "narrowband") == 0)
		{
			modeID = SPEEX_MODEID_NB;
		}
		else if (strcmp(modeInput, "wideband") == 0)
		{
			modeID = SPEEX_MODEID_WB;
		}
		else if (strcmp(modeInput, "ultra-wideband") == 0)
		{
			modeID = SPEEX_MODEID_UWB;
		}
	}
	if (channels > 0){
		chan = channels;
	}
	
	speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
	snprintf(vendor_string, sizeof(vendor_string), "Encoded with Speex %s", speex_version);

	comment_init(&comments, &comments_length, vendor_string);
	comment_add(&comments, &comments_length, "TITLE=", "saa1");
	comment_add(&comments, &comments_length, "AUTHOR=", "uptivity");
	comment_add(&comments, &comments_length, "FORMATTYPE=", (char*)speex_version);
	comment_add(&comments, &comments_length, "DURATION=", "00000");
	/*Initialize Ogg stream struct*/
	srand(time(NULL));
	if (ogg_stream_init(&os, rand()) == -1)
	{
		fprintf(stderr, "Error: stream init failed\n");
		exit(1);
	}
	rate = pcmRate;
   if (modeID == -1 )
   {
	   /* By default, use narrowband/8 kHz */
	   modeID = SPEEX_MODEID_NB;
	   if (pcmRate < 0){
		   rate = 8000;
	   }
   }
   if (pcmRate < 0){
	   if (modeID == SPEEX_MODEID_NB)
	   	rate = 8000;
	   else if (modeID == SPEEX_MODEID_WB)
	   	rate = 16000;
	   else if (modeID == SPEEX_MODEID_UWB)
	   	rate = 32000;
   }

   if (!mode)
	   mode = speex_lib_get_mode(modeID);

   speex_init_header(&header, rate, 1, mode);
   header.frames_per_packet = 1;
   header.vbr = 0;
   header.nb_channels = chan;

   {
	   char *st_string = "mono";
	   if (chan == 2)
		   st_string = "stereo";
		fprintf(stderr, "Encoding %d Hz audio using %s mode (%s)\n",
		header.rate, mode->modeName, st_string);
   }

   /*Initialize Speex encoder*/
   st = speex_encoder_init(mode);
   fout = fopen(filename, "wb");
	if (!fout)
	{
		perror(filename);
		exit(1);
	}

   speex_encoder_ctl(st, SPEEX_GET_FRAME_SIZE, &frame_size);
   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &complexity);
   speex_encoder_ctl(st, SPEEX_SET_SAMPLING_RATE, &rate);
   if (quality >= 0)
   {
	   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &quality);
   }

   speex_encoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);

   /*Write header*/
   {
	   int packet_size;
	   op.packet = (unsigned char *)speex_header_to_packet(&header, &packet_size);
	   op.bytes = packet_size;
	   op.b_o_s = 1;
	   op.e_o_s = 0;
	   op.granulepos = 0;
	   op.packetno = 0;

	   // submit the packet to the ogg streaming layer
	   ogg_stream_packetin(&os, &op);
	   free(op.packet);

	   while ((result = ogg_stream_flush(&os, &og)))
	   {
		   if (!result) break;
		   ret = oe_write_page(&og, fout);
		   if (ret != og.header_len + og.body_len)
		   {
			   fprintf(stderr, "Error: failed writing header to output stream\n");
			   exit(1);
		   }
		   else
			   bytes_written += ret;
	   }

	   op.packet = (unsigned char *)comments;
	   op.bytes = comments_length;
	   op.b_o_s = 0;
	   op.e_o_s = 0;
	   op.granulepos = 0;
	   op.packetno = 1;
	   ogg_stream_packetin(&os, &op);
	   durationIndex = bytes_written + os.header_fill + os.body_fill - 5;
   }

   /* writing the rest of the speex header packets */
   while ((result = ogg_stream_flush(&os, &og)))
   {
	   if (!result) break;
	   ret = oe_write_page(&og, fout);
	   if (ret != og.header_len + og.body_len)
	   {
		   fprintf(stderr, "Error: failed writing header to output stream\n");
		   exit(1);
	   }
	   else
		   bytes_written += ret;
   }
   free(comments);

   speex_bits_init(&bits);

   return 0;
}
Пример #14
0
int SpeexEncoder::EncodeFromFile(FILE *fin)
{
	int id = -1;
	int nframes = 1;
	int lsb = 1;
	int fmt = 16;
	spx_int32_t size;
	
	nb_samples = read_samples(fin, frame_size, fmt, chan, lsb, input, &size);

	if (nb_samples == 0)
		eos = 1;
	total_samples += nb_samples;
	nb_encoded = -lookahead;

	
	/*Main encoding loop (one frame per iteration)*/
	while (!eos || total_samples > nb_encoded)
	{
		id++;
		/*Encode current frame*/
		if (chan == 2)
			speex_encode_stereo_int(input, frame_size, &bits);

		if (preprocess)
			speex_preprocess(preprocess, input, NULL);

		speex_encode_int(st, input, &bits);

		nb_encoded += frame_size;
		nb_samples = read_samples(fin, frame_size, fmt, chan, lsb, input, NULL);

		if (nb_samples == 0)
		{
			eos = 1;
		}
		if (eos && total_samples <= nb_encoded)
			op.e_o_s = 1;
		else
			op.e_o_s = 0;
		total_samples += nb_samples;

		if ((id + 1) % nframes != 0)
			continue;

		speex_bits_insert_terminator(&bits);
		nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES);
		speex_bits_reset(&bits);
		op.packet = (unsigned char *)cbits;
		op.bytes = nbBytes;
		op.b_o_s = 0;
		/*Is this redundent?*/
		if (eos && total_samples <= nb_encoded)
			op.e_o_s = 1;
		else
			op.e_o_s = 0;
		op.granulepos = (id + 1)*frame_size - lookahead;
		if (op.granulepos > total_samples)
			op.granulepos = total_samples;
		//printf("granulepos: %d %d %d %d %d %d\n", (int)op.granulepos, id, 2 + id / nframes, lookahead, 5, 6);
		op.packetno = 2 + id / nframes;
		ogg_stream_packetin(&os, &op);

		/*Write all new pages (most likely 0 or 1)*/
		while (ogg_stream_pageout(&os, &og))
		{
			ret = oe_write_page(&og, fout);
			if (ret != og.header_len + og.body_len)
			{
				fprintf(stderr, "Error: failed writing header to output stream\n");
				fclose(fin);
				exit(1);
			}
			else
				bytes_written += ret;
		}
	}
	if ((id + 1) % nframes != 0)
	{
		while ((id + 1) % nframes != 0)
		{
			id++;
			speex_bits_pack(&bits, 15, 5);
		}
		nbBytes = speex_bits_write(&bits, cbits, MAX_FRAME_BYTES);
		op.packet = (unsigned char *)cbits;
		op.bytes = nbBytes;
		op.b_o_s = 0;
		op.e_o_s = 1;
		op.granulepos = (id + 1)*frame_size - lookahead;
		if (op.granulepos > total_samples)
			op.granulepos = total_samples;

		op.packetno = 2 + id / nframes;
		ogg_stream_packetin(&os, &op);
	}

	/*Flush all pages left to be written*/
	while (ogg_stream_flush(&os, &og))
	{
		ret = oe_write_page(&og, fout);
		if (ret != og.header_len + og.body_len)
		{
			fprintf(stderr, "Error: failed writing header to output stream\n");
			fclose(fin);
			exit(1);
		}
		else
			bytes_written += ret;
	}

	int durationInSec = frame_size *id / rate;
	fprintf(stderr, "Duration: %d\n", durationInSec);
	int minutes = (int)(frame_size *id / rate)/60;
	int seconds = (frame_size *id / rate) - (minutes * 60);
	fprintf(stderr, "Duration Minutes: %d\n", minutes);
	fprintf(stderr, "Duration Seconds: %d\n", seconds);
	
	char duration[5];
	sprintf(duration, "%05d", durationInSec);

	fseek(fout, durationIndex, SEEK_SET);
	fputs(duration, fout);
	fclose(fin);

	return 0;
}