2336 static PyObject *
2337 pa_write_stream(PyObject *self, PyObject *args)
2338 {
2339 const char *data;
2340 int total_size;
2341 int total_frames;
2342 int err;
2343 int should_throw_exception = 0;
2344
2345 PyObject *stream_arg;
2346 _pyAudio_Stream *streamObject;
2347 PaStream *stream;
2348
2349 if (!PyArg_ParseTuple(args, "O!s#i|i",
when PyArg_ParseTuple() succeeds
taking False path
2350 &_pyAudio_StreamType,
2351 &stream_arg,
2352 &data,
2353 &total_size,
2354 &total_frames,
2355 &should_throw_exception))
2356 return NULL;
2357
2358 /* make sure total frames is larger than 0 */
2359 if (total_frames < 0) {
when considering range: 0 <= value <= 0x7fffffff
taking False path
2360 PyErr_SetString(PyExc_ValueError,
2361 "Invalid number of frames");
2362 return NULL;
2363 }
2364
2365 streamObject = (_pyAudio_Stream *) stream_arg;
2366
2367 if (!_is_open(streamObject)) {
when considering range: 1 <= value <= 0x7fffffff
taking False path
2368 PyErr_SetObject(PyExc_IOError,
2369 Py_BuildValue("(s,i)",
2370 "Stream closed",
2371 paBadStreamPtr));
2372 return NULL;
2373 }
2374
2375 stream = streamObject->stream;
2376
2377 Py_BEGIN_ALLOW_THREADS
releasing the GIL by calling PyEval_SaveThread()
2378 err = Pa_WriteStream(stream, data, total_frames);
2379 Py_END_ALLOW_THREADS
reacquiring the GIL by calling PyEval_RestoreThread()
2380
2381 if (err != paNoError) {
when considering range: -0x80000000 <= value <= -1
taking True path
2382 if (err == paOutputUnderflowed) {
when considering range: -0x80000000 <= value <= -9981
taking False path
2383 if (should_throw_exception)
2384 goto error;
2385 } else
2386 goto error;
2387 }
2388
2389 Py_INCREF(Py_None);
2390 return Py_None;
2391
2392 error:
2393 /* cleanup */
2394 _cleanup_Stream_object(streamObject);
2395
2396 #ifdef VERBOSE
2397 fprintf(stderr, "An error occured while using the portaudio stream\n");
2398 fprintf(stderr, "Error number: %d\n", err);
2399 fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
2400 #endif
2401
2402 PyErr_SetObject(PyExc_IOError,
when Py_BuildValue() succeeds
calling PyErr_SetObject()
new ref from call to Py_BuildValue was allocated at: PyErr_SetObject(PyExc_IOError,
ob_refcnt is now refs: 1 owned
ob_refcnt is now refs: 1 owned, 1 borrowed
2403 Py_BuildValue("(s,i)",
2404 Pa_GetErrorText(err),
2405 err));
2406 return NULL;
2407 }