From: Juan Carlos Castro y Castro <jcastro@instant.com.br>
To: alsa-devel@lists.sourceforge.net
Cc: Takashi Iwai <tiwai@suse.de>
Subject: A better pcm_file "infile" patch, and a declaration of being miffed.
Date: Thu, 18 May 2006 13:29:36 -0300 [thread overview]
Message-ID: <446CA0F0.2000603@instant.com.br> (raw)
[-- 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
}
next reply other threads:[~2006-05-18 16:29 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-18 16:29 Juan Carlos Castro y Castro [this message]
2006-05-19 10:40 ` A better pcm_file "infile" patch, and a declaration of being miffed Takashi Iwai
2006-05-19 13:45 ` Juan Carlos Castro y Castro
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=446CA0F0.2000603@instant.com.br \
--to=jcastro@instant.com.br \
--cc=alsa-devel@lists.sourceforge.net \
--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.