[Vorbis-dev] c++ Wav->ogg encoder

keghn keghn at netscape.net
Wed Jun 19 15:40:05 PDT 2013


keghn <keghn <at> netscape.net> writes:

> 
> 
> can it be in linux?
> 
 I have this one:

	/*
	 This progam generates sine wave and then compresses it and then
	save it to the hard drive as an .ogg file.
	 The sine waves are 22050 sample rate and 8bits and one channal 
(mono).
	 But in truth, two mono sine waves are made and combined by the data 
compressor into a
	single stereo .ogg file.
	 The sine waves do not have  the 44 byte wav header just the data 
part is made here
	and that all that is needed for now. 
	the name of the file writen to hard drive will be 
"vorbis_2ch_q9.0_22050.ogg".

	 Tested on Mint 14.1 mate 64 bit linux laptop.
	compile as:  

	gcc k1kompressor.c -lvorbis -lvorbisenc -lvorbisfile -o k1kompressor

	run with ./k1kompressor
    
   then play the file with what ever player than can play .ogg file.
 	
********************************************************************/

	#include <stdio.h>
	#include <stdlib.h>
	#include <math.h>
	#include <string.h>
	#include <errno.h>
	#include <vorbis/codec.h>
	#include <vorbis/vorbisenc.h>

	//#define datasize1        2048//the datasize1 is sizeof is 4 * 2048 
= 8192 bytes same as int datasize1 = 2048
	#define datasize1        16384

	#define ARRAY_LEN(x)   (sizeof(x)/sizeof(x[0]))
	// Create simple test pcm data sine wave without the 44 byte wav 
header.
	void gen_pcm_sine (char *pcm_data, int len, float maximum, unsigned 
int s1sample_rate,  float frequ);
	void vorbis_kompress_wave_save (const char *filename, int srate, 
float q, const float * data1, int count1,const float * 
data2, int count2, int ch);
	void pcm_to_float (float * data_float_0, char * pcm_8bit_data_0, int 
dlength);

	int main(void)
		{
		  float hz_freq;
		  static char pcm_8bit_data_1 [datasize1];
		  static char pcm_8bit_data_2 [datasize1];
		  static float data_float_1 [datasize1];
		  static float data_float_2 [datasize1];
		  unsigned int sample_rate = 22050; //44100, 48000, 32000, 
22050, 16000, 96000
		  unsigned k ;
		  int errors = 0 ;
		  int ch;
		  float loudness;
		  loudness = 127.0;// 127 is max for 8bit 

		  hz_freq = 300; //the first mono sine wave, left head 
phone.

		  gen_pcm_sine (pcm_8bit_data_1, datasize1, loudness, 
sample_rate, hz_freq);// volume range of 127 to -127
		  // changing 8bit signed wave to floting point fraction.
		  pcm_to_float ( data_float_1,pcm_8bit_data_1, datasize1); 
// .9999 to -.9999 range convertion

		  hz_freq = 2000; //the seconed mono sine wave, right head 
phone.

		  gen_pcm_sine (pcm_8bit_data_2, datasize1, loudness, 
sample_rate, hz_freq);

		  pcm_to_float ( data_float_2, pcm_8bit_data_2, datasize1);

		  ch = 2;
		  float q=.9;
		  printf("\nTesting %d channel%s\n\n",ch,ch==1?"":"s");

		  char filename [64] ;
		  snprintf (filename, sizeof (filename), 
"vorbis_%dch_q%.1f_%u.ogg", ch,q*10,sample_rate);
		  printf ("    %-20s : ", filename);
		  fflush (stdout);

		  vorbis_kompress_wave_save (filename, sample_rate , q, 
data_float_1, ARRAY_LEN (data_float_1), data_float_2, 
ARRAY_LEN (data_float_2),ch);

		  printf("   file has been writen to the hard drive.\n\n");
		  return 0;
		 }

	// generating sine wave that in floating point numbers.

	void gen_pcm_sine (char *pcm_data, int len, float maximum, unsigned 
int s1sample_rate, float frequ)
		 {
		   unsigned int  y,yy;
		   float mm , xx;
		   y = 0;
		   mm = (2.0 * M_PI) / s1sample_rate;//converting x movement 
rate to radians, through the sin wave.
		   for (y = 0 ; y < len ; y++)
				    {/// ///
					  xx = y * mm; //x distance is 
caluclated.
					  pcm_data [y] = maximum * sin( 
frequ * xx); //making a sine wave of frequ.  mono_16 pcm or 
raw
				     }/// ///
		   return ;
		  }

	 void pcm_to_float ( float * data_float, char * pcm_8bit_data, int 
dlength)
			 {//333333333333333333333333333333333333333333
			   int kccc;
			   kccc=0;
			   float kfff;
			   while (kccc<dlength)
			      {
			       kfff = (pcm_8bit_data 
[kccc])/127.0;//converting 8 bit pcm signed values to floating point. ogg 
uses 
floating point.

			        data_float [kccc] = kfff;
			        kccc = kccc +1;
			       }
			  }//333333333333333333333333333333333333333333


	void vorbis_kompress_wave_save (const char *filename, int srate, 
float q, const float * data1, int count1,const float * 
data2, int count2, int ch)
		 {
		   FILE * file ; // for the out put file.
		   ogg_stream_state os;
		   ogg_page         og;
		   ogg_packet       op;
		   vorbis_info      vi;
		   vorbis_comment   vc;
		   vorbis_dsp_state vd;
		   vorbis_block     vb;

		   int eos = 0, ret;

		   if ((file = fopen (filename, "wb")) == NULL)
				{
				  printf("\n\nError : fopen failed : %s\n", 
strerror (errno)) ;
				  exit (1) ;
				 }

		   //******** Encode setup ************

		   vorbis_info_init (&vi);

		   ret = vorbis_encode_init_vbr (&vi,ch,srate,q);
		   if (ret)
				   {
				     printf ("vorbis_encode_init_vbr return 
%d\n", ret) ;
				     exit (1) ;
				    }

		   vorbis_comment_init (&vc);
		   vorbis_comment_add_tag (&vc,"ENCODER","test/util.c");
		   vorbis_analysis_init (&vd,&vi);
		   vorbis_block_init (&vd,&vb);

		   ogg_stream_init (&os,12345678);

		   {/// /// ///
		     ogg_packet header;
		     ogg_packet header_comm;
		     ogg_packet header_code;

		     vorbis_analysis_headerout 
(&vd,&vc,&header,&header_comm,&header_code);
		     ogg_stream_packetin (&os,&header);
		     ogg_stream_packetin (&os,&header_comm);
		     ogg_stream_packetin (&os,&header_code);

		     //Ensures the audio data will start on a new page.
		     while (!eos)
						 {
						   int result = 
ogg_stream_flush (&os,&og);
						   if (result == 0)
										   
{
										     
break;
										    
}
						   fwrite 
(og.header,1,og.header_len,file);
						   fwrite 
(og.body,1,og.body_len,file);
						  }
		    }/// /// ///

	{/// /// /// ///
	  // expose the buffer to submit data 
	  float **buffer = vorbis_analysis_buffer (&vd,count1);  //count1 or 
count2 or which ever is the longer one.
	  int i = 0;
	  for(i=0;i<count1; i++)
				   		 {/// /
	//			   		   buffer[i] = data1[i];	
// to play one channel through both side at same 
time. mono.
				   		   buffer[0][i] = data1[i];	
// load pcm wave sine wave into left channell or 
side of head phone.
	//				   		   buffer[0][i] = 0;		
//cancel out a channel for testing
						
				   		   buffer[1][i] = data2[i];	
//right channel to do just one channel remove this 
line with //.
	//				   		   buffer[1][i] = 
0.0;
	/*
				   		   buffer[2][i] = 
data222[i]; //up to eight channels
				   		   buffer[3][i] = 
data333[i];					
				   		   buffer[4][i] = 
data444[i];
				   		   buffer[5][i] = 
data555[i];
				   		   buffer[6][i] = 
data666[i];
				   		   buffer[7][i] = 
data777[i];
	*/
				   		  }/// /


	  //tell the library how much we actually submitted
	  vorbis_analysis_wrote (&vd,count1);
	  vorbis_analysis_wrote (&vd,0);
	 }/// /// /// ///

	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);

				  while (!eos)
					   {
					     int result = ogg_stream_pageout 
(&os,&og);
					     if (result == 0){break;}				
					     fwrite 
(og.header,1,og.header_len,file);
					     fwrite 
(og.body,1,og.body_len,file);
					     if (ogg_page_eos (&og)){eos = 
1;}				
					    }
				 }////////////
		 }/////////// ///

	  ogg_stream_clear (&os);
	  vorbis_block_clear (&vb);
	  vorbis_dsp_clear (&vd);
	  vorbis_comment_clear (&vc);
	  vorbis_info_clear (&vi);
	  fclose (file) ;
	 }






More information about the Vorbis-dev mailing list