All of lore.kernel.org
 help / color / mirror / Atom feed
From: han.lu@intel.com
To: tiwai@suse.de, liam.r.girdwood@linux.intel.com,
	alsa-devel@alsa-project.org
Cc: "Lu, Han" <han.lu@intel.com>
Subject: [PATCH 1/6] alsabat: clean file process on capture thread loop
Date: Tue, 22 Mar 2016 13:10:24 +0800	[thread overview]
Message-ID: <86ef8b623292e93bd8512d7ff882e2d184980ce3.1458623090.git.han.lu@intel.com> (raw)
In-Reply-To: <cover.1458623090.git.han.lu@intel.com>
In-Reply-To: <cover.1458623090.git.han.lu@intel.com>

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

Move file operations to sub function, and add common function to
handle wav file header updating.

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

diff --git a/bat/alsa.c b/bat/alsa.c
index 79c86fe..666bcf2 100644
--- a/bat/alsa.c
+++ b/bat/alsa.c
@@ -465,12 +465,29 @@ 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");
+	err = -errno;
+	if (fp == NULL) {
+		fprintf(bat->err, _("Cannot open file: %s %d\n"),
+				bat->capture.file, err);
+		return err;
+	}
+	/* leave space for file header */
+	if (fseek(fp, sizeof(struct wav_container), SEEK_SET) != 0) {
+		err = -errno;
+		fclose(fp);
+		return err;
+	}
 
 	while (remain > 0) {
 		size = (remain <= sndpcm->period_bytes) ?
@@ -489,6 +506,8 @@ static int read_from_pcm_loop(FILE *fp, int count,
 					snd_strerror(err), err);
 			return -EIO;
 		}
+
+		bytes_read += size;
 		remain -= size;
 		bat->periods_played++;
 
@@ -497,6 +516,9 @@ static int read_from_pcm_loop(FILE *fp, int count,
 			break;
 	}
 
+	update_wav_header(bat, fp, bytes_read);
+
+	fclose(fp);
 	return 0;
 }
 
@@ -505,21 +527,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);
 
@@ -543,48 +557,27 @@ void *record_alsa(struct bat *bat)
 		goto exit2;
 	}
 
-	remove(bat->capture.file);
-	fp = fopen(bat->capture.file, "wb");
-	err = -errno;
-	if (fp == NULL) {
-		fprintf(bat->err, _("Cannot open file: %s %d\n"),
-				bat->capture.file, err);
-		retval_record = err;
-		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 = err;
-		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 = err;
-		goto exit4;
+		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. */
-	pthread_cleanup_pop(0);
+	/* 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);
 
 	snd_pcm_drain(sndpcm.handle);
+	pthread_exit(&retval_record);
 
-exit4:
-	fclose(fp);
 exit3:
 	free(sndpcm.buffer);
 exit2:
diff --git a/bat/common.c b/bat/common.c
index 41aaf3a..e51bafd 100644
--- a/bat/common.c
+++ b/bat/common.c
@@ -195,3 +195,19 @@ int write_wav_header(FILE *fp, struct wav_container *wav, struct bat *bat)
 
 	return 0;
 }
+
+/* update wav header when data size changed */
+int update_wav_header(struct bat *bat, FILE *fp, int bytes)
+{
+	int err = 0;
+	struct wav_container wav;
+
+	prepare_wav_info(&wav, bat);
+	wav.chunk.length = bytes;
+	wav.header.length = (wav.chunk.length) + sizeof(wav.chunk)
+		+ sizeof(wav.format) + sizeof(wav.header) - 8;
+	rewind(fp);
+	err = write_wav_header(fp, &wav, bat);
+
+	return err;
+}
diff --git a/bat/common.h b/bat/common.h
index 30e39fc..d72a940 100644
--- a/bat/common.h
+++ b/bat/common.h
@@ -183,3 +183,4 @@ struct analyze {
 void prepare_wav_info(struct wav_container *, struct bat *);
 int read_wav_header(struct bat *, char *, FILE *, bool);
 int write_wav_header(FILE *, struct wav_container *, struct bat *);
+int update_wav_header(struct bat *, FILE *, int);
-- 
2.5.0

  reply	other threads:[~2016-03-22  5:09 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-22  5:10 [PATCH 0/6] *** alsabat: clean structure and tinyalsa support *** han.lu
2016-03-22  5:10 ` han.lu [this message]
2016-03-22  5:10 ` [PATCH 2/6] alsabat: use common wav process function in playback loop han.lu
2016-03-22  5:10 ` [PATCH 3/6] alsabat: clean return value of playback and capture loops han.lu
2016-03-22  5:10 ` [PATCH 4/6] alsabat: use common data generator function han.lu
2016-03-22  5:10 ` [PATCH 5/6] alsabat: move alsa process to alsa.c han.lu
2016-03-22  5:10 ` [PATCH 6/6] alsabat: add tinyalsa support han.lu
2016-03-22  7:30 ` [PATCH 0/6] *** alsabat: clean structure and tinyalsa support *** Takashi Iwai
2016-03-22 14:31   ` Lu, Han
2016-03-22 14:41     ` Takashi Iwai
2016-03-22 15:17       ` Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86ef8b623292e93bd8512d7ff882e2d184980ce3.1458623090.git.han.lu@intel.com \
    --to=han.lu@intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=liam.r.girdwood@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.