2019年9月15日 星期日

pyalsaaudio錄音問題

不知為何,用alsaaudio.PCM()錄音時,錄出來的格式與設定不符
最後看到這篇才解決
直接強制改pyalsaaudio的alsaaudio.c,改成想要的格式

Copy it form github
author: Hauptmech
diff --git a/alsaaudio.c b/alsaaudio.c
index 76c0ffe..db81f96 100644
--- a/alsaaudio.c
+++ b/alsaaudio.c
@@ -360,13 +359,17 @@ alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     int pcmmode = 0;
     char *device = "default";
     char *card = NULL;
+    unsigned int rate = 48000;
+    unsigned int latency = 500000;
+    unsigned int channels = 2;
+    snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
     int cardidx = -1;
     char hw_device[128];
-    char *kw[] = { "type", "mode", "device", "cardindex", "card", NULL };
+    char *kw[] = { "type", "mode", "device", "cardindex", "card", "rate", "latency", "fmt", "channels", NULL };
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oisiz", kw,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oisiziiii", kw,
                                      &pcmtypeobj, &pcmmode, &device,
-                                     &cardidx, &card))
+                                     &cardidx, &card, &rate, &latency, &format, &channels))
         return NULL;
 
     if (cardidx >= 0) {
@@ -410,18 +413,28 @@ alsapcm_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     self->handle = 0;
     self->pcmtype = pcmtype;
     self->pcmmode = pcmmode;
-    self->channels = 2;
-    self->rate = 44100;
-    self->format = SND_PCM_FORMAT_S16_LE;
-    self->periodsize = 32;
+    self->channels = channels;
+    self->rate = rate;
+    self->format = format;
+
 
     res = snd_pcm_open(&(self->handle), device, self->pcmtype,
                        self->pcmmode);
 
-    if (res >= 0) {
-        res = alsapcm_setup(self);
+    if (res >= 0){
+     snd_pcm_hw_params_malloc(&(self->hwparams));
+    }
+    res = snd_pcm_set_params(self->handle, format, 
+      SND_PCM_ACCESS_RW_INTERLEAVED, channels, rate, 1, latency);
+    if (res) {
+            PyErr_Format(ALSAAudioError, "%s [%s]", snd_strerror(res), device);
     }
-    
+
+    //Populate framesize and periodsize
+    snd_pcm_hw_params_current(self->handle, self->hwparams);
+    self->framesize = channels * snd_pcm_hw_params_get_sbits(self->hwparams)/8;
+    snd_pcm_hw_params_get_period_size(self->hwparams,&self->periodsize,0);
+
     if (res >= 0) {
         self->cardname = strdup(device);
     }
Copy it form github
author: Hauptmech

沒有留言:

張貼留言