int PlayerObject::setPlaying(bool playing) { PlayerObject* player = this; bool oldplayingstate = false; PyScopedGIL gil; { PyScopedGIUnlock gunlock; player->workerThread.start(); // if not running yet, start if(!player->outStream.get()) player->outStream.reset(new OutStream(this)); assert(player->outStream.get() != NULL); if(soundcardOutputEnabled) { if(playing && !player->outStream->stream) { if(!player->outStream->open()) playing = false; } } oldplayingstate = player->playing; if(soundcardOutputEnabled && player->outStream.get() && player->outStream->isOpen() && oldplayingstate != playing) fader.init(playing ? 1 : -1, outSamplerate); player->playing = playing; } if(!PyErr_Occurred() && player->dict) { Py_INCREF(player->dict); PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange"); if(onPlayingStateChange && onPlayingStateChange != Py_None) { Py_INCREF(onPlayingStateChange); PyObject* kwargs = PyDict_New(); assert(kwargs); PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate)); PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing)); PyObject* retObj = PyEval_CallObjectWithKeywords(onPlayingStateChange, NULL, kwargs); Py_XDECREF(retObj); // errors are not fatal from the callback, so handle it now and go on if(PyErr_Occurred()) PyErr_Print(); Py_DECREF(kwargs); Py_DECREF(onPlayingStateChange); } Py_DECREF(player->dict); } return PyErr_Occurred() ? -1 : 0; }
int PlayerObject::setPlaying(bool playing) { PlayerObject* player = this; bool oldplayingstate = false; PyScopedGIL gil; { PyScopedGIUnlock gunlock; player->workerThread.start(); // if not running yet, start if(!player->outStream.get()) player->outStream.reset(new OutStream(this)); assert(player->outStream.get() != NULL); if(playing && !player->outStream->stream) { PaError ret; ret = Pa_OpenDefaultStream( &player->outStream->stream, 0, player->outNumChannels, // numOutputChannels paInt16, // sampleFormat player->outSamplerate, // sampleRate AUDIO_BUFFER_SIZE / 2, // framesPerBuffer, &paStreamCallback, player //void *userData ); if(ret != paNoError) { PyErr_SetString(PyExc_RuntimeError, "Pa_OpenDefaultStream failed"); if(player->outStream->stream) player->outStream->close(); playing = 0; } } if(playing) { player->needRealtimeReset = 1; Pa_StartStream(player->outStream->stream); } else player->outStream->stop(); oldplayingstate = player->playing; player->playing = playing; } if(!PyErr_Occurred() && player->dict) { Py_INCREF(player->dict); PyObject* onPlayingStateChange = PyDict_GetItemString(player->dict, "onPlayingStateChange"); if(onPlayingStateChange && onPlayingStateChange != Py_None) { Py_INCREF(onPlayingStateChange); PyObject* kwargs = PyDict_New(); assert(kwargs); PyDict_SetItemString_retain(kwargs, "oldState", PyBool_FromLong(oldplayingstate)); PyDict_SetItemString_retain(kwargs, "newState", PyBool_FromLong(playing)); PyObject* retObj = PyEval_CallObjectWithKeywords(onPlayingStateChange, NULL, kwargs); Py_XDECREF(retObj); // errors are not fatal from the callback, so handle it now and go on if(PyErr_Occurred()) PyErr_Print(); Py_DECREF(kwargs); Py_DECREF(onPlayingStateChange); } Py_DECREF(player->dict); } return PyErr_Occurred() ? -1 : 0; }