[PATCH 04/10] alsabat: clean the thread loopback of alsa capture

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Lu, Han" <han.lu@xxxxxxxxx>

1. Move file operations to sub loopback, so the structure is more
clear, for alsa and tinyalsa to share common functions.
2. Update wav header information after capture.
3. Remove redundant code and update comment.

Signed-off-by: Lu, Han <han.lu@xxxxxxxxx>

diff --git a/bat/alsa.c b/bat/alsa.c
index 5775748..47441e7 100644
--- a/bat/alsa.c
+++ b/bat/alsa.c
@@ -464,12 +464,27 @@ static int read_from_pcm(struct pcm_container *sndpcm,
 	return 0;
 }
 
-static int read_from_pcm_loop(FILE *fp, int count,
-		struct pcm_container *sndpcm, struct bat *bat)
+static int read_from_pcm_loop(struct pcm_container *sndpcm, struct bat *bat)
 {
 	int err = 0;
+	FILE *fp = NULL;
 	int size, frames;
-	int remain = count;
+	int bytes_read = 0;
+	int bytes_count = bat->frames * bat->frame_size;
+	int remain = bytes_count;
+
+	remove(bat->capture.file);
+	fp = fopen(bat->capture.file, "wb");
+	if (fp == NULL) {
+		fprintf(bat->err, _("Cannot open file for capture: %s %d\n"),
+				bat->capture.file, -errno);
+		return -errno;
+	}
+	/* leave space for file header */
+	if (fseek(fp, sizeof(struct wav_container), SEEK_SET) != 0) {
+		fclose(fp);
+		return -errno;
+	}
 
 	while (remain > 0) {
 		size = (remain <= sndpcm->period_bytes) ?
@@ -479,15 +494,14 @@ static int read_from_pcm_loop(FILE *fp, int count,
 		/* read a chunk from pcm device */
 		err = read_from_pcm(sndpcm, frames, bat);
 		if (err != 0)
-			return err;
+			break;
 
 		/* write the chunk to file */
 		err = fwrite(sndpcm->buffer, 1, size, fp);
-		if (err != size) {
-			fprintf(bat->err, _("Write file error: %s(%d)\n"),
-					snd_strerror(err), err);
-			return -EIO;
-		}
+		if (err != size)
+			break;
+
+		bytes_read += size;
 		remain -= size;
 		bat->periods_played++;
 
@@ -496,7 +510,10 @@ static int read_from_pcm_loop(FILE *fp, int count,
 			break;
 	}
 
-	return 0;
+	err = update_wav_header(bat, fp, bytes_read);
+
+	fclose(fp);
+	return err;
 }
 
 static void pcm_cleanup(void *p)
@@ -504,21 +521,13 @@ static void pcm_cleanup(void *p)
 	snd_pcm_close(p);
 }
 
-static void file_cleanup(void *p)
-{
-	fclose(p);
-}
-
 /**
  * Record
  */
 void *record_alsa(struct bat *bat)
 {
 	int err = 0;
-	FILE *fp = NULL;
 	struct pcm_container sndpcm;
-	struct wav_container wav;
-	int count;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 
@@ -542,47 +551,26 @@ void *record_alsa(struct bat *bat)
 		goto exit2;
 	}
 
-	remove(bat->capture.file);
-	fp = fopen(bat->capture.file, "w+");
-	if (fp == NULL) {
-		fprintf(bat->err, _("Cannot open file for capture: %s %d\n"),
-				bat->capture.file, -errno);
-		retval_record = 1;
-		goto exit3;
-	}
-
-	prepare_wav_info(&wav, bat);
-
 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 	pthread_cleanup_push(pcm_cleanup, sndpcm.handle);
 	pthread_cleanup_push(free, sndpcm.buffer);
-	pthread_cleanup_push(file_cleanup, fp);
-
-	err = write_wav_header(fp, &wav, bat);
-	if (err != 0) {
-		retval_record = 1;
-		goto exit4;
-	}
 
-	count = wav.chunk.length;
 	fprintf(bat->log, _("Recording ...\n"));
-	err = read_from_pcm_loop(fp, count, &sndpcm, bat);
+	err = read_from_pcm_loop(&sndpcm, bat);
 	if (err != 0) {
-		retval_record = 1;
-		goto exit4;
+		retval_record = err;
+		goto exit3;
 	}
 
-	/* Normally we will never reach this part of code (before fail_exit) as
-	   this thread will be cancelled by end of play thread. */
+	/* Normally we will never reach this part of code (unless error in
+	 * previous call) (before exit3) as this thread will be cancelled
+	 *  by end of play thread. Except in single line mode. */
 	pthread_cleanup_pop(0);
 	pthread_cleanup_pop(0);
-	pthread_cleanup_pop(0);
-
 	snd_pcm_drain(sndpcm.handle);
+	pthread_exit(&retval_record);
 
-exit4:
-	fclose(fp);
 exit3:
 	free(sndpcm.buffer);
 exit2:
-- 
2.5.0

_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux