Click here to Skip to main content
15,896,063 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)
10 May 2024CPOL2 min read 81.6K   10.4K   21  
Create text issues in Redmine by using Google speech recognition service
#define useflac 1
#include "stdafx.h"

#include "FlacEnc.h"

static FLAC__int32 pcm[2048/*samples*/ * 1/*channels*/];

void progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
{
	(void)encoder, (void)client_data;

#ifdef _MSC_VER
	//fprintf(stderr, "wrote %I64u bytes, %I64u/%u samples, %u/%u frames\n", bytes_written, samples_written, 0, frames_written, total_frames_estimate);
#else
	//fprintf(stderr, "wrote %llu bytes, %llu/%u samples, %u/%u frames\n", bytes_written, samples_written, 0, frames_written, total_frames_estimate);
#endif
}

static 
bool InitialiseEncoder(char* filepath, FILE** _file, FLAC__StreamEncoder** _encoder, FLAC__StreamMetadata** _metadata1, FLAC__StreamMetadata** _metadata2)
{
	FLAC__bool ok = true;
	FLAC__StreamEncoder *encoder = 0;
	FLAC__StreamEncoderInitStatus init_status;
	FLAC__StreamMetadata *metadata[2];
	/*FLAC__StreamMetadata* metadata1;
	FLAC__StreamMetadata* metadata2;*/

	FLAC__StreamMetadata_VorbisComment_Entry entry;

	unsigned sample_rate = 16000;
	unsigned channels = 1;
	unsigned bps = 16;

	/* allocate the encoder */
	if((encoder = FLAC__stream_encoder_new()) == NULL) {
		//fprintf(stderr, "ERROR: allocating encoder\n");
		return false;
	}

	ok &= FLAC__stream_encoder_set_verify(encoder, true);
	ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
	ok &= FLAC__stream_encoder_set_channels(encoder, channels);
	ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
	ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
	ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, 0);

	/* now add some metadata; we'll add some tags and a padding block */
	if(ok) {
		//if(
		//	(metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL ||
		//	(metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL ||
		//	/* there are many tag (vorbiscomment) functions but these are convenient for this particular use: */
		//	!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ARTIST", "cerriun speech") ||
		//	!FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) || /* copy=false: let metadata object take control of entry's allocated string */
		//	!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "YEAR", "2012") ||
		//	!FLAC__metadata_object_vorbiscomment_append_comment(metadata[1], entry, /*copy=*/false)
		//	) {
		//		//fprintf(stderr, "ERROR: out of memory or tag error\n");
		//		ok = false;
		//}

		//metadata[1]->length = 1234; /* set the padding length */

		/*metadata[0] = metadata1;
		metadata[1] = metadata2;*/
		//ok = FLAC__stream_encoder_set_metadata(encoder, metadata, 2);
	}
		/* initialize encoder */
	FILE* flacfile = _wfopen((wchar_t*)filepath, L"wb");
	if(ok) {
		init_status = FLAC__stream_encoder_init_FILE(encoder, flacfile, progress_callback, /*client_data=*/NULL);
		if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
			fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]);
			ok = false;
		}
	}
	

	*_encoder = encoder;
	*_file = flacfile;
	//*_metadata1 = metadata[0];
	//*_metadata2 = metadata[1];

	return ok;
}

static 
bool ProcessEncoder(FLAC__StreamEncoder *encoder, FLAC__byte* _pcm, size_t need)
{
	FLAC__bool ok = true;
	/* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */

	/* feed samples to encoder */
	for(unsigned int i = 0; i < need*1; i++) {
		/* inefficient but simple and works on big- or little-endian machines */
		pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)_pcm[2*i+1] << 8) | (FLAC__int16)_pcm[2*i]);
	}
	ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
	return ok;
}

static
bool CloseEncoder(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata* _metadata1, FLAC__StreamMetadata* _metadata2)
{
	FLAC__bool ok = true;
	ok = FLAC__stream_encoder_finish(encoder);

	//fprintf(stderr, "encoding: %s\n", ok? "succeeded" : "FAILED");
	//fprintf(stderr, "   state: %s\n", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]);

	/* now that encoding is finished, the metadata can be freed */
	//FLAC__metadata_object_delete(_metadata1);
	//FLAC__metadata_object_delete(_metadata2);

	FLAC__stream_encoder_delete(encoder);
	return ok;
}

bool VorbisEnc::IFlacEnc::Start(char* strpath)
{	
	//bool r = InitialiseEncoder(strpath, &this->encoder, &this->metadata1, &this->metadata2);
	bool r = InitialiseEncoder(strpath, &this->flacfile, &this->encoder, &this->metadata1, &this->metadata2);
	//fprintf(stdout, "%s", r?"flac good":"flac not inited");
	return r;
}

void VorbisEnc::IFlacEnc::Close()
{
	bool r = CloseEncoder(this->encoder, this->metadata1, this->metadata2);
	if(this->flacfile != 0)
		fclose(this->flacfile);

	//fprintf(stdout, "%s", r?"flac good":"flac not closed");
}

void  VorbisEnc::IFlacEnc::UploadChunk(signed char* data, long sz)
{
	bool r = ProcessEncoder(this->encoder, (FLAC__byte*)data, sz / 2);// 4096/2 = 2048 = pcm sz
}

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