1647 static PyObject *
1648 pa_open(PyObject *self, PyObject *args, PyObject *kwargs)
1649 {
1650 int rate, channels;
1651 int input, output, frames_per_buffer;
1652 int input_device_index = -1;
1653 int output_device_index = -1;
1654 PyObject *input_device_index_arg = NULL;
1655 PyObject *output_device_index_arg = NULL;
1656 PyObject *stream_callback = NULL;
1657 PaSampleFormat format;
1658 PaError err;
1659 PyObject *input_device_index_long;
1660 PyObject *output_device_index_long;
1661 PaStreamParameters *outputParameters = NULL;
1662 PaStreamParameters *inputParameters = NULL;
1663 PaStream *stream = NULL;
1664 PaStreamInfo *streamInfo = NULL;
1665 PyAudioCallbackContext *context = NULL;
1666 _pyAudio_Stream *streamObject;
1667
1668 /* pass in rate, channel, width */
1669 static char *kwlist[] = {"rate",
1670 "channels",
1671 "format",
1672 "input",
1673 "output",
1674 "input_device_index",
1675 "output_device_index",
1676 "frames_per_buffer",
1677 "input_host_api_specific_stream_info",
1678 "output_host_api_specific_stream_info",
1679 "stream_callback",
1680 NULL};
1681
1682 #ifdef MACOSX
1683 _pyAudio_MacOSX_hostApiSpecificStreamInfo *inputHostSpecificStreamInfo =
1684 NULL;
1685 _pyAudio_MacOSX_hostApiSpecificStreamInfo *outputHostSpecificStreamInfo =
1686 NULL;
1687 #else
1688 /* mostly ignored...*/
1689 PyObject *inputHostSpecificStreamInfo = NULL;
1690 PyObject *outputHostSpecificStreamInfo = NULL;
1691 #endif
1692
1693 /* default to neither output nor input */
1694 input = 0;
1695 output = 0;
1696 frames_per_buffer = DEFAULT_FRAMES_PER_BUFFER;
1697
1698 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
when PyArg_ParseTupleAndKeywords() succeeds
taking False path
1699 #ifdef MACOSX
1700 "iik|iiOOiO!O!O",
1701 #else
1702 "iik|iiOOiOOO",
1703 #endif
1704 kwlist,
1705 &rate, &channels, &format,
1706 &input, &output,
1707 &input_device_index_arg,
1708 &output_device_index_arg,
1709 &frames_per_buffer,
1710 #ifdef MACOSX
1711 &_pyAudio_MacOSX_hostApiSpecificStreamInfoType,
1712 #endif
1713 &inputHostSpecificStreamInfo,
1714 #ifdef MACOSX
1715 &_pyAudio_MacOSX_hostApiSpecificStreamInfoType,
1716 #endif
1717 &outputHostSpecificStreamInfo,
1718 &stream_callback))
1719
1720 return NULL;
1721
1722 if (stream_callback && (PyCallable_Check(stream_callback) == 0)) {
taking True path
when PyCallable_Check() returns 1 (true)
taking False path
1723 PyErr_SetString(PyExc_TypeError, "stream_callback must be callable");
1724 return NULL;
1725 }
1726
1727 /* check to see if device indices were specified */
1728 if ((input_device_index_arg == NULL) ||
taking False path
taking False path
1729 (input_device_index_arg == Py_None)) {
1730
1731 #ifdef VERBOSE
1732 printf("Using default input device\n");
1733 #endif
1734
1735 input_device_index = -1;
1736
1737 } else {
1738 // Support both Python 2 and Python 3 by using PyNumber_Check
1739 if (!PyNumber_Check(input_device_index_arg)) {
when considering range: -0x80000000 <= value <= -1
taking False path
1740 PyErr_SetString(PyExc_ValueError,
1741 "input_device_index must be integer (or None)");
1742 return NULL;
1743 }
1744
1745 input_device_index_long =
when PyNumber_Long() succeeds
1746 PyNumber_Long(input_device_index_arg);
1747
1748 input_device_index = (int) PyLong_AsLong(input_device_index_long);
1749 Py_DECREF(input_device_index_long);
when taking True path
1750
1751 #ifdef VERBOSE
1752 printf("Using input device index number: %d\n", input_device_index);
1753 #endif
1754 }
1755
1756 if ((output_device_index_arg == NULL) ||
taking False path
taking False path
1757 (output_device_index_arg == Py_None)) {
1758
1759 #ifdef VERBOSE
1760 printf("Using default output device\n");
1761 #endif
1762
1763 output_device_index = -1;
1764
1765 } else {
1766 // Support both Python 2 and Python 3 by using PyNumber_Check
1767 if (!PyNumber_Check(output_device_index_arg)) {
when considering range: -0x80000000 <= value <= -1
taking False path
1768 PyErr_SetString(PyExc_ValueError,
1769 "output_device_index must be integer (or None)");
1770 return NULL;
1771 }
1772
1773 output_device_index_long =
when PyNumber_Long() succeeds
1774 PyNumber_Long(output_device_index_arg);
1775 output_device_index = (int) PyLong_AsLong(output_device_index_long);
1776 Py_DECREF(output_device_index_long);
when taking True path
1777
1778 #ifdef VERBOSE
1779 printf("Using output device index number: %d\n", output_device_index);
1780 #endif
1781 }
1782
1783 /* sanity checks */
1784 if (input == 0 && output == 0) {
when considering range: -0x80000000 <= value <= -1
taking False path
1785 PyErr_SetString(PyExc_ValueError, "Must specify either input or output");
1786 return NULL;
1787 }
1788
1789 if (channels < 1) {
when considering range: 1 <= value <= 0x7fffffff
taking False path
1790 PyErr_SetString(PyExc_ValueError, "Invalid audio channels");
1791 return NULL;
1792 }
1793
1794 if (output) {
when considering range: -0x80000000 <= value <= -1
taking True path
1795 outputParameters =
1796 (PaStreamParameters *) malloc(sizeof(PaStreamParameters));
1797
1798
1799 if (output_device_index < 0)
when considering range: -0x8000000000000000 <= value <= -1
taking True path
1800 /* default output device */
1801 outputParameters->device = Pa_GetDefaultOutputDevice();
when treating unknown void * from src/_portaudiomodule.c:1795 as non-NULL
1802 else
1803 outputParameters->device = output_device_index;
1804
1805 /* final check -- ensure that there is a default device */
1806 if (outputParameters->device < 0 ||
when considering range: 0 <= value <= 0x7fffffff
taking False path
when taking False path
1807 outputParameters->device >= Pa_GetDeviceCount()) {
1808 free(outputParameters);
1809 PyErr_SetObject(PyExc_IOError,
1810 Py_BuildValue("(s,i)",
1811 "Invalid output device "
1812 "(no default output device)",
1813 paInvalidDevice));
1814 return NULL;
1815 }
1816
1817 outputParameters->channelCount = channels;
1818 outputParameters->sampleFormat = format;
1819 outputParameters->suggestedLatency =
1820 Pa_GetDeviceInfo(outputParameters->device)->defaultLowOutputLatency;
when treating unknown const struct PaDeviceInfo * from src/_portaudiomodule.c:1820 as non-NULL
1821 outputParameters->hostApiSpecificStreamInfo = NULL;
1822
1823 #ifdef MACOSX
1824 if (outputHostSpecificStreamInfo) {
1825 outputParameters->hostApiSpecificStreamInfo =
1826 outputHostSpecificStreamInfo->paMacCoreStreamInfo;
1827 }
1828 #endif
1829
1830 }
1831
1832 if (input) {
taking True path
1833 inputParameters =
1834 (PaStreamParameters *) malloc(sizeof(PaStreamParameters));
1835
1836 if (input_device_index < 0) {
when considering range: -0x8000000000000000 <= value <= -1
taking True path
1837 /* default output device */
1838 inputParameters->device = Pa_GetDefaultInputDevice();
when treating unknown void * from src/_portaudiomodule.c:1833 as non-NULL
1839 } else {
1840 inputParameters->device = input_device_index;
1841 }
1842
1843 /* final check -- ensure that there is a default device */
1844 if (inputParameters->device < 0) {
when considering range: -0x80000000 <= value <= -1
taking True path
1845 free(inputParameters);
1846 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
1847 Py_BuildValue("(s,i)",
1848 "Invalid input device "
1849 "(no default output device)",
1850 paInvalidDevice));
1851 return NULL;
1852 }
1853
1854 inputParameters->channelCount = channels;
1855 inputParameters->sampleFormat = format;
1856 inputParameters->suggestedLatency =
1857 Pa_GetDeviceInfo(inputParameters->device)->defaultLowInputLatency;
1858 inputParameters->hostApiSpecificStreamInfo = NULL;
1859
1860 #ifdef MACOSX
1861 if (inputHostSpecificStreamInfo) {
1862 inputParameters->hostApiSpecificStreamInfo =
1863 inputHostSpecificStreamInfo->paMacCoreStreamInfo;
1864 }
1865 #endif
1866
1867 }
1868
1869 // Handle callback mode:
1870 if (stream_callback) {
1871 Py_INCREF(stream_callback);
1872 context = (PyAudioCallbackContext *) malloc(sizeof(PyAudioCallbackContext));
1873 context->callback = (PyObject *) stream_callback;
1874 context->main_thread_id = PyThreadState_Get()->thread_id;
1875 context->frame_size = Pa_GetSampleSize(format) * channels;
1876 }
1877
1878 err = Pa_OpenStream(&stream,
1879 /* input/output parameters */
1880 /* NULL values are ignored */
1881 inputParameters,
1882 outputParameters,
1883 /* Samples Per Second */
1884 rate,
1885 /* allocate frames in the buffer */
1886 frames_per_buffer,
1887 /* we won't output out of range samples
1888 so don't bother clipping them */
1889 paClipOff,
1890 /* callback, if specified */
1891 (stream_callback)?(_stream_callback_cfunction):(NULL),
1892 /* callback userData, if applicable */
1893 context);
1894
1895 if (err != paNoError) {
1896
1897 #ifdef VERBOSE
1898 fprintf(stderr, "An error occured while using the portaudio stream\n");
1899 fprintf(stderr, "Error number: %d\n", err);
1900 fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
1901 #endif
1902
1903 PyErr_SetObject(PyExc_IOError,
1904 Py_BuildValue("(s,i)",
1905 Pa_GetErrorText(err), err));
1906 return NULL;
1907 }
1908
1909 streamInfo = (PaStreamInfo *) Pa_GetStreamInfo(stream);
1910 if (!streamInfo) {
1911 /* Pa_Terminate(); */
1912 PyErr_SetObject(PyExc_IOError,
1913 Py_BuildValue("(s,i)",
1914 "Could not get stream information",
1915 paInternalError));
1916 return NULL;
1917 }
1918
1919 streamObject = _create_Stream_object();
1920 streamObject->stream = stream;
1921 streamObject->inputParameters = inputParameters;
1922 streamObject->outputParameters = outputParameters;
1923 streamObject->is_open = 1;
1924 streamObject->streamInfo = streamInfo;
1925 streamObject->callbackContext = context;
1926
1927 return (PyObject *) streamObject;
1928 }