diff options
Diffstat (limited to 'raw2ogg/raw2vorbis.c')
-rw-r--r-- | raw2ogg/raw2vorbis.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/raw2ogg/raw2vorbis.c b/raw2ogg/raw2vorbis.c new file mode 100644 index 0000000..5643695 --- /dev/null +++ b/raw2ogg/raw2vorbis.c @@ -0,0 +1,175 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#include <vorbis/vorbisenc.h> + +#define READ_SZ 1024 +signed char readbuffer[READ_SZ*4+44]; + +int main(int argc, char **argv) +{ + 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 */ + + vorbis_info vi; /* struct that stores all the static vorbis bitstream + settings */ + vorbis_comment vc; /* struct that stores all the user comments */ + + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + int eos=0,ret; + int i, founddata; + FILE *fin=NULL,*fout=NULL; + + /* get input/output files from input */ + if (argc != 3) + { + printf("%s [input] [output]\n",argv[0]); + exit(1); + } + + fin = fopen(argv[1],"r"); + if (fin == NULL) + { + printf("Cant open file %s\n", argv[1]); + exit(1); + } + + fout = fopen(argv[2],"w"); + if (fout == NULL) + { + printf("Cant open file %s\n", argv[2]); + exit(1); + } + + /* encoding setup */ + vorbis_info_init(&vi); + + ret=vorbis_encode_init_vbr(&vi,2,44100,-.1); + if (ret) + { + printf("Cant setup encode mode\n"); + exit(1); + } + + /* add comment */ + vorbis_comment_init(&vc); + vorbis_comment_add_tag(&vc, "ENCODER", "encoder_example.c"); + + /* set up the analysis state and auxiliary encoding storage */ + vorbis_analysis_init(&vd, &vi); + vorbis_block_init(&vd, &vb); + + /* set up our packet->stream encoder */ + /* pick a random serial number; that way we can more likely build + chained streams just by concatenation */ + srand(time(NULL)); + ogg_stream_init(&os, rand()); + + /* Vorbis streams begin with three headers; the initial header (with + most of the codec setup parameters) which is mandated by the Ogg + bitstream spec. The second header holds any comment fields. The + third header holds the bitstream codebook. We merely need to + make the headers, then pass them to libvorbis one at a time; + libvorbis handles the additional Ogg bitstream constraints */ + + { + 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); /* automatically placed in its own + page */ + ogg_stream_packetin(&os, &header_comm); + ogg_stream_packetin(&os, &header_code); + + /* This ensures the actual + * audio data will start on a new page, as per spec + */ + while(!eos) + { + int result=ogg_stream_flush(&os, &og); + if(result==0) + break; + fwrite(og.header, 1, og.header_len, fout); + fwrite(og.body, 1, og.body_len, fout); + } + } + + while (!eos) + { + long i; + long bytes = fread(readbuffer, 1, READ_SZ*4, fin); + + if (bytes == 0) + { + vorbis_analysis_wrote(&vd, 0); + } else + { + float **buffer = vorbis_analysis_buffer(&vd, READ_SZ); + /*do i need interleaver samples*/ + for (i=0; i<bytes/4; i++) + { + buffer[0][i] = ((readbuffer[i*4+1]<<8)| + (0x00ff&(int)readbuffer[i*4]))/32768.f; + buffer[1][i] = ((readbuffer[i*4+3]<<8)| + (0x00ff&(int)readbuffer[i*4+2]))/32768.f; + } + vorbis_analysis_wrote(&vd, bytes/4); + } + + /* vorbis does some data preanalysis, then divvies up blocks for + more involved (potentially parallel) processing. Get a single + block for encoding now */ + + while (vorbis_analysis_blockout(&vd, &vb)==1) + { + /* analysis, assume we want to use bitrate management */ + vorbis_analysis(&vb, NULL); + vorbis_bitrate_addblock(&vb); + + while(vorbis_bitrate_flushpacket(&vd,&op)) + { + /* weld the packet into the bitstream */ + ogg_stream_packetin(&os, &op); + + /* write out pages (if any) */ + while (!eos) + { + int result = ogg_stream_pageout(&os, &og); + if (result == 0) + break; + fwrite(og.header, 1, og.header_len, fout); + fwrite(og.body, 1, og.body_len, fout); + + /* this could be set above, but for illustrative purposes, I do + it here (to show that vorbis does know where the stream ends) */ + + 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(fout); + fclose(fin); + + printf("Done\n"); + + return 0; +}
\ No newline at end of file |