~ubuntu-branches/ubuntu/quantal/python-pyo/quantal

« back to all changes in this revision

Viewing changes to src/engine/pyomodule.c

  • Committer: Package Import Robot
  • Author(s): Tiago Bortoletto Vaz
  • Date: 2012-07-03 23:45:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120703234541-jh5jg00lvljnwq8m
Tags: 0.6.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "tablemodule.h"
30
30
#include "matrixmodule.h"
31
31
 
 
32
/** Note : 
 
33
 ** Add an argument to pa_get_* and pm_get_* functions to allow printing to the console
 
34
 **/
 
35
 
32
36
/****** Portaudio utilities ******/
33
37
static void portaudio_assert(PaError ecode, const char* cmdName) {
34
38
    if (ecode != paNoError) {
88
92
            for (i=0; i < n; ++i){
89
93
                const PaHostApiInfo *info = Pa_GetHostApiInfo(i);
90
94
                assert(info);
91
 
                
92
95
                fprintf(stdout, "index: %i, id: %i, name: %s, num devices: %i, default in: %i, default out: %i\n", i, (int)info->type, info->name, (int)info->deviceCount, (int)info->defaultInputDevice, (int)info->defaultOutputDevice);
93
96
            }
94
97
        }        
114
117
        }
115
118
    else {
116
119
        i = Pa_GetDefaultHostApi();
117
 
        const PaHostApiInfo *info = Pa_GetHostApiInfo(i);
118
 
        assert(info);
119
 
        
120
 
        fprintf(stdout, "index: %i, id: %i, name: %s, num devices: %i, default in: %i, default out: %i\n", i, (int)info->type, info->name, (int)info->deviceCount, (int)info->defaultInputDevice, (int)info->defaultOutputDevice);
121
 
        
122
120
        return PyInt_FromLong(i);
123
121
    }
124
122
}
224
222
        else {
225
223
            for (i=0; i < n; ++i){
226
224
                const PaDeviceInfo *info=Pa_GetDeviceInfo(i);
227
 
                assert(info);
228
 
                
 
225
                assert(info);                
229
226
                if (info->maxOutputChannels > 0){
230
 
                    fprintf(stdout, "%i: OUT, name: %s, host api index: %i, default sr: %i Hz, latency: %f s\n", i, info->name, (int)info->hostApi, (int)info->defaultSampleRate, (float)info->defaultLowOutputLatency);
231
227
                    PyList_Append(list, PyString_FromString(info->name));
232
228
                    PyList_Append(list_index, PyInt_FromLong(i));
233
229
                }
267
263
        else {
268
264
            for (i=0; i < n; ++i){
269
265
                const PaDeviceInfo *info=Pa_GetDeviceInfo(i);
270
 
                assert(info);
271
 
                
 
266
                assert(info);                
272
267
                if (info->maxInputChannels > 0){
273
 
                    fprintf(stdout, "%i: IN, name: %s, host api index: %i, default sr: %i Hz, latency: %f s\n", i, info->name, (int)info->hostApi, (int)info->defaultSampleRate, (float)info->defaultLowInputLatency);
274
268
                    PyList_Append(list, PyString_FromString(info->name));
275
269
                    PyList_Append(list_index, PyInt_FromLong(i));
276
270
                }
299
293
        }
300
294
    else {
301
295
        i = Pa_GetDefaultInputDevice();
302
 
        const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
303
 
        assert(info);
304
 
        
305
 
        if (info->maxInputChannels > 0)
306
 
            fprintf(stdout, "%i: IN, name: %s, default sr: %i Hz, latency: %f s\n", i, info->name, (int)info->defaultSampleRate, (float)info->defaultLowInputLatency);
307
 
 
308
296
        return PyInt_FromLong(i);        
309
297
    }
310
298
 
329
317
        }
330
318
    else {
331
319
        i = Pa_GetDefaultOutputDevice();
332
 
        const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
333
 
        assert(info);
334
 
        
335
 
        if (info->maxOutputChannels > 0)
336
 
            fprintf(stdout, "%i: OUT, name: %s, default sr: %i Hz, latency: %f s\n", i, info->name, (int)info->defaultSampleRate, (float)info->defaultLowInputLatency);
337
 
        
338
320
        return PyInt_FromLong(i);
339
321
        
340
322
    }
391
373
static PyObject*
392
374
portmidi_get_input_devices(){
393
375
        int n, i;
394
 
    
395
376
    PyObject *list, *list_index;
396
377
    list = PyList_New(0);
397
378
    list_index = PyList_New(0);
398
 
 
399
379
    n = Pm_CountDevices();
400
380
    if (n < 0){
401
381
        printf("Portmidi warning: No Midi interface found\n\n");
403
383
    else {
404
384
        for (i=0; i < n; i++){
405
385
            const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
406
 
        
407
386
            if (info->input){
408
 
                printf("%d: IN, name: %s, interface: %s\n", i, info->name, info->interf);
409
387
                PyList_Append(list, PyString_FromString(info->name));
410
388
                PyList_Append(list_index, PyInt_FromLong(i));
411
389
            }
424
402
static PyObject*
425
403
portmidi_get_output_devices(){
426
404
        int n, i;
427
 
    
428
405
    PyObject *list, *list_index;
429
406
    list = PyList_New(0);
430
407
    list_index = PyList_New(0);
431
 
    
432
408
    n = Pm_CountDevices();
433
409
    if (n < 0){
434
410
        printf("Portmidi warning: No Midi interface found\n\n");
436
412
    else {
437
413
        for (i=0; i < n; i++){
438
414
            const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
439
 
            
440
415
            if (info->output){
441
 
                printf("%d: OUT, name: %s, interface: %s\n", i, info->name, info->interf);
442
416
                PyList_Append(list, PyString_FromString(info->name));
443
417
                PyList_Append(list_index, PyInt_FromLong(i));
444
418
            }
460
434
    PmDeviceID i;
461
435
    
462
436
    i = Pm_GetDefaultInputDeviceID();
463
 
    if (i >= 0) {
464
 
        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
465
 
        if (info->input) 
466
 
            printf("%d: IN, name: %s, interface: %s\n", i, info->name, info->interf);        
467
 
    }
468
 
    else {
 
437
    if (i < 0)
469
438
        printf("pm_get_default_input: no midi input device found.\n");
470
 
    }
471
 
 
472
439
    return PyInt_FromLong(i);
473
440
}
474
441
 
482
449
static PyObject *
483
450
portmidi_get_default_output(){
484
451
    PmDeviceID i;
485
 
    
486
452
    i = Pm_GetDefaultOutputDeviceID();
487
 
    if (i >= 0) {
488
 
        const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
489
 
        if (info->output) 
490
 
            printf("%d: OUT, name: %s, interface: %s\n", i, info->name, info->interf);        
491
 
    }
492
 
    else {
 
453
    if (i < 0)
493
454
        printf("pm_get_default_output: no midi output device found.\n");
494
 
    }
495
 
    
496
455
    return PyInt_FromLong(i);
497
456
}
498
457
 
524
483
 
525
484
    static char *kwlist[] = {"path", "print", NULL};
526
485
 
527
 
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &pathtmp, &print))
 
486
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "s|i", kwlist, &pathtmp, &print)) {
 
487
        PySys_WriteStderr("sndinfo: failed to open the file.\n");
528
488
        Py_RETURN_NONE;
 
489
    }
529
490
 
530
491
    path = malloc(strlen(pathtmp)+1);
531
492
    strcpy(path, pathtmp);
534
495
    info.format = 0;
535
496
    sf = sf_open(path, SFM_READ, &info);
536
497
    if (sf == NULL) {
537
 
        printf("Failed to open the file.\n");
 
498
        PySys_WriteStderr("sndinfo: failed to open the file.\n");
538
499
        Py_RETURN_NONE;
539
500
    }
540
501
    else {
683
644
    }
684
645
    else {
685
646
        if (PyList_Size(samples) != channels) {
686
 
            printf("Samples list size and channels must be the same!\n");
 
647
            printf("savefile: samples list size and channels must be the same!\n");
687
648
            return PyInt_FromLong(-1);
688
649
        }
689
650
        size = PyList_Size(PyList_GET_ITEM(samples, 0)) * channels;
695
656
        }    
696
657
    }    
697
658
    if (! (recfile = sf_open(recpath, SFM_WRITE, &recinfo))) {
698
 
        printf ("Not able to open output file %s.\n", recpath);
 
659
        printf ("savefile: failed to open output file %s.\n", recpath);
699
660
        return PyInt_FromLong(-1);
700
661
    }
701
662
    SF_WRITE(recfile, sampsarray, size);
705
666
    Py_RETURN_NONE;    
706
667
}
707
668
 
 
669
#define savefileFromTable_info \
 
670
"\nCreates an audio file from the content of a table.\n\nsavefileFromTable(table, path, fileformat=0, sampletype=0)\n\nParameters:\n\n    \
 
671
table : PyoTableObject\n        table from which to retrieve samples to write.\n    \
 
672
path : string\n        Full path (including extension) of the new file.\n    \
 
673
fileformat : int, optional\n        Format type of the new file. Defaults to 0. Supported formats are:\n    \
 
674
0 : WAVE - Microsoft WAV format (little endian) {.wav, .wave}\n    \
 
675
1 : AIFF - Apple/SGI AIFF format (big endian) {.aif, .aiff}\n    \
 
676
sampletype ; int, optional\n        Bit depth encoding of the audio file. Defaults to 0. Supported types are:\n    \
 
677
0 : 16 bit int\n    \
 
678
1 : 24 bit int\n    \
 
679
2 : 32 bit int\n    \
 
680
3 : 32 bit float\n    \
 
681
4 : 64 bit float\n\n\
 
682
Examples:\n\n    \
 
683
>>> import os\n    \
 
684
>>> home = os.path.expanduser('~')\n    \
 
685
>>> path1 = SNDS_PATH + '/transparent.aif'\n    \
 
686
>>> path2 = os.path.join(home, '/transparent2.aif')\n    \
 
687
>>> t = SndTable(path1)\n    \
 
688
>>> savefileFromTable(table=t, path=path, fileformat=1, sampletype=1)\n\n"
 
689
 
 
690
static PyObject *
 
691
savefileFromTable(PyObject *self, PyObject *args, PyObject *kwds) {
 
692
    int i, j, size;
 
693
    char *recpath;
 
694
    PyObject *table;
 
695
    PyObject *base_objs;
 
696
    PyObject *tablestreamlist;
 
697
    MYFLT *sampsarray;
 
698
    int sr = 44100;
 
699
    int channels = 1;
 
700
    int fileformat = 0;
 
701
    int sampletype = 0;
 
702
    int count = 0;
 
703
    int num_items = 0;
 
704
    SNDFILE *recfile;
 
705
    SF_INFO recinfo;
 
706
    static char *kwlist[] = {"table", "path", "fileformat", "sampletype", NULL};
 
707
    
 
708
    if (! PyArg_ParseTupleAndKeywords(args, kwds, "Os|ii", kwlist, &table, &recpath, &fileformat, &sampletype))
 
709
        return PyInt_FromLong(-1);
 
710
    
 
711
    base_objs = PyObject_GetAttrString(table, "_base_objs");
 
712
    channels = PyList_Size(base_objs);
 
713
    tablestreamlist = PyList_New(channels);
 
714
    for (i=0; i<channels; i++) {
 
715
        PyList_SET_ITEM(tablestreamlist, i, PyObject_CallMethod(PyList_GetItem(base_objs, i), "getTableStream", NULL));
 
716
    }
 
717
    sr = (int)TableStream_getSamplingRate((PyObject *)PyList_GetItem(tablestreamlist, 0));
 
718
    size = TableStream_getSize((PyObject *)PyList_GetItem(tablestreamlist, 0));
 
719
    
 
720
    recinfo.samplerate = sr;
 
721
    recinfo.channels = channels;
 
722
    switch (fileformat) {
 
723
        case 0:
 
724
            recinfo.format = SF_FORMAT_WAV;
 
725
            break;
 
726
        case 1:
 
727
            recinfo.format = SF_FORMAT_AIFF;
 
728
            break;
 
729
    }
 
730
    switch (sampletype) {
 
731
        case 0:
 
732
            recinfo.format = recinfo.format | SF_FORMAT_PCM_16;
 
733
            break;
 
734
        case 1:
 
735
            recinfo.format = recinfo.format | SF_FORMAT_PCM_24;
 
736
            break;
 
737
        case 2:
 
738
            recinfo.format = recinfo.format | SF_FORMAT_PCM_32;
 
739
            break;
 
740
        case 3:
 
741
            recinfo.format = recinfo.format | SF_FORMAT_FLOAT;
 
742
            break;
 
743
        case 4:
 
744
            recinfo.format = recinfo.format | SF_FORMAT_DOUBLE;
 
745
            break;
 
746
    }
 
747
 
 
748
    if (! (recfile = sf_open(recpath, SFM_WRITE, &recinfo))) {
 
749
        printf ("savefileFromTable: failed to open output file %s.\n", recpath);
 
750
        Py_XDECREF(base_objs);
 
751
        Py_XDECREF(tablestreamlist);
 
752
        return PyInt_FromLong(-1);
 
753
    }
 
754
    
 
755
    if (channels == 1) {
 
756
        MYFLT *data;
 
757
        if (size < (sr * 60)) {
 
758
            data = TableStream_getData((PyObject *)PyList_GetItem(tablestreamlist, 0));
 
759
            sampsarray = (MYFLT *)malloc(size * sizeof(MYFLT));
 
760
            for (i=0; i<size; i++) {
 
761
                sampsarray[i] = data[i];
 
762
            }
 
763
            SF_WRITE(recfile, sampsarray, size);
 
764
        }
 
765
        else {
 
766
            data = TableStream_getData((PyObject *)PyList_GetItem(tablestreamlist, 0));
 
767
            num_items = sr * 30;
 
768
            sampsarray = (MYFLT *)malloc(num_items * sizeof(MYFLT));
 
769
            do {
 
770
                if ((size - count) < num_items)
 
771
                    num_items = size - count;
 
772
                for (i=0; i<num_items; i++) {
 
773
                    sampsarray[i] = data[count++];
 
774
                }
 
775
                SF_WRITE(recfile, sampsarray, num_items);
 
776
            } while (num_items == (sr * 30));
 
777
        }
 
778
    }
 
779
    else {
 
780
        MYFLT *data[channels];
 
781
        if (size < (sr * 60)) {
 
782
            for (j=0; j<channels; j++) {
 
783
                data[j] = TableStream_getData((PyObject *)PyList_GetItem(tablestreamlist, j));
 
784
            }
 
785
            sampsarray = (MYFLT *)malloc(size * channels * sizeof(MYFLT));
 
786
            for (i=0; i<size; i++) {
 
787
                for (j=0; j<channels; j++) {
 
788
                    sampsarray[i*channels+j] = data[j][i];
 
789
                }
 
790
            }
 
791
            SF_WRITE(recfile, sampsarray, size * channels);
 
792
        }
 
793
        else {
 
794
            for (j=0; j<channels; j++) {
 
795
                data[j] = TableStream_getData((PyObject *)PyList_GetItem(tablestreamlist, j));
 
796
            }
 
797
            num_items = sr * 30;
 
798
            sampsarray = (MYFLT *)malloc(num_items * channels * sizeof(MYFLT));
 
799
            do {
 
800
                if ((size - count) < num_items)
 
801
                    num_items = size - count;
 
802
                for (i=0; i<num_items; i++) {
 
803
                    for (j=0; j<channels; j++) {
 
804
                        sampsarray[i*channels+j] = data[j][count];
 
805
                    }
 
806
                    count++;
 
807
                }
 
808
                SF_WRITE(recfile, sampsarray, num_items * channels);
 
809
            } while (num_items == (sr * 30));
 
810
        }
 
811
    }    
 
812
 
 
813
    sf_close(recfile);
 
814
    free(sampsarray);
 
815
    Py_XDECREF(base_objs);
 
816
    Py_XDECREF(tablestreamlist);
 
817
    
 
818
    Py_RETURN_NONE;    
 
819
}
 
820
 
708
821
/****** Sampling rate conversions ******/
709
822
#define upsamp_info \
710
823
"\nIncreases the sampling rate of an audio file.\n\nupsamp(path, outfile, up=4, order=128)\n\nParameters:\n\n    \
835
948
    info.format = 0;
836
949
    sf = sf_open(inpath, SFM_READ, &info);
837
950
    if (sf == NULL) {
838
 
        printf("Failed to open the file.\n");
 
951
        printf("upsamp: failed to open the input file %s.\n", inpath);
839
952
        return PyInt_FromLong(-1);
840
953
    }
841
954
    snd_size = info.frames;
888
1001
    }    
889
1002
    
890
1003
    if (! (sf = sf_open(outpath, SFM_WRITE, &info))) {
891
 
        printf ("Not able to open output file %s.\n", outpath);
 
1004
        printf ("upsamp: failed to open output file %s.\n", outpath);
892
1005
        free(tmp);
893
1006
        for (i=0; i<snd_chnls; i++) {
894
1007
            free(samples[i]);
938
1051
    info.format = 0;
939
1052
    sf = sf_open(inpath, SFM_READ, &info);
940
1053
    if (sf == NULL) {
941
 
        printf("Failed to open the file.\n");
 
1054
        printf("downsamp: failed to open the input file %s.\n", inpath);
942
1055
        return PyInt_FromLong(-1);
943
1056
    }
944
1057
    snd_size = info.frames;
988
1101
    }    
989
1102
    
990
1103
    if (! (sf = sf_open(outpath, SFM_WRITE, &info))) {
991
 
        printf ("Not able to open output file %s.\n", outpath);
 
1104
        printf("downsamp: failed to open the output file %s.\n", outpath);
992
1105
        free(tmp);
993
1106
        for (i=0; i<snd_chnls; i++) {
994
1107
            free(samples[i]);
1610
1723
#define sampsToSec_info \
1611
1724
"\nReturns the duration in seconds equivalent to the number of samples given as an argument.\n\nsampsToSec(x)\n\nParameters:\n\n    \
1612
1725
x : int or float\n        Duration in samples. `x` can be a number, a list or a tuple, otherwise function returns None.\n\nExamples:\n\n    \
 
1726
>>> s = Server().boot()\n    \
1613
1727
>>> a = (64, 128, 256)\n    \
1614
1728
>>> b = sampsToSec(a)\n    \
1615
1729
>>> print b\n    \
1661
1775
#define secToSamps_info \
1662
1776
"\nReturns the number of samples equivalent to the duration in seconds given as an argument.\n\nsecToSamps(x)\n\nParameters:\n\n    \
1663
1777
x : int or float\n        Duration in seconds. `x` can be a number, a list or a tuple, otherwise function returns None.\n\nExamples:\n\n    \
 
1778
>>> s = Server().boot()\n    \
1664
1779
>>> a = (0.1, 0.25, 0.5, 1)\n    \
1665
1780
>>> b = secToSamps(a)\n    \
1666
1781
>>> print b\n    \
1748
1863
            Py_RETURN_TRUE;
1749
1864
    }
1750
1865
    else {
1751
 
        printf("'serverBooted' called but there is no server created.\n");
 
1866
        printf("Warning: A Server must be created before calling `serverBooted` function.\n");
1752
1867
        Py_RETURN_FALSE;
1753
1868
    }
1754
1869
}
1771
1886
{"pm_get_default_output", (PyCFunction)portmidi_get_default_output, METH_NOARGS, portmidi_get_default_output_info},
1772
1887
{"sndinfo", (PyCFunction)sndinfo, METH_VARARGS|METH_KEYWORDS, sndinfo_info},
1773
1888
{"savefile", (PyCFunction)savefile, METH_VARARGS|METH_KEYWORDS, savefile_info},
 
1889
{"savefileFromTable", (PyCFunction)savefileFromTable, METH_VARARGS|METH_KEYWORDS, savefileFromTable_info},
1774
1890
{"upsamp", (PyCFunction)upsamp, METH_VARARGS|METH_KEYWORDS, upsamp_info},
1775
1891
{"downsamp", (PyCFunction)downsamp, METH_VARARGS|METH_KEYWORDS, downsamp_info},
1776
1892
{"reducePoints", (PyCFunction)reducePoints, METH_VARARGS|METH_KEYWORDS, reducePoints_info},
1797
1913
    
1798
1914
    m = Py_InitModule3(LIB_BASE_NAME, pyo_functions, "Python digital signal processing module.");
1799
1915
 
 
1916
#ifndef NO_MESSAGES
 
1917
#ifndef USE_DOUBLE
 
1918
    printf("pyo version %s (uses single precision)\n", PYO_VERSION);
 
1919
#else
 
1920
    printf("pyo version %s (uses double precision)\n", PYO_VERSION);
 
1921
#endif
 
1922
#endif
 
1923
 
1800
1924
    if (PyType_Ready(&ServerType) < 0)
1801
1925
        return;
1802
1926
    Py_INCREF(&ServerType);
1998
2122
    Py_INCREF(&MatrixRecType);
1999
2123
    PyModule_AddObject(m, "MatrixRec_base", (PyObject *)&MatrixRecType);
2000
2124
 
 
2125
    if (PyType_Ready(&MatrixRecLoopType) < 0)
 
2126
        return;
 
2127
    Py_INCREF(&MatrixRecLoopType);
 
2128
    PyModule_AddObject(m, "MatrixRecLoop_base", (PyObject *)&MatrixRecLoopType);
 
2129
    
2001
2130
    if (PyType_Ready(&MatrixMorphType) < 0)
2002
2131
        return;
2003
2132
    Py_INCREF(&MatrixMorphType);
2272
2401
        return;
2273
2402
    Py_INCREF(&BiquadxType);
2274
2403
    PyModule_AddObject(m, "Biquadx_base", (PyObject *)&BiquadxType);
2275
 
 
 
2404
    
2276
2405
    if (PyType_Ready(&BiquadaType) < 0)
2277
2406
        return;
2278
2407
    Py_INCREF(&BiquadaType);
2307
2436
        return;
2308
2437
    Py_INCREF(&PhaserType);
2309
2438
    PyModule_AddObject(m, "Phaser_base", (PyObject *)&PhaserType);    
 
2439
 
 
2440
    if (PyType_Ready(&VocoderType) < 0)
 
2441
        return;
 
2442
    Py_INCREF(&VocoderType);
 
2443
    PyModule_AddObject(m, "Vocoder_base", (PyObject *)&VocoderType);
2310
2444
    
2311
2445
    if (PyType_Ready(&PortType) < 0)
2312
2446
        return;
2388
2522
    Py_INCREF(&CtlScanType);
2389
2523
    PyModule_AddObject(m, "CtlScan_base", (PyObject *)&CtlScanType);
2390
2524
 
 
2525
    if (PyType_Ready(&CtlScan2Type) < 0)
 
2526
        return;
 
2527
    Py_INCREF(&CtlScan2Type);
 
2528
    PyModule_AddObject(m, "CtlScan2_base", (PyObject *)&CtlScan2Type);
 
2529
    
2391
2530
    if (PyType_Ready(&MidiNoteType) < 0)
2392
2531
        return;
2393
2532
    Py_INCREF(&MidiNoteType);