[asterisk-commits] trunk r19673 - /trunk/formats/format_wav_gsm.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Apr 12 18:29:55 MST 2006


Author: tilghman
Date: Wed Apr 12 20:29:54 2006
New Revision: 19673

URL: http://svn.digium.com/view/asterisk?rev=19673&view=rev
Log:
Document the MSGSM format, and fix the uncalculated number of samples

Modified:
    trunk/formats/format_wav_gsm.c

Modified: trunk/formats/format_wav_gsm.c
URL: http://svn.digium.com/view/asterisk/trunk/formats/format_wav_gsm.c?rev=19673&r1=19672&r2=19673&view=diff
==============================================================================
--- trunk/formats/format_wav_gsm.c (original)
+++ trunk/formats/format_wav_gsm.c Wed Apr 12 20:29:54 2006
@@ -56,7 +56,7 @@
 
 #define	GSM_FRAME_SIZE	33
 #define	MSGSM_FRAME_SIZE	65
-#define	MSGSM_DATA_OFS		60	/* offset of data bytes */
+#define	MSGSM_DATA_OFFSET		60	/* offset of data bytes */
 #define	GSM_SAMPLES		160	/* samples in a GSM block */
 #define	MSGSM_SAMPLES		(2*GSM_SAMPLES)	/* samples in an MSGSM block */
 
@@ -219,15 +219,16 @@
 static int update_header(FILE *f)
 {
 	off_t cur,end,bytes;
-	int datalen,filelen;
-	
+	int datalen, filelen, samples;
+
 	cur = ftello(f);
 	fseek(f, 0, SEEK_END);
 	end = ftello(f);
 	/* in a gsm WAV, data starts 60 bytes in */
-	bytes = end - MSGSM_DATA_OFS;
+	bytes = end - MSGSM_DATA_OFFSET;
+	samples = bytes / GSM_FRAME_SIZE * MSGSM_SAMPLES;
 	datalen = htoll((bytes + 1) & ~0x1);
-	filelen = htoll(52 + ((bytes + 1) & ~0x1));
+	filelen = htoll(MSGSM_DATA_OFFSET - 8 + ((bytes + 1) & ~0x1));
 	if (cur < 0) {
 		ast_log(LOG_WARNING, "Unable to find our position\n");
 		return -1;
@@ -237,7 +238,15 @@
 		return -1;
 	}
 	if (fwrite(&filelen, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to set write file size\n");
+		ast_log(LOG_WARNING, "Unable to write file size\n");
+		return -1;
+	}
+	if (fseek(f, 48, SEEK_SET)) {
+		ast_log(LOG_WARNING, "Unable to set our position\n");
+		return -1;
+	}
+	if (fwrite(&samples, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write samples\n");
 		return -1;
 	}
 	if (fseek(f, 56, SEEK_SET)) {
@@ -245,7 +254,7 @@
 		return -1;
 	}
 	if (fwrite(&datalen, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to set write datalen\n");
+		ast_log(LOG_WARNING, "Unable to write datalen\n");
 		return -1;
 	}
 	if (fseeko(f, cur, SEEK_SET)) {
@@ -257,78 +266,111 @@
 
 static int write_header(FILE *f)
 {
-	unsigned int hz=htoll(DEFAULT_SAMPLE_RATE);	/* XXX the following are relate to DEFAULT_SAMPLE_RATE ? */
-	unsigned int bhz = htoll(1625);
-	unsigned int hs = htoll(20);
+	/* Samples per second (always 8000 for this format). */
+	unsigned int sample_rate = htoll(8000);
+	/* Bytes per second (always 1625 for this format). */
+	unsigned int byte_sample_rate = htoll(1625);
+	/* This is the size of the "fmt " subchunk */
+	unsigned int fmtsize = htoll(20);
+	/* WAV #49 */
 	unsigned short fmt = htols(49);
+	/* Mono = 1 channel */
 	unsigned short chans = htols(1);
-	unsigned int fhs = htoll(4);
-	unsigned int x_1 = htoll(65);
-	unsigned short x_2 = htols(2);
-	unsigned short x_3 = htols(320);
-	unsigned int y_1 = htoll(20160);
+	/* Each block of data is exactly 65 bytes in size. */
+	unsigned short block_align = htols(MSGSM_FRAME_SIZE);
+	/* Not actually 2, but rounded up to the nearest bit */
+	unsigned short bits_per_sample = htols(2);
+	/* Needed for compressed formats */
+	unsigned short extra_format = htols(MSGSM_SAMPLES);
+	/* This is the size of the "fact" subchunk */
+	unsigned int factsize = htoll(4);
+	/* Number of samples in the data chunk */
+	unsigned int num_samples = htoll(0);
+	/* Number of bytes in the data chunk */
 	unsigned int size = htoll(0);
 	/* Write a GSM header, ignoring sizes which will be filled in later */
+
+	/*  0: Chunk ID */
 	if (fwrite("RIFF", 1, 4, f) != 4) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
+	/*  4: Chunk Size */
 	if (fwrite(&size, 1, 4, f) != 4) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
-	if (fwrite("WAVEfmt ", 1, 8, f) != 8) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&hs, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
+	/*  8: Chunk Format */
+	if (fwrite("WAVE", 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 12: Subchunk 1: ID */
+	if (fwrite("fmt ", 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 16: Subchunk 1: Size (minus 8) */
+	if (fwrite(&fmtsize, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 20: Subchunk 1: Audio format (49) */
 	if (fwrite(&fmt, 1, 2, f) != 2) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
+	/* 22: Subchunk 1: Number of channels */
 	if (fwrite(&chans, 1, 2, f) != 2) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
-	if (fwrite(&hz, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&bhz, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&x_1, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&x_2, 1, 2, f) != 2) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&x_3, 1, 2, f) != 2) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
+	/* 24: Subchunk 1: Sample rate */
+	if (fwrite(&sample_rate, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 28: Subchunk 1: Byte rate */
+	if (fwrite(&byte_sample_rate, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 32: Subchunk 1: Block align */
+	if (fwrite(&block_align, 1, 2, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 36: Subchunk 1: Bits per sample */
+	if (fwrite(&bits_per_sample, 1, 2, f) != 2) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 38: Subchunk 1: Extra format bytes */
+	if (fwrite(&extra_format, 1, 2, f) != 2) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 40: Subchunk 2: ID */
 	if (fwrite("fact", 1, 4, f) != 4) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
-	if (fwrite(&fhs, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
-	if (fwrite(&y_1, 1, 4, f) != 4) {
-		ast_log(LOG_WARNING, "Unable to write header\n");
-		return -1;
-	}
+	/* 44: Subchunk 2: Size (minus 8) */
+	if (fwrite(&factsize, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 48: Subchunk 2: Number of samples */
+	if (fwrite(&num_samples, 1, 4, f) != 4) {
+		ast_log(LOG_WARNING, "Unable to write header\n");
+		return -1;
+	}
+	/* 52: Subchunk 3: ID */
 	if (fwrite("data", 1, 4, f) != 4) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
 	}
+	/* 56: Subchunk 3: Size */
 	if (fwrite(&size, 1, 4, f) != 4) {
 		ast_log(LOG_WARNING, "Unable to write header\n");
 		return -1;
@@ -454,7 +496,7 @@
 	off_t offset=0, distance, max;
 	struct wavg_desc *s = (struct wavg_desc *)fs->private;
 
-	off_t min = MSGSM_DATA_OFS;
+	off_t min = MSGSM_DATA_OFFSET;
 	off_t cur = ftello(fs->f);
 	fseek(fs->f, 0, SEEK_END);
 	max = ftello(fs->f);	/* XXX ideally, should round correctly */
@@ -496,8 +538,7 @@
 	offset = ftello(fs->f);
 	/* since this will most likely be used later in play or record, lets stick
 	 * to that level of resolution, just even frames boundaries */
-	/* XXX why 52 ? */
-	return (offset - 52)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
+	return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
 }
 
 static struct ast_format_lock me = { .usecnt = -1 };



More information about the asterisk-commits mailing list