All of lore.kernel.org
 help / color / mirror / Atom feed
* A better pcm_file "infile" patch, and a declaration of being miffed.
@ 2006-05-18 16:29 Juan Carlos Castro y Castro
  2006-05-19 10:40 ` Takashi Iwai
  0 siblings, 1 reply; 3+ messages in thread
From: Juan Carlos Castro y Castro @ 2006-05-18 16:29 UTC (permalink / raw)
  To: alsa-devel; +Cc: Takashi Iwai

[-- Attachment #1: Type: text/plain, Size: 833 bytes --]

OK, this implements the "infile" parameter of pcm_file in a much cleaner 
way. Note that the the below new members of snd_pcm_file_t are not used 
now, but WILL be when I implement protection from fraction-of-frame reads:

       size_t rbuf_size_bytes;
       size_t rbuf_used_bytes;
       char *rbuf;

Now, the whole reason of this shebang was so I can use the "infile" AND 
convert rates in the process -- i.e., the app programs its microphone in 
whatever rate/format it wants, and ALSA converts the sound from the 
existing format to what the app needs.

The exact opposite of this already works for output -- I can force a 
file to be written in the same format, no matter how the app configures 
its sound output. For this, I use the .asoundrc that's also attached. 
But it doesn't work for input. Can someone help me?

Juan

[-- Attachment #2: pcm_file-infile.3.patch --]
[-- Type: text/x-patch, Size: 5425 bytes --]

diff -r 53656cf23f78 src/pcm/pcm_file.c
--- a/src/pcm/pcm_file.c	Thu May 18 11:26:00 2006 +0200
+++ b/src/pcm/pcm_file.c	Thu May 18 13:20:29 2006 -0300
@@ -46,6 +46,8 @@ typedef struct {
 	snd_pcm_generic_t gen;
 	char *fname;
 	int fd;
+	char *ifname;
+	int ifd;
 	int format;
 	snd_pcm_uframes_t appl_ptr;
 	snd_pcm_uframes_t file_ptr_bytes;
@@ -53,6 +55,9 @@ typedef struct {
 	size_t wbuf_size_bytes;
 	size_t wbuf_used_bytes;
 	char *wbuf;
+	size_t rbuf_size_bytes;
+	size_t rbuf_used_bytes;
+	char *rbuf;
 	snd_pcm_channel_area_t *wbuf_areas;
 	size_t buffer_bytes;
 } snd_pcm_file_t;
@@ -120,6 +125,10 @@ static int snd_pcm_file_close(snd_pcm_t 
 		free((void *)file->fname);
 		close(file->fd);
 	}
+	if (file->ifname) {
+		free((void *)file->ifname);
+		close(file->ifd);
+	}
 	return snd_pcm_generic_close(pcm);
 }
 
@@ -222,10 +231,20 @@ static snd_pcm_sframes_t snd_pcm_file_re
 {
 	snd_pcm_file_t *file = pcm->private_data;
 	snd_pcm_channel_area_t areas[pcm->channels];
-	snd_pcm_sframes_t n = snd_pcm_readi(file->gen.slave, buffer, size);
-	if (n > 0) {
-		snd_pcm_areas_from_buf(pcm, areas, buffer);
-		snd_pcm_file_add_frames(pcm, areas, 0, n);
+	snd_pcm_sframes_t n /* , bytesn */;
+
+	if (file->ifd >= 0) {
+		n = /* bytesn = */ read(file->ifd, buffer, size * pcm->frame_bits / 8);
+		if (n > 0)
+			n = n * 8 / pcm->frame_bits;
+		/* SNDERR("DEBUG: channels = %d, sample_bits = %d, frame_bits = %d, bytes = %d, frames = %d",
+		        pcm->channels, pcm->sample_bits, pcm->frame_bits, bytesn, n); */
+	} else {
+		n = snd_pcm_readi(file->gen.slave, buffer, size);
+		if (n > 0) {
+			snd_pcm_areas_from_buf(pcm, areas, buffer);
+			snd_pcm_file_add_frames(pcm, areas, 0, n);
+		}
 	}
 	return n;
 }
@@ -234,7 +253,14 @@ static snd_pcm_sframes_t snd_pcm_file_re
 {
 	snd_pcm_file_t *file = pcm->private_data;
 	snd_pcm_channel_area_t areas[pcm->channels];
-	snd_pcm_sframes_t n = snd_pcm_readn(file->gen.slave, bufs, size);
+	snd_pcm_sframes_t n;
+
+	if (file->ifd >= 0) {
+		SNDERR("DEBUG: Noninterleaved read not yet implemented.\n");
+		return 0;	/* TODO: Noninterleaved read */
+	}
+
+	n = snd_pcm_readn(file->gen.slave, bufs, size);
 	if (n > 0) {
 		snd_pcm_areas_from_bufs(pcm, areas, bufs);
 		snd_pcm_file_add_frames(pcm, areas, 0, n);
@@ -365,8 +391,11 @@ static snd_pcm_fast_ops_t snd_pcm_file_f
  * \brief Creates a new File PCM
  * \param pcmp Returns created PCM handle
  * \param name Name of PCM
- * \param fname Filename (or NULL if file descriptor is available)
- * \param fd File descriptor
+ * \param fname Output filename (or NULL if file descriptor fd is available)
+ * \param fd Output file descriptor
+ * \param ifname Input filename (or NULL if file descriptor ifd is available)
+ * \param ifd Input file descriptor (if (ifd < 0) && (ifname == NULL), no input
+ *            redirection will be performed)
  * \param fmt File format ("raw" is supported only)
  * \param perm File permission
  * \param slave Slave PCM handle
@@ -377,8 +406,8 @@ static snd_pcm_fast_ops_t snd_pcm_file_f
  *          changed in future.
  */
 int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
-		      const char *fname, int fd, const char *fmt, int perm,
-		      snd_pcm_t *slave, int close_slave)
+		      const char *fname, int fd, const char *ifname, int ifd, 
+		      const char *fmt, int perm, snd_pcm_t *slave, int close_slave)
 {
 	snd_pcm_t *pcm;
 	snd_pcm_file_t *file;
@@ -395,7 +424,7 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, 
 	if (fname) {
 		fd = open(fname, O_WRONLY|O_CREAT, perm);
 		if (fd < 0) {
-			SYSERR("open %s failed", fname);
+			SYSERR("open %s for writing failed", fname);
 			return -errno;
 		}
 	}
@@ -405,10 +434,23 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, 
 			close(fd);
 		return -ENOMEM;
 	}
-	
+
+	if (ifname) {
+		ifd = open(ifname, O_RDONLY);	/* TODO: mind blocking mode */
+		if (ifd < 0) {
+			SYSERR("open %s for reading failed", ifname);
+			if (fname)
+				close(fd);
+			return -errno;
+		}
+	}
+
 	if (fname)
 		file->fname = strdup(fname);
+	if (ifname)
+		file->ifname = strdup(ifname);
 	file->fd = fd;
+	file->ifd = ifd;
 	file->format = format;
 	file->gen.slave = slave;
 	file->gen.close_slave = close_slave;
@@ -486,9 +528,9 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp,
 	int err;
 	snd_pcm_t *spcm;
 	snd_config_t *slave = NULL, *sconf;
-	const char *fname = NULL;
+	const char *fname = NULL, *ifname = NULL;
 	const char *format = NULL;
-	long fd = -1;
+	long fd = -1, ifd = -1;
 	int perm = 0600;
 	snd_config_for_each(i, next, conf) {
 		snd_config_t *n = snd_config_iterator_entry(i);
@@ -513,6 +555,17 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp,
 			err = snd_config_get_string(n, &fname);
 			if (err < 0) {
 				err = snd_config_get_integer(n, &fd);
+				if (err < 0) {
+					SNDERR("Invalid type for %s", id);
+					return -EINVAL;
+				}
+			}
+			continue;
+		}
+		if (strcmp(id, "infile") == 0) {
+			err = snd_config_get_string(n, &ifname);
+			if (err < 0) {
+				err = snd_config_get_integer(n, &ifd);
 				if (err < 0) {
 					SNDERR("Invalid type for %s", id);
 					return -EINVAL;
@@ -556,7 +609,7 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp,
 	snd_config_delete(sconf);
 	if (err < 0)
 		return err;
-	err = snd_pcm_file_open(pcmp, name, fname, fd, format, perm, spcm, 1);
+	err = snd_pcm_file_open(pcmp, name, fname, fd, ifname, ifd, format, perm, spcm, 1);
 	if (err < 0)
 		snd_pcm_close(spcm);
 	return err;

[-- Attachment #3: dot-asoundrc --]
[-- Type: text/plain, Size: 246 bytes --]

pcm.fileout {
	type file
	file /home/jcastro/alsaout.raw
	infile /home/jcastro/alsain.raw
	slave.pcm null
}

pcm_slave.sl3 {
    pcm "fileout"
    format S16_LE
    channels 1
    rate 48000
}

pcm.complex_convert {
    type plug
    slave sl3
}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A better pcm_file "infile" patch, and a declaration of being miffed.
  2006-05-18 16:29 A better pcm_file "infile" patch, and a declaration of being miffed Juan Carlos Castro y Castro
@ 2006-05-19 10:40 ` Takashi Iwai
  2006-05-19 13:45   ` Juan Carlos Castro y Castro
  0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2006-05-19 10:40 UTC (permalink / raw)
  To: Juan Carlos Castro y Castro; +Cc: alsa-devel

At Thu, 18 May 2006 13:29:36 -0300,
Juan Carlos Castro y Castro wrote:
> 
> OK, this implements the "infile" parameter of pcm_file in a much cleaner 
> way. Note that the the below new members of snd_pcm_file_t are not used 
> now, but WILL be when I implement protection from fraction-of-frame reads:
> 
>        size_t rbuf_size_bytes;
>        size_t rbuf_used_bytes;
>        char *rbuf;
> 
> Now, the whole reason of this shebang was so I can use the "infile" AND 
> convert rates in the process -- i.e., the app programs its microphone in 
> whatever rate/format it wants, and ALSA converts the sound from the 
> existing format to what the app needs.
> 
> The exact opposite of this already works for output -- I can force a 
> file to be written in the same format, no matter how the app configures 
> its sound output. For this, I use the .asoundrc that's also attached. 
> But it doesn't work for input. Can someone help me?

I guess it works if you point a real mic PCM device as slave but still
using infile?

The patch looks almost OK.  But please don't forget to add the
description of new parameter in the doxygen comment (in \section
pcm_plugins_file Plugin: File), too.

Also, please provide a changelog and a signed-off-by line, e.g.

	The short summary in a line...

	A detailed change log...
	....

	Signed-off-by: Foo Bar <foo@bar.com>


Thanks,

Takashi


-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A better pcm_file "infile" patch, and a declaration of being miffed.
  2006-05-19 10:40 ` Takashi Iwai
@ 2006-05-19 13:45   ` Juan Carlos Castro y Castro
  0 siblings, 0 replies; 3+ messages in thread
From: Juan Carlos Castro y Castro @ 2006-05-19 13:45 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

Takashi Iwai wrote:

>At Thu, 18 May 2006 13:29:36 -0300,
>Juan Carlos Castro y Castro wrote:
>  
>
>>OK, this implements the "infile" parameter of pcm_file in a much cleaner 
>>way. Note that the the below new members of snd_pcm_file_t are not used 
>>now, but WILL be when I implement protection from fraction-of-frame reads:
>>
>>       size_t rbuf_size_bytes;
>>       size_t rbuf_used_bytes;
>>       char *rbuf;
>>
>>Now, the whole reason of this shebang was so I can use the "infile" AND 
>>convert rates in the process -- i.e., the app programs its microphone in 
>>whatever rate/format it wants, and ALSA converts the sound from the 
>>existing format to what the app needs.
>>
>>The exact opposite of this already works for output -- I can force a 
>>file to be written in the same format, no matter how the app configures 
>>its sound output. For this, I use the .asoundrc that's also attached. 
>>But it doesn't work for input. Can someone help me?
>>    
>>
>I guess it works if you point a real mic PCM device as slave but still
>using infile?
>  
>
It will ignore the microphone and read from the file instead. The 
typical use, therefore, is with the null plugin as slave.

If you want to mix a file and a live input (say, for making a narration 
with ambient music), I suppose there are ways to do that with dmix, am I 
correct? (Hmmm, this could have a "loop" option)

My problem is different, it's rate & format conversion. I want to be 
able to use an specific existing file as input even if the app programs 
the "microphone" for a different rate/format. I'm almost certain there 
is a way to do that with existing ALSA plugins (plug? dmix?) but I've 
been unable to find it out on my own. :(

>The patch looks almost OK.  But please don't forget to add the
>description of new parameter in the doxygen comment (in \section
>pcm_plugins_file Plugin: File), too.
>
>Also, please provide a changelog and a signed-off-by line, e.g.
>
>	The short summary in a line...
>
>	A detailed change log...
>	....
>
>	Signed-off-by: Foo Bar <foo@bar.com>
>  
>
Will do.

Cheers,
Juan


-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-05-19 13:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-18 16:29 A better pcm_file "infile" patch, and a declaration of being miffed Juan Carlos Castro y Castro
2006-05-19 10:40 ` Takashi Iwai
2006-05-19 13:45   ` Juan Carlos Castro y Castro

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.