Click here to Skip to main content
15,887,273 members
Articles / Programming Languages / C# 4.0

Fun with Google Speech Recognition Service

Rate me:
Please Sign up or sign in to vote.
4.14/5 (7 votes)
26 Apr 2024CPOL2 min read 81.5K   10.3K   21  
Create text issues in Redmine by using Google speech recognition service
// This is the main DLL file.

#include "stdafx.h"
#include "stock_buffer.h"

#include "Tags.h"
#include "VorbisEnc.h"


#define READ 1024

void VorbisEnc::IVorbisEnc::UploadChunk32(signed char* data, long sz)
{	
	float f_temp = (float)FIXED32_ONE;
	int eos=0, ret;
	//while(!eos){
	long i = 0;
	//long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
	long bytes = sz;
	char* readbuffer = (char*)data;

	if(bytes == 0){
		/* end of file.  this can be done implicitly in the mainline,
		but it's easier to see here in non-clever fashion.
		Tell the library we're at end of stream so that it can handle
		the last frame and mark end of stream in the output properly */
		vorbis_analysis_wrote(&vd, 0);

	}else{
		/* data to encode */

		/* expose the buffer to submit data */
		//float **buffer=vorbis_analysis_buffer(&vd,1024);
		float **buffer = vorbis_analysis_buffer(&vd, sz / (this->channels * 4));

		/* uninterleave samples */
		//TODO: any number of channels
		//stereo
		if(this->channels == 2)
		{
			for(i=0;i < bytes / 8; i++){
				buffer[0][i] = (*(int*)(readbuffer+(i*8))) / f_temp;
				buffer[1][i] = (*(int*)(readbuffer+(i*8 + 4))) / f_temp;
			}
		}
		//mono
		else if(this->channels == 1)
		{
			for(i=0;i < bytes / 4; i++)
				buffer[0][i] = (*(int*)(readbuffer+(i*4))) / f_temp;
				//buffer[0][i] = ((readbuffer[i*2+1] << 8)|
				//	(0x00ff & (int)readbuffer[i*2])) / 32768.f;
		}

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

	/* 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,this->_oggfile);
				fwrite(og.body,1,og.body_len,this->_oggfile);

				/* 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;
			}
		}
	}
	//}
}
void VorbisEnc::IVorbisEnc::UploadChunk(signed char* data, long sz)
{	
	int eos=0, ret;
	//while(!eos){
	long i = 0;
	//long bytes=fread(readbuffer,1,READ*4,stdin); /* stereo hardwired here */
	long bytes = sz;
	char* readbuffer = (char*)data;

	if(bytes == 0){
		/* end of file.  this can be done implicitly in the mainline,
		but it's easier to see here in non-clever fashion.
		Tell the library we're at end of stream so that it can handle
		the last frame and mark end of stream in the output properly */
		vorbis_analysis_wrote(&vd, 0);

	}else{
		/* data to encode */

		/* expose the buffer to submit data */
		//float **buffer=vorbis_analysis_buffer(&vd,1024);
		float **buffer = vorbis_analysis_buffer(&vd, sz / (this->channels * 2));

		/* uninterleave samples */
		//TODO: any number of channels
		//stereo
		if(this->channels == 2)
		{
			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;
			}
		}
		//mono
		else if(this->channels == 1)
		{
			for(i=0;i < bytes / 2; i++)
				buffer[0][i] = ((readbuffer[i*2+1] << 8)|
					(0x00ff & (int)readbuffer[i*2])) / 32768.f;
		}

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

	/* 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,this->_oggfile);
				fwrite(og.body,1,og.body_len,this->_oggfile);

				/* 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;
			}
		}
	}
	//}
}
void VorbisEnc::IVorbisEnc::Close(void)
{
	ogg_stream_clear(&this->os);
	vorbis_block_clear(&this->vb);
	vorbis_dsp_clear(&this->vd);
	vorbis_comment_clear(&this->vc);
	vorbis_info_clear(&this->vi);
	fclose(this->_oggfile);
}
//2,44100,0.1
int VorbisEnc::IVorbisEnc::Initialise(char* stringFile, int channels, int rate, double q, Tag^ t)
{  
	//this->_oggfile = fopen(stringFile, "wb");
	this->_oggfile = _wfopen((wchar_t*)stringFile, L"wb");
	this->channels = channels;

	if(!this->_oggfile)return 0;

	int eos=0,ret;
	int i, founddata;

	vorbis_info_init(&this->vi);
	if(q<10.0)
	{
		ret=vorbis_encode_init_vbr(&this->vi, channels, rate, q);
	}else{
		q = q * 1000;
		ret = vorbis_encode_init(&this->vi, channels, rate, -1, q, -1);
	}
	if(ret)
		return 0;

	/* add a comment */
	vorbis_comment_init(&this->vc);
	
	if(t->track)
		vorbis_comment_add_tag(&this->vc, "TITLE", t->track);
	if(t->artist)
		vorbis_comment_add_tag(&this->vc, "ARTIST", t->artist);
	if(t->album)
		vorbis_comment_add_tag(&this->vc, "ALBUM", t->album);
	if(t->year)
		vorbis_comment_add_tag(&this->vc, "DATE", t->year);
	if(t->tracknum)
		vorbis_comment_add_tag(&this->vc, "TRACKNUMBER", t->tracknum);
	if(t->genre)
		vorbis_comment_add_tag(&this->vc, "GENRE", t->genre);
	if(t->pic)
	{
		vorbis_comment_add_tag(&this->vc, "COVERARTMIME", "image/jpeg");
		vorbis_comment_add_tag(&this->vc, "COVERARTDESCRIPTION", "cover.jpg");
		vorbis_comment_add_tag(&this->vc, "COVERART", t->pic);
	}
	if(t->publisher)
		vorbis_comment_add_tag(&this->vc, "PUBLISHER", t->publisher);
	if(t->comment)
		vorbis_comment_add_tag(&this->vc, "COMMENT", t->comment);
	vorbis_comment_add_tag(&this->vc, "ENCODER", "cerriun VorbisEnc library for .NET, please navigate to http://www.xiph.org/");
	/* set up the analysis state and auxiliary encoding storage */
	vorbis_analysis_init(&this->vd,&this->vi);
	vorbis_block_init(&this->vd,&this->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(&this->os,rand());

	{
		ogg_packet header;
		ogg_packet header_comm;
		ogg_packet header_code;

		vorbis_analysis_headerout(&this->vd,&vc,&header,&header_comm,&header_code);
		ogg_stream_packetin(&this->os,&header); /* automatically placed in its own
										  page */
		ogg_stream_packetin(&this->os,&header_comm);
		ogg_stream_packetin(&this->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(&this->os,&this->og);
			if(result==0)break;
			fwrite(this->og.header,1,this->og.header_len,this->_oggfile);
			fwrite(this->og.body,1,this->og.body_len,this->_oggfile);
		}
		return 1;
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions