[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