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

« back to all changes in this revision

Viewing changes to src/engine/servermodule.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:
24
24
#include <stdarg.h>
25
25
#include <time.h>
26
26
#include <stdlib.h>
 
27
#include <pthread.h>
27
28
 
28
29
#include "structmember.h"
29
30
#include "portaudio.h"
86
87
Server_warning(Server *self, char * format, ...)
87
88
{
88
89
    // Warnings should be used when an unexpected or unusual choice was made by pyo
 
90
#ifndef NO_MESSAGES
89
91
    if (self->verbosity & 4) {
90
92
        char buffer[256];
91
93
        va_list args;
94
96
        va_end (args);
95
97
        printf("%s",buffer);
96
98
    }
 
99
#endif
97
100
}
98
101
 
99
102
void
512
515
    PyoPaBackendData *be_data = (PyoPaBackendData *) self->audio_be_data;
513
516
 
514
517
    if (Pa_IsStreamActive(be_data->stream) || ! Pa_IsStreamStopped(be_data->stream)) {
515
 
        err = Pa_StopStream(be_data->stream);
516
 
        portaudio_assert(err, "Pa_StopStream");
 
518
        self->server_started = 0;
 
519
        //err = Pa_StopStream(be_data->stream);
 
520
        //portaudio_assert(err, "Pa_StopStream");
517
521
    }
518
522
    
519
 
    err = Pa_CloseStream(be_data->stream);
520
 
    portaudio_assert(err, "Pa_CloseStream");
 
523
//    err = Pa_CloseStream(be_data->stream);
 
524
//    portaudio_assert(err, "Pa_CloseStream");
521
525
    
522
526
    err = Pa_Terminate();
523
527
    portaudio_assert(err, "Pa_Terminate");
566
570
    int i=0;
567
571
    while(ports[i]!=NULL && be_data->jack_in_ports[i] != NULL){
568
572
        if (jack_connect (be_data->jack_client, ports[i], jack_port_name(be_data->jack_in_ports[i]))) {
569
 
            Server_warning(self, "Jack: cannot connect input ports\n");
 
573
            Server_error(self, "Jack: cannot connect input ports\n");
570
574
            ret = -1;
571
575
        }
572
576
        i++;
582
586
    i=0;
583
587
    while(ports[i]!=NULL && be_data->jack_out_ports[i] != NULL){
584
588
        if (jack_connect (be_data->jack_client, jack_port_name (be_data->jack_out_ports[i]), ports[i])) {
585
 
            Server_warning(self, "Jack: cannot connect output ports\n");
 
589
            Server_error(self, "Jack: cannot connect output ports\n");
586
590
            ret = -1;
587
591
        }
588
592
        i++;
616
620
        return -1;
617
621
    }
618
622
    if (status & JackServerStarted) {
619
 
        Server_message(self, "JACK server started.\n");
 
623
        Server_warning(self, "JACK server started.\n");
620
624
    }
621
625
    if (strcmp(self->serverName, jack_get_client_name(be_data->jack_client)) ) {
622
626
        strcpy(self->serverName, jack_get_client_name(be_data->jack_client));
756
760
            free(name);
757
761
            break;
758
762
        }
759
 
        Server_message(self, "   %d : \"%s\"\n", i, name);
 
763
        Server_debug(self, "   %d : \"%s\"\n", i, name);
760
764
        free(name);
761
765
    }    
762
766
    
786
790
        if (err != kAudioHardwareNoError) {
787
791
            Server_error(self, "Get kAudioDevicePropertyDeviceName error %s A %08X\n", (char*)&err, mInputDevice);
788
792
        }
789
 
        Server_message(self, "Coreaudio : Uses input device : \"%s\"\n", name);
 
793
        Server_debug(self, "Coreaudio : Uses input device : \"%s\"\n", name);
790
794
        self->input = mInputDevice;
791
795
        free(name);
792
796
    }    
813
817
    if (err != kAudioHardwareNoError) {
814
818
        Server_error(self, "Get kAudioDevicePropertyDeviceName error %s A %08X\n", (char*)&err, mOutputDevice);
815
819
    }
816
 
    Server_message(self, "Coreaudio : Uses output device : \"%s\"\n", name);
 
820
    Server_debug(self, "Coreaudio : Uses output device : \"%s\"\n", name);
817
821
    self->output = mOutputDevice;
818
822
    free(name);
819
823
    
880
884
        if (err != kAudioHardwareNoError)
881
885
            Server_error(self, "set kAudioDevicePropertyBufferFrameSize error %4.4s\n", (char*)&err);
882
886
        else
883
 
            Server_message(self, "pyo buffer size set to output device buffer size : %i\n", self->bufferSize);
 
887
            Server_debug(self, "pyo buffer size set to output device buffer size : %i\n", self->bufferSize);
884
888
    } 
885
889
    else
886
 
        Server_message(self, "Coreaudio : Changed output device buffer size successfully: %i\n", self->bufferSize);
 
890
        Server_debug(self, "Coreaudio : Changed output device buffer size successfully: %i\n", self->bufferSize);
887
891
 
888
892
    if (self->duplex == 1) {
889
893
        err = AudioDeviceSetProperty(mInputDevice, &now, 0, false, kAudioDevicePropertyBufferFrameSize, count, &self->bufferSize);
903
907
        if (err != kAudioHardwareNoError)
904
908
            Server_error(self, "set kAudioDevicePropertyNominalSampleRate error %s\n", (char*)&err);
905
909
        else    
906
 
            Server_message(self, "pyo sampling rate set to output device sampling rate : %i\n", self->samplingRate);
 
910
            Server_debug(self, "pyo sampling rate set to output device sampling rate : %i\n", self->samplingRate);
907
911
    }
908
912
    else
909
 
        Server_message(self, "Coreaudio : Changed output device sampling rate successfully: %.2f\n", self->samplingRate);
 
913
        Server_debug(self, "Coreaudio : Changed output device sampling rate successfully: %.2f\n", self->samplingRate);
910
914
    
911
915
    if (self->duplex ==1) {
912
916
        pyoSamplingRate = self->samplingRate;
1061
1065
#endif
1062
1066
 
1063
1067
int
1064
 
Server_offline_init (Server *self)
1065
 
{
1066
 
    return 0;
1067
 
}
1068
 
 
1069
 
int
1070
 
Server_offline_deinit (Server *self)
1071
 
{
1072
 
    return 0;
1073
 
}
1074
 
 
1075
 
int
1076
 
Server_offline_start (Server *self)
1077
 
{
 
1068
Server_offline_init(Server *self)
 
1069
{
 
1070
    return 0;
 
1071
}
 
1072
 
 
1073
int
 
1074
Server_offline_deinit(Server *self)
 
1075
{
 
1076
    return 0;
 
1077
}
 
1078
 
 
1079
void 
 
1080
*Server_offline_thread(void *arg)
 
1081
{
 
1082
    int numBlocks;
 
1083
    Server *self;
 
1084
    self = (Server *)arg;
 
1085
    
 
1086
    if (self->recdur < 0) {
 
1087
        Server_error(self,"Duration must be specified for Offline Server (see Server.recordOptions).");
 
1088
    }
 
1089
    else {
 
1090
        Server_message(self,"Offline Server rendering file %s dur=%f\n", self->recpath, self->recdur);
 
1091
        numBlocks = ceil(self->recdur * self->samplingRate/self->bufferSize);
 
1092
        Server_debug(self,"Number of blocks: %i\n", numBlocks);
 
1093
        Server_start_rec_internal(self, self->recpath);
 
1094
        while (numBlocks-- > 0 && self->server_stopped == 0) {
 
1095
            offline_process_block((Server *) self); 
 
1096
        }
 
1097
        self->server_started = 0;
 
1098
        self->record = 0;
 
1099
        sf_close(self->recfile);
 
1100
        Server_message(self,"Offline Server rendering finished.\n");         
 
1101
    }
 
1102
}
 
1103
 
 
1104
int
 
1105
Server_offline_nb_start(Server *self)
 
1106
{
 
1107
    pthread_t offthread;
 
1108
    pthread_create(&offthread, NULL, Server_offline_thread, self);
 
1109
    return 0;
 
1110
}
 
1111
 
 
1112
int
 
1113
Server_offline_start(Server *self)
 
1114
{
 
1115
    int numBlocks;
 
1116
    
1078
1117
    if (self->recdur < 0) {
1079
1118
        Server_error(self,"Duration must be specified for Offline Server (see Server.recordOptions).");
1080
1119
        return -1;
1081
1120
    }
1082
1121
    Server_message(self,"Offline Server rendering file %s dur=%f\n", self->recpath, self->recdur);
1083
 
    int numBlocks = ceil(self->recdur * self->samplingRate/self->bufferSize);
 
1122
    numBlocks = ceil(self->recdur * self->samplingRate/self->bufferSize);
1084
1123
    Server_debug(self,"Number of blocks: %i\n", numBlocks);
1085
1124
    Server_start_rec_internal(self, self->recpath);
1086
1125
    while (numBlocks-- > 0 && self->server_stopped == 0) {
1087
 
        offline_process_block((Server *) self);   
 
1126
        offline_process_block((Server *) self); 
1088
1127
    }
1089
1128
    self->server_started = 0;
1090
1129
    self->record = 0;
1094
1133
}
1095
1134
 
1096
1135
int
1097
 
Server_offline_stop (Server *self)
 
1136
Server_offline_stop(Server *self)
1098
1137
{
1099
1138
    self->server_stopped = 1;
1100
1139
    return 0;
1109
1148
    float *out = server->output_buffer;    
1110
1149
    MYFLT buffer[server->nchnls][server->bufferSize];
1111
1150
    int i, j, chnl;
1112
 
    int count = server->stream_count;
1113
1151
    int nchnls = server->nchnls;
1114
1152
    MYFLT amp = server->amp;
1115
1153
    Stream *stream_tmp;
1117
1155
 
1118
1156
    memset(&buffer, 0, sizeof(buffer));
1119
1157
    PyGILState_STATE s = PyGILState_Ensure();
1120
 
    for (i=0; i<count; i++) {
 
1158
    for (i=0; i<server->stream_count; i++) {
1121
1159
        stream_tmp = (Stream *)PyList_GET_ITEM(server->streams, i);
1122
1160
        if (Stream_getStreamActive(stream_tmp) == 1) {
1123
1161
            Stream_callFunction(stream_tmp);
1258
1296
    int i;
1259
1297
    int ret = -1;
1260
1298
    if (self->server_booted == 0) {
1261
 
        Server_error(self, "The Server must be booted!");
 
1299
        Server_error(self, "The Server must be booted!\n");
1262
1300
        Py_INCREF(Py_None);
1263
1301
        return Py_None;
1264
1302
    }
1287
1325
        case PyoOffline:
1288
1326
            ret = Server_offline_deinit(self);  
1289
1327
            break;         
 
1328
        case PyoOfflineNB:
 
1329
            ret = Server_offline_deinit(self);  
 
1330
            break;         
1290
1331
    }
1291
1332
    self->server_booted = 0;
1292
1333
    if (ret < 0) {
1319
1360
static void
1320
1361
Server_dealloc(Server* self)
1321
1362
{  
1322
 
    Server_shut_down(self);
 
1363
    if (self->server_booted == 1)
 
1364
        Server_shut_down(self);
1323
1365
    Server_clear(self);
1324
1366
    free(self->input_buffer);
 
1367
    free(self->output_buffer);
1325
1368
    free(self->serverName);
 
1369
    my_server = NULL;
1326
1370
    self->ob_type->tp_free((PyObject*)self);
1327
1371
}
1328
1372
 
1358
1402
    self->startoffset = 0.0;
1359
1403
    self->globalSeed = 0;
1360
1404
    Py_XDECREF(my_server);
1361
 
    Py_XINCREF(self);
1362
1405
    my_server = (Server *)self;
1363
1406
    return (PyObject *)self;
1364
1407
}
1387
1430
    else if (strcmp(audioType, "offline") == 0) {
1388
1431
        self->audio_be_type = PyoOffline;
1389
1432
    } 
 
1433
    else if (strcmp(audioType, "offline_nb") == 0) {
 
1434
        self->audio_be_type = PyoOfflineNB;
 
1435
    } 
1390
1436
    else {
1391
1437
        Server_warning(self, "Unknown audio type. Using Portaudio\n");
1392
1438
        self->audio_be_type = PyoPortaudio;
1398
1444
    self->recpath = getenv("HOME");
1399
1445
    if (self->recpath != NULL)
1400
1446
        strncat(self->recpath, "/pyo_rec.wav", strlen("/pyo_rec.wav")); 
 
1447
 
1401
1448
    return 0;
1402
1449
}
1403
1450
 
1404
 
 
1405
1451
static PyObject *
1406
1452
Server_setInputDevice(Server *self, PyObject *arg)
1407
1453
{
1778
1824
                Server_offline_deinit(self);
1779
1825
            }
1780
1826
            break;
 
1827
        case PyoOfflineNB:
 
1828
            audioerr = Server_offline_init(self);
 
1829
            if (audioerr < 0) {
 
1830
                Server_offline_deinit(self);
 
1831
            }
 
1832
            break;
1781
1833
    }
1782
1834
    // Must allocate buffer after initializing the audio backend in case parameters change there
1783
1835
    if (self->input_buffer) {
1820
1872
    }
1821
1873
    int err = -1;
1822
1874
    
 
1875
    Server_debug(self, "Number of streams %d\n", self->stream_count);
 
1876
 
1823
1877
    /* Ensure Python is set up for threading */
1824
1878
    PyEval_InitThreads();
1825
1879
 
1857
1911
        case PyoOffline:
1858
1912
            err = Server_offline_start(self);
1859
1913
            break;           
 
1914
        case PyoOfflineNB:
 
1915
            err = Server_offline_nb_start(self);
 
1916
            break;           
1860
1917
    }
1861
1918
    if (err) {
1862
 
        Server_error(self, "Error starting server.");
 
1919
        Server_error(self, "Error starting server.\n");
1863
1920
    }
1864
1921
 
1865
1922
    Py_INCREF(Py_None);
1892
1949
        case PyoOffline:
1893
1950
            err = Server_offline_stop(self);
1894
1951
            break;    
 
1952
        case PyoOfflineNB:
 
1953
            err = Server_offline_stop(self);
 
1954
            break;    
1895
1955
    }
1896
1956
 
1897
1957
    if (err < 0) {
2011
2071
        return PyInt_FromLong(-1); 
2012
2072
        
2013
2073
    if (tmp == NULL) {
2014
 
        Server_error(self, "Need a pyo object as argument\n");
 
2074
        Server_error(self, "Server_addStream needs a pyo object as argument.\n");
2015
2075
        return PyInt_FromLong(-1);
2016
2076
    }
2017
2077
 
2018
 
    Py_INCREF(tmp);
2019
2078
    PyList_Append(self->streams, tmp);
2020
2079
 
2021
2080
    self->stream_count++;
2037
2096
            Server_debug(self, "Removed stream id %d\n", id);
2038
2097
            PySequence_DelItem(self->streams, i);
2039
2098
            self->stream_count--;
 
2099
            break;
2040
2100
        }
2041
2101
    }
 
2102
 
2042
2103
    Py_INCREF(Py_None);
2043
2104
    return Py_None;    
2044
2105
}
2157
2218
    {"setDuplex", (PyCFunction)Server_setDuplex, METH_O, "Sets the server's duplex mode (0 = only out, 1 = in/out)."},
2158
2219
    {"setGlobalSeed", (PyCFunction)Server_setGlobalSeed, METH_O, "Sets the server's global seed for random objects."},
2159
2220
    {"setAmp", (PyCFunction)Server_setAmp, METH_O, "Sets the overall amplitude."},
2160
 
    {"setAmpCallable", (PyCFunction)Server_setAmpCallable, METH_O, "Sets the Server's GUI object."},
2161
 
    {"setTimeCallable", (PyCFunction)Server_setTimeCallable, METH_O, "Sets the Server's TIME object."},
 
2221
    {"setAmpCallable", (PyCFunction)Server_setAmpCallable, METH_O, "Sets the Server's GUI callable object."},
 
2222
    {"setTimeCallable", (PyCFunction)Server_setTimeCallable, METH_O, "Sets the Server's TIME callable object."},
2162
2223
    {"setVerbosity", (PyCFunction)Server_setVerbosity, METH_O, "Sets the verbosity."},
2163
2224
    {"setStartOffset", (PyCFunction)Server_setStartOffset, METH_O, "Sets starting time offset."},
2164
2225
    {"boot", (PyCFunction)Server_boot, METH_NOARGS, "Setup and boot the server."},