[Scummvm-cvs-logs] SF.net SVN: scummvm: [27907] tools/branches/gsoc2007-toolsgui

lightcast at users.sourceforge.net lightcast at users.sourceforge.net
Thu Jul 5 01:00:39 CEST 2007


Revision: 27907
          http://scummvm.svn.sourceforge.net/scummvm/?rev=27907&view=rev
Author:   lightcast
Date:     2007-07-04 16:00:38 -0700 (Wed, 04 Jul 2007)

Log Message:
-----------
Added support for libvorbis and libflac.  The new function encodeRaw uses these libraries without the need for external binaries, but will fall back to the old code if linking libvorbis and/or libflac are disabled with DISABLE_VORBIS and DISABLE_FLAC respectively.

Modified Paths:
--------------
    tools/branches/gsoc2007-toolsgui/compress.c
    tools/branches/gsoc2007-toolsgui/compress.h

Modified: tools/branches/gsoc2007-toolsgui/compress.c
===================================================================
--- tools/branches/gsoc2007-toolsgui/compress.c	2007-07-04 21:38:30 UTC (rev 27906)
+++ tools/branches/gsoc2007-toolsgui/compress.c	2007-07-04 23:00:38 UTC (rev 27907)
@@ -35,37 +35,32 @@
 	int nominalBitr;
 	int minBitr;
 	int maxBitr;
-	int quality;
+	float quality;
 	bool silent;
 } oggencparams;
 
-/* FIXME: This is an evil way to pass on the params to FLAC.
- It makes it near impossible to reliably pass default params to the
- encoder.
-*/
 typedef struct {
-	char * const* argv;
-	int numArgs;
+	int compressionLevel;
+	int blocksize;
+	bool verify;
+	bool silent;
 } flaccparams;
 
 typedef struct {
-	bool isLittleEndian;
-	bool isStereo;
-	bool isUnsigned;
+	bool isLittleEndian, isStereo;
 	uint8 bitsPerSample;
 } rawtype;
 
 lameparams encparms = { minBitrDef, maxBitrDef, false, algqualDef, vbrqualDef, 0 };
 oggencparams oggparms = { -1, -1, -1, oggqualDef, 0 };
-flaccparams flacparms;
-rawtype	rawAudioType = { false, false, false, 8 };
+flaccparams flacparms = { flacCompressDef, flacBlocksizeDef, false, false };
+rawtype	rawAudioType = { false, false, 8 };
 
 const char *tempEncoded = TEMP_MP3;
 
-void setRawAudioType(bool isLittleEndian, bool isStereo, bool isUnsigned, uint8 bitsPerSample) {
+void setRawAudioType(bool isLittleEndian, bool isStereo, uint8 bitsPerSample) {
 	rawAudioType.isLittleEndian = isLittleEndian;
 	rawAudioType.isStereo = isStereo;
-	rawAudioType.isUnsigned = isUnsigned;
 	rawAudioType.bitsPerSample = bitsPerSample;
 }
 
@@ -105,102 +100,476 @@
 }
 
 void encodeAudio(const char *inname, bool rawInput, int rawSamplerate, const char *outname, CompressMode compmode) {
+	bool err = false;
 	char fbuf[2048];
 	char *tmp = fbuf;
-	int i;
-	bool err = false;
 
-	switch (compmode) {
-	case kVorbisMode:
-		tmp += sprintf(tmp, "oggenc ");
-		if (rawInput) {
-			tmp += sprintf(tmp, "--raw ");
-			tmp += sprintf(tmp, "--raw-chan=%d ", (rawAudioType.isStereo ? 2 : 1));
-			tmp += sprintf(tmp, "--raw-bits=%d ", rawAudioType.bitsPerSample);
-			tmp += sprintf(tmp, "--raw-rate=%d ", rawSamplerate);
-			tmp += sprintf(tmp, "--raw-endianness=%d ", (rawAudioType.isLittleEndian ? 0 : 1));
-		}
-
-		if (oggparms.nominalBitr != -1)
-			tmp += sprintf(tmp, "--bitrate=%d ", oggparms.nominalBitr);
-		if (oggparms.minBitr != -1)
-			tmp += sprintf(tmp, "--min-bitrate=%d ", oggparms.minBitr);
-		if (oggparms.maxBitr != -1)
-			tmp += sprintf(tmp, "--max-bitrate=%d ", oggparms.maxBitr);
-		if (oggparms.silent)
-			tmp += sprintf(tmp, "--quiet ");
-		tmp += sprintf(tmp, "--quality=%d ", oggparms.quality);
-		tmp += sprintf(tmp, "--output=\"%s\" ", outname);
-		tmp += sprintf(tmp, "\"%s\" ", inname);
-		err = system(fbuf) != 0;
-		break;
-
-	case kMP3Mode:
+	if (compmode == kMP3Mode) {
 		tmp += sprintf(tmp, "lame -t ");
 		if (rawInput) {
 			tmp += sprintf(tmp, "-r ");
 			tmp += sprintf(tmp, "--bitwidth %d ", rawAudioType.bitsPerSample);
-			if (rawAudioType.isLittleEndian)
+
+			if (rawAudioType.isLittleEndian) {
 				tmp += sprintf(tmp, "-x ");
+			}
+
 			tmp += sprintf(tmp, (rawAudioType.isStereo ? "-m j " : "-m m "));
 			tmp += sprintf(tmp, "-s %d ", rawSamplerate);
 		}
 
-		if (encparms.abr)
+		if (encparms.abr) {
 			tmp += sprintf(tmp, "--abr %d ", encparms.minBitr);
-		else
+		} else {
 			tmp += sprintf(tmp, "--vbr-new -b %d ", encparms.minBitr);
+		}
 
 		/* Explicitly specify a target sample rate, to work around a bug (?)
-		 * in newer lame versions (>= 3.95) which causes it to malfunction
-		 * for odd sample rates when in VBR mode. See also bug #934026.
-		 * We essentially duplicate the old behaviour of lame (found in e.g.
-		 * version 3.93.1): we round the input sample rate up to the next
-		 * higher valid MP3 sample rate, with a margin of 3%.
-		 */
-		if (rawSamplerate != -1)
+		* in newer lame versions (>= 3.95) which causes it to malfunction
+		* for odd sample rates when in VBR mode. See also bug #934026.
+		* We essentially duplicate the old behaviour of lame (found in e.g.
+		* version 3.93.1): we round the input sample rate up to the next
+		* higher valid MP3 sample rate, with a margin of 3%.
+		*/
+		if (rawSamplerate != -1) {
 			tmp += sprintf(tmp, "--resample %d ", map2MP3Frequency(97 * rawSamplerate / 100));
+		}
 
-		if (encparms.silent)
+		if (encparms.silent) {
 			tmp += sprintf(tmp, " --silent ");
+		}
+
 		tmp += sprintf(tmp, "-q %d ", encparms.algqual);
 		tmp += sprintf(tmp, "-V %d ", encparms.vbrqual);
 		tmp += sprintf(tmp, "-B %d ", encparms.maxBitr);
 		tmp += sprintf(tmp, "\"%s\" \"%s\" ", inname, outname);
+
 		err = system(fbuf) != 0;
-		break;
 
-	case kFlacMode:
-		/* --lax is needed to allow 11kHz, we dont need place for meta-tags, and no seektable */
-		/* -f is reqired to force override of unremoved temp file. See bug #1294648 */
-		tmp += sprintf(tmp, "flac --best -b 1152 -f --lax --no-padding --no-seektable --no-ogg ");
+		if (err) {
+			printf("Got error from encoder. (check your parameters)\n");
+			printf("Encoder Commandline: %s\n", fbuf );
+			exit(-1);
+		} else {
+			return;
+		}
+	}
 
+#ifdef DISABLE_VORBIS
+		if (compmode == kVorbisMode) {
+			tmp += sprintf(tmp, "oggenc ");
+			if (rawInput) {
+				tmp += sprintf(tmp, "--raw ");
+				tmp += sprintf(tmp, "--raw-chan=%d ", (rawAudioType.isStereo ? 2 : 1));
+				tmp += sprintf(tmp, "--raw-bits=%d ", rawAudioType.bitsPerSample);
+				tmp += sprintf(tmp, "--raw-rate=%d ", rawSamplerate);
+				tmp += sprintf(tmp, "--raw-endianness=%d ", (rawAudioType.isLittleEndian ? 0 : 1));
+			}
+
+			if (oggparms.nominalBitr != -1) {
+				tmp += sprintf(tmp, "--bitrate=%d ", oggparms.nominalBitr);
+			} else {
+				tmp += sprintf(tmp, "--quality=%d ", oggparms.quality);
+			}
+
+			if (oggparms.minBitr != -1) {
+				tmp += sprintf(tmp, "--min-bitrate=%d ", oggparms.minBitr);
+			}
+
+			if (oggparms.maxBitr != -1) {
+				tmp += sprintf(tmp, "--max-bitrate=%d ", oggparms.maxBitr);
+			}
+
+			if (oggparms.silent) {
+				tmp += sprintf(tmp, "--quiet ");
+			}
+
+			tmp += sprintf(tmp, "--output=\"%s\" ", outname);
+			tmp += sprintf(tmp, "\"%s\" ", inname);
+
+			err = system(fbuf) != 0;
+
+			if (err) {
+				printf("Got error from encoder. (check your parameters)\n");
+				printf("Encoder Commandline: %s\n", fbuf );
+				exit(-1);
+			} else {
+				return;
+			}
+		}
+#endif
+
+#ifdef DISABLE_FLAC
+		if (compmode == kFlacMode) {
+			/* --lax is needed to allow 11kHz, we dont need place for meta-tags, and no seektable */
+			/* -f is reqired to force override of unremoved temp file. See bug #1294648 */
+			tmp += sprintf(tmp, "flac -f --lax --no-padding --no-seektable --no-ogg ");
+
+			if (rawInput) {
+				tmp += sprintf(tmp, "--force-raw-format ");
+				tmp += sprintf(tmp, "--sign=%s ", ((rawAudioType.bitsPerSample == 8) ? "unsigned" : "signed"));
+				tmp += sprintf(tmp, "--channels=%d ", (rawAudioType.isStereo ? 2 : 1));
+				tmp += sprintf(tmp, "--bps=%d ", rawAudioType.bitsPerSample);
+				tmp += sprintf(tmp, "--sample-rate=%d ", rawSamplerate);
+				tmp += sprintf(tmp, "--endian=%s ", (rawAudioType.isLittleEndian ? "little" : "big"));
+			}
+
+			if (flacparms.silent) {
+				tmp += sprintf(tmp, "--silent ");
+			}
+
+			if (flacparms.verify) {
+				tmp += sprintf(tmp, "--verify ");
+			}
+
+			tmp += sprintf(tmp, "--compression-level-%d ", flacparms.compressionLevel);
+			tmp += sprintf(tmp, "-b %d ", flacparms.blocksize);
+			tmp += sprintf(tmp, "-o \"%s\" ", outname);
+			tmp += sprintf(tmp, "\"%s\" ", inname);
+
+			err = system(fbuf) != 0;
+
+			if (err) {
+				printf("Got error from encoder. (check your parameters)\n");
+				printf("Encoder Commandline: %s\n", fbuf );
+				exit(-1);
+			} else {
+				return;
+			}
+		}
+#endif
 		if (rawInput) {
-			tmp += sprintf(tmp, "--force-raw-format ");
-			tmp += sprintf(tmp, "--sign=%s ", (rawAudioType.isUnsigned ? "unsigned" : "signed"));
-			tmp += sprintf(tmp, "--channels=%d ", (rawAudioType.isStereo ? 2 : 1));
-			tmp += sprintf(tmp, "--bps=%d ", rawAudioType.bitsPerSample);
-			tmp += sprintf(tmp, "--sample-rate=%d ", rawSamplerate);
-			tmp += sprintf(tmp, "--endian=%s ", (rawAudioType.isLittleEndian ? "little" : "big"));
+			FILE *inputRaw;
+			long length;
+			char *rawData;
+
+			inputRaw = fopen(inname, "rb");
+			length = fileSize(inputRaw);
+			rawData = (char *)malloc(length);
+			fread(rawData, 1, length, inputRaw);
+
+			printf(" - length = %d\n", length);
+			printf(" - channels = %d\n", (rawAudioType.isStereo ? 2 : 1));
+			printf(" - sample rate = %d\n", rawSamplerate);
+			printf(" - compression = %dbits\n", rawAudioType.bitsPerSample);
+
+			encodeRaw(rawData, length, rawSamplerate, outname, compmode);
+
+			fclose(inputRaw);
+			free(rawData);
+		} else {
+			FILE *inputWav;
+			int fmtHeaderSize, length, numChannels, sampleRate, bitsPerSample;
+			char *wavData;
+
+			inputWav = fopen(inname, "rb");
+
+			/* Standard PCM fmt header is 16 bits, but at least Simon 1 and 2 use 18 bits */
+			fseek(inputWav, 16, SEEK_SET);
+			fmtHeaderSize = readUint32LE(inputWav);
+
+			fseek(inputWav, 22, SEEK_SET);
+			numChannels = readUint16LE(inputWav);
+			sampleRate = readUint32LE(inputWav);
+
+			fseek(inputWav, 34, SEEK_SET);
+			bitsPerSample = readUint16LE(inputWav);
+
+			/* The size of the raw audio is after the RIFF chunk (12 bytes), fmt chunk (8 + fmtHeaderSize bytes), and data chunk id (4 bytes) */
+			fseek(inputWav, 24 + fmtHeaderSize, SEEK_SET);
+			length = readUint32LE(inputWav);
+
+			wavData = (char *)malloc(length);
+			fread(wavData, 1, length, inputWav);
+
+			printf(" - length = %d\n", length);
+			printf(" - channels = %d\n", numChannels);
+			printf(" - sample rate = %d\n", sampleRate);
+			printf(" - compression = %dbits\n", bitsPerSample);
+
+			setRawAudioType(true, numChannels == 2, bitsPerSample);
+			encodeRaw(wavData, length, sampleRate, outname, compmode);
+
+			fclose(inputWav);
+			free (wavData);
 		}
+}
 
-		for (i = 0; i < flacparms.numArgs; i++) {
-			/* Append optional encoder arguments */
-			tmp += sprintf(tmp, "%s ", flacparms.argv[i]);
+void encodeRaw(char *rawData, int length, int samplerate, const char *outname, CompressMode compmode) {
+#ifndef DISABLE_VORBIS
+	if (compmode == kVorbisMode) {
+		FILE *outputOgg;
+		char outputString[256] = "";
+		int numChannels = (rawAudioType.isStereo ? 2 : 1);
+		int totalSamples = length / ((rawAudioType.bitsPerSample / 8) * numChannels);
+		int samplesLeft = totalSamples;
+		int eos = 0;
+		int totalBytes = 0;
+
+		vorbis_info vi;
+		vorbis_comment vc;
+		vorbis_dsp_state vd;
+		vorbis_block vb;
+
+		ogg_stream_state os;
+		ogg_page og;
+		ogg_packet op;
+
+		ogg_packet header;
+		ogg_packet header_comm;
+		ogg_packet header_code;
+
+		outputOgg = fopen(outname,"wb");
+
+		vorbis_info_init(&vi);
+
+		if (oggparms.nominalBitr > 0) {
+			int result = 0;
+
+			/* Input is in kbps, function takes bps */
+			result = vorbis_encode_setup_managed(&vi, numChannels, samplerate, (oggparms.maxBitr > 0 ? 1000 * oggparms.maxBitr : -1), (1000 * oggparms.nominalBitr), (oggparms.minBitr > 0 ? 1000 * oggparms.minBitr : -1));
+
+			if (result == OV_EFAULT) {
+				printf("Error: Internal Logic Fault.\n\n");
+				vorbis_info_clear(&vi);
+				exit(-1);
+			} else if ((result == OV_EINVAL) || (result == OV_EIMPL)) {
+				printf("Error: Invalid bitrate parameters.\n\n");
+				vorbis_info_clear(&vi);
+				exit(-1);
+			}
+
+			if (!oggparms.silent) {
+				sprintf(outputString, "Encoding to\n         \"%s\"\nat average bitrate %i kbps (", outname, oggparms.nominalBitr);
+
+				if (oggparms.minBitr > 0) {
+					sprintf(outputString + strlen(outputString), "min %i kbps, ", oggparms.minBitr);
+				} else {
+					sprintf(outputString + strlen(outputString), "no min, ");
+				}
+
+				if (oggparms.maxBitr > 0) {
+					sprintf(outputString + strlen(outputString), "max %i kbps),\nusing full bitrate management engine\nSet optional hard quality restrictions\n", oggparms.maxBitr);
+				} else {
+					sprintf(outputString + strlen(outputString), "no max),\nusing full bitrate management engine\nSet optional hard quality restrictions\n");
+				}
+			}
+		} else {
+			int result = 0;
+
+			/* Quality input is 1 - 10, function takes -0.1 through 1.0 */
+			result = vorbis_encode_setup_vbr(&vi, numChannels, samplerate, oggparms.quality * 0.1);
+
+			if (result == OV_EFAULT) {
+				printf("Error: Internal Logic Fault.\n\n");
+				vorbis_info_clear(&vi);
+				exit(-1);
+			} else if ((result == OV_EINVAL) || (result == OV_EIMPL)) {
+				printf("Error: Invalid bitrate parameters.\n\n");
+				vorbis_info_clear(&vi);
+				exit(-1);
+			}
+
+			if (!oggparms.silent) {
+				sprintf(outputString, "Encoding to\n         \"%s\"\nat quality %2.2f", outname, oggparms.quality);
+			}
+
+			if ((oggparms.minBitr > 0) || (oggparms.maxBitr > 0)) {
+				struct ovectl_ratemanage_arg extraParam;
+				vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_GET, &extraParam);
+
+				extraParam.bitrate_hard_min = (oggparms.minBitr > 0 ? (1000 * oggparms.minBitr) : -1);
+				extraParam.bitrate_hard_max = (oggparms.maxBitr > 0 ? (1000 * oggparms.maxBitr) : -1);
+				extraParam.management_active = 1;
+
+				vorbis_encode_ctl(&vi, OV_ECTL_RATEMANAGE_SET, &extraParam);
+
+				if (!oggparms.silent) {
+					sprintf(outputString + strlen(outputString), " using constrained VBR (");
+
+					if (oggparms.minBitr != -1) {
+						sprintf(outputString + strlen(outputString), "min %i kbps, ", oggparms.minBitr);
+					} else {
+						sprintf(outputString + strlen(outputString), "no min, ");
+					}
+
+					if (oggparms.maxBitr != -1) {
+						sprintf(outputString + strlen(outputString), "max %i kbps)\nSet optional hard quality restrictions\n", oggparms.maxBitr);
+					} else {
+						sprintf(outputString + strlen(outputString), "no max)\nSet optional hard quality restrictions\n");
+					}
+				}
+			} else {
+				sprintf(outputString + strlen(outputString), "\n");
+			}
 		}
 
-		tmp += sprintf(tmp, "-o \"%s\" ", outname);
-		tmp += sprintf(tmp, "\"%s\" ", inname);
+		printf(outputString);
 
-		err = system(fbuf) != 0;
-		break;
+		vorbis_encode_setup_init(&vi);
+		vorbis_comment_init(&vc);
+		vorbis_analysis_init(&vd, &vi);
+		vorbis_block_init(&vd, &vb);
+		ogg_stream_init(&os, 0);
+		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);
+
+		while (!eos) {
+			int result = ogg_stream_flush(&os,&og);
+
+			if (result == 0) {
+				break;
+			}
+
+			fwrite(og.header, 1, og.header_len, outputOgg);
+			fwrite(og.body, 1, og.body_len, outputOgg);
+		}
+
+		while (!eos) {
+			int i, j;
+			int numSamples = ((samplesLeft < 2048) ? samplesLeft : 2048);
+			float **buffer = vorbis_analysis_buffer(&vd, numSamples);
+
+			/* We must tell the encoder that we have reached the end of the stream */
+			if (numSamples == 0) {
+				vorbis_analysis_wrote(&vd, 0);
+			} else {
+				/* Adapted from oggenc 1.1.1 */
+				if (rawAudioType.bitsPerSample == 8) {
+					unsigned char *rawDataUnsigned = (unsigned char *)rawData;
+					for (i = 0; i < numSamples; i++) {
+						for (j = 0; j < numChannels; j++) {
+							buffer[j][i] = ((int)(rawDataUnsigned[i * numChannels + j]) - 128) / 128.0f;
+						}
+					}
+				} else if(rawAudioType.bitsPerSample == 16) {
+					if(rawAudioType.isLittleEndian) {
+						for(i = 0; i < numSamples; i++) {
+							for(j = 0; j < numChannels; j++) {
+								buffer[j][i] = ((rawData[(i * 2 * numChannels) + (2 * j) + 1] << 8) | (rawData[(i * 2 * numChannels) + (2 * j)] & 0xff)) / 32768.0f;
+							}
+						}
+					}
+					else {
+						for(i = 0; i < numSamples; i++) {
+							for(j = 0; j < numChannels; j++) {
+								buffer[j][i] = ((rawData[(i * 2 * numChannels) + (2 * j)] << 8) | (rawData[(i * 2 * numChannels) + (2 * j) + 1] & 0xff)) / 32768.0f;
+							}
+						}
+					}
+				}
+
+				vorbis_analysis_wrote(&vd, numSamples);
+			}
+
+			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;
+						}
+
+						totalBytes += fwrite(og.header, 1, og.header_len, outputOgg);
+						totalBytes += fwrite(og.body, 1, og.body_len, outputOgg);
+
+						if(ogg_page_eos(&og)) {
+							eos = 1;
+						}
+					}
+				}
+			}
+
+			rawData += 2048 * (rawAudioType.bitsPerSample / 8) * numChannels;
+			samplesLeft -= 2048;
+		}
+
+		ogg_stream_clear(&os);
+		vorbis_block_clear(&vb);
+		vorbis_dsp_clear(&vd);
+		vorbis_info_clear(&vi);
+
+		fclose(outputOgg);
+
+		if (!oggparms.silent) {
+			printf("\nDone encoding file \"%s\"\n", outname);
+			printf("\n\tFile length:  %dm %ds\n", (int)(totalSamples / samplerate / 60), (totalSamples / samplerate % 60));
+			printf("\tAverage bitrate: %.1f kb/s\n\n", (8.0 * (double)totalBytes / 1000.0) / ((double)totalSamples / (double)samplerate));
+		}
 	}
+#endif
 
-	if (err) {
-		printf("Got error from encoder. (check your parameters)\n");
-		printf("Encoder Commandline: %s\n", fbuf );
-		exit(-1);
+#ifndef DISABLE_FLAC
+	if (compmode == kFlacMode) {
+		int i;
+		int numChannels = (rawAudioType.isStereo ? 2 : 1);
+		int samplesPerChannel = length / ((rawAudioType.bitsPerSample / 8) * numChannels);
+		FLAC__StreamEncoder *encoder;
+		FLAC__StreamEncoderInitStatus initStatus;
+		FLAC__int32 *flacData;
+
+		flacData = (FLAC__int32 *)malloc(samplesPerChannel * numChannels * sizeof(FLAC__int32));
+
+		if (rawAudioType.bitsPerSample == 8) {
+			for (i = 0; i < samplesPerChannel * numChannels; i++) {
+				FLAC__uint8 *rawDataUnsigned;
+				rawDataUnsigned = (FLAC__uint8 *)rawData;
+				flacData[i] = (FLAC__int32)rawDataUnsigned[i] - 0x80;
+			}
+		} else if (rawAudioType.bitsPerSample == 16) {
+			/* The rawData pointer is an 8-bit char so we must create a new pointer to access 16-bit samples */
+			FLAC__int16 *rawData16;
+			rawData16 = (FLAC__int16 *)rawData;
+			for (i = 0; i < samplesPerChannel * numChannels; i++) {
+				flacData[i] = (FLAC__int32)rawData16[i];
+			}
+		}
+
+		if (!flacparms.silent) {
+			printf("Encoding to\n         \"%s\"\nat compression level %d using blocksize %d\n\n", outname, flacparms.compressionLevel, flacparms.blocksize);
+		}
+
+		encoder = FLAC__stream_encoder_new();
+
+		FLAC__stream_encoder_set_bits_per_sample(encoder, rawAudioType.bitsPerSample);
+		FLAC__stream_encoder_set_blocksize(encoder, flacparms.blocksize);
+		FLAC__stream_encoder_set_channels(encoder, numChannels);
+		FLAC__stream_encoder_set_compression_level(encoder, flacparms.compressionLevel);
+		FLAC__stream_encoder_set_sample_rate(encoder, samplerate);
+		FLAC__stream_encoder_set_streamable_subset(encoder, false);
+		FLAC__stream_encoder_set_total_samples_estimate(encoder, samplesPerChannel);
+		FLAC__stream_encoder_set_verify(encoder, flacparms.verify);
+
+		initStatus = FLAC__stream_encoder_init_file(encoder, outname, NULL, NULL);
+
+		if (initStatus != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
+			printf("Got error from encoder. (check your paramters)\n");
+			printf("FLAC error: %s\n\n", FLAC__StreamEncoderInitStatusString[initStatus]);
+			exit(-1);
+		} else {
+			FLAC__stream_encoder_process_interleaved(encoder, flacData, samplesPerChannel);
+		}
+
+		FLAC__stream_encoder_finish(encoder);
+		FLAC__stream_encoder_delete(encoder);
+
+		free(flacData);
+
+		if (!flacparms.silent) {
+			printf("\nDone encoding file \"%s\"\n", outname);
+			printf("\n\tFile length:  %dm %ds\n\n", (int)(samplesPerChannel / samplerate / 60), (samplesPerChannel / samplerate % 60));
+		}
 	}
+#endif
 }
 
 void extractAndEncodeWAV(const char *outName, FILE *input, CompressMode compMode) {
@@ -261,6 +630,7 @@
 		length = fgetc(input);
 		length |= fgetc(input) << 8;
 		length |= fgetc(input) << 16;
+
 		if (blocktype == 1) {
 			length -= 2;
 			sample_rate = fgetc(input);
@@ -287,14 +657,18 @@
 				  (comp == 3 ? "2bits"   :
 								"Multi")))), comp);
 
-		if (comp != 0)
+		if (comp != 0) {
 			error("Cannot handle compressed VOC data");
+		}
 
 		/* Copy the raw data to a temporary file */
 		while (length > 0) {
 			size = fread(fbuf, 1, length > sizeof(fbuf) ? sizeof(fbuf) : (uint32)length, input);
-			if (size <= 0)
+
+			if (size <= 0) {
 				break;
+			}
+
 			length -= (int)size;
 			fwrite(fbuf, 1, size, f);
 		}
@@ -304,7 +678,7 @@
 
 	assert(real_samplerate != -1);
 
-	setRawAudioType(false, false, true, 8);
+	setRawAudioType(false, false, 8);
 
 	/* Convert the raw temp file to OGG/MP3 */
 	encodeAudio(outName, true, real_samplerate, tempEncoded, compMode);
@@ -318,35 +692,59 @@
 			encparms.abr=1;
 		} else if (strcmp(argv[i], "-b") == 0) {
 			encparms.minBitr = atoi(argv[i + 1]);
-			if ((encparms.minBitr % 8) != 0)
+
+			if ((encparms.minBitr % 8) != 0) {
 				encparms.minBitr -= encparms.minBitr % 8;
-			if (encparms.minBitr >160)
+			}
+
+			if (encparms.minBitr >160) {
 				encparms.minBitr = 160;
-			if (encparms.minBitr < 8)
-				encparms.minBitr=8;
+			}
+
+			if (encparms.minBitr < 8) {
+				encparms.minBitr = 8;
+			}
+
 			i++;
 		} else if (strcmp(argv[i], "-B") == 0) {
 			encparms.maxBitr = atoi(argv[i + 1]);
-			if ((encparms.maxBitr % 8) != 0)
+
+			if ((encparms.maxBitr % 8) != 0) {
 				encparms.maxBitr -= encparms.maxBitr % 8;
-			if (encparms.maxBitr > 160)
+			}
+
+			if (encparms.maxBitr > 160) {
 				encparms.maxBitr = 160;
-			if (encparms.maxBitr < 8)
+			}
+
+			if (encparms.maxBitr < 8) {
 				encparms.maxBitr = 8;
+			}
+
 			i++;
 		} else if (strcmp(argv[i], "-V") == 0) {
 			encparms.vbrqual = atoi(argv[i + 1]);
-			if(encparms.vbrqual < 0)
+
+			if(encparms.vbrqual < 0) {
 				encparms.vbrqual = 0;
-			if(encparms.vbrqual > 9)
+			}
+
+			if(encparms.vbrqual > 9) {
 				encparms.vbrqual = 9;
+			}
+
 			i++;
 		} else if (strcmp(argv[i], "-q") == 0) {
 			encparms.algqual = atoi(argv[i + 1]);
-			if (encparms.algqual < 0)
+
+			if (encparms.algqual < 0) {
 				encparms.algqual = 0;
-			if (encparms.algqual > 9)
+			}
+
+			if (encparms.algqual > 9) {
 				encparms.algqual = 9;
+			}
+
 			i++;
 		} else if (strcmp(argv[i], "--silent") == 0) {
 			encparms.silent = 1;
@@ -358,9 +756,11 @@
 			break;
 		}
 	}
+
 	if (i != (argc - 1)) {
 		return 0;
 	}
+
 	return 1;
 }
 
@@ -368,14 +768,52 @@
 	for (; i < argc; i++) {
 		if (strcmp(argv[i], "-b") == 0) {
 			oggparms.nominalBitr = atoi(argv[i + 1]);
+
+			if ((oggparms.nominalBitr % 8) != 0) {
+				oggparms.nominalBitr -= oggparms.nominalBitr % 8;
+			}
+
+			if (oggparms.nominalBitr >160) {
+				oggparms.nominalBitr = 160;
+			}
+
+			if (oggparms.nominalBitr < 8) {
+				oggparms.nominalBitr = 8;
+			}
+
 			i++;
-		}
-		else if (strcmp(argv[i], "-m") == 0) {
+		} else if (strcmp(argv[i], "-m") == 0) {
 			oggparms.minBitr = atoi(argv[i + 1]);
+
+			if ((oggparms.minBitr % 8) != 0) {
+				oggparms.minBitr -= oggparms.minBitr % 8;
+			}
+
+			if (oggparms.minBitr >160) {
+				oggparms.minBitr = 160;
+			}
+
+			if (oggparms.minBitr < 8) {
+				oggparms.minBitr = 8;
+			}
+
 			i++;
 		}
 		else if (strcmp(argv[i], "-M") == 0) {
 			oggparms.maxBitr = atoi(argv[i + 1]);
+
+			if ((oggparms.maxBitr % 8) != 0) {
+				oggparms.maxBitr -= encparms.minBitr % 8;
+			}
+
+			if (oggparms.maxBitr >160) {
+				oggparms.maxBitr = 160;
+			}
+
+			if (oggparms.maxBitr < 8) {
+				oggparms.maxBitr = 8;
+			}
+
 			i++;
 		}
 		else if (strcmp(argv[i], "-q") == 0) {
@@ -391,19 +829,77 @@
 		else if (argv[i][0] == '-') {
 			return 0;
 		}
-		else
+		else {
 			break;
+		}
 	}
-	if (i != argc - 1)
+
+	if (i != argc - 1) {
 		return 0;
+	}
+
 	return 1;
 }
 
 int process_flac_parms(int argc, char *argv[], int i){
-	flacparms.argv = &argv[i];
-	flacparms.numArgs = argc - 1 - i;
+	for (; i < argc; i++) {
+		if (strcmp(argv[i], "-b") == 0) {
+			flacparms.blocksize = atoi(argv[i + 1]);
+			i++;
+		}
+		else if (strcmp(argv[i], "--fast") == 0) {
+			flacparms.compressionLevel = 0;
+		}
+		else if (strcmp(argv[i], "--best") == 0) {
+			flacparms.compressionLevel = 8;
+		}
+		else if (strcmp(argv[i], "-0") == 0) {
+			flacparms.compressionLevel = 0;
+		}
+		else if (strcmp(argv[i], "-1") == 0) {
+			flacparms.compressionLevel = 1;
+		}
+		else if (strcmp(argv[i], "-2") == 0) {
+			flacparms.compressionLevel = 2;
+		}
+		else if (strcmp(argv[i], "-3") == 0) {
+			flacparms.compressionLevel = 3;
+		}
+		else if (strcmp(argv[i], "-4") == 0) {
+			flacparms.compressionLevel = 4;
+		}
+		else if (strcmp(argv[i], "-5") == 0) {
+			flacparms.compressionLevel = 5;
+		}
+		else if (strcmp(argv[i], "-6") == 0) {
+			flacparms.compressionLevel = 6;
+		}
+		else if (strcmp(argv[i], "-7") == 0) {
+			flacparms.compressionLevel = 7;
+		}
+		else if (strcmp(argv[i], "-8") == 0) {
+			flacparms.compressionLevel = 8;
+		}
+		else if (strcmp(argv[i], "--verify") == 0) {
+			flacparms.verify = true;
+		}
+		else if (strcmp(argv[i], "--silent") == 0) {
+			flacparms.silent = true;
+		}
+		else if (strcmp(argv[i], "--help") == 0) {
+			return 0;
+		}
+		else if (argv[i][0] == '-') {
+			return 0;
+		}
+		else {
+			break;
+		}
+	}
 
-	if (i >= argc)
+	if (i != argc - 1) {
 		return 0;
+	}
+
 	return 1;
 }

Modified: tools/branches/gsoc2007-toolsgui/compress.h
===================================================================
--- tools/branches/gsoc2007-toolsgui/compress.h	2007-07-04 21:38:30 UTC (rev 27906)
+++ tools/branches/gsoc2007-toolsgui/compress.h	2007-07-04 23:00:38 UTC (rev 27907)
@@ -24,6 +24,8 @@
 #define EXTRACT_H
 
 #include "util.h"
+#include <vorbis/vorbisenc.h>
+#include <FLAC/stream_encoder.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -38,6 +40,10 @@
 /* The default for oggenc invocation is to use the --quality option only */
 #define oggqualDef 3
 
+/* These are the default parameters for the FLAC invocation */
+#define flacCompressDef 8
+#define flacBlocksizeDef 1152
+
 #define TEMP_WAV	"tempfile.wav"
 #define TEMP_RAW	"tempfile.raw"
 #define TEMP_MP3	"tempfile.mp3"
@@ -60,7 +66,8 @@
 extern void extractAndEncodeWAV(const char *outName, FILE *input, CompressMode compMode);
 
 extern void encodeAudio(const char *inname, bool rawInput, int rawSamplerate, const char *outname, CompressMode compmode);
-extern void setRawAudioType(bool isLittleEndian, bool isStereo, bool isUnSigned, uint8 bitsPerSample);
+extern void encodeRaw(char *rawData, int length, int samplerate, const char *outname, CompressMode compmode);
+extern void setRawAudioType(bool isLittleEndian, bool isStereo, uint8 bitsPerSample);
 
 #if defined(__cplusplus)
 }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list