3

私はC++で書かれた小さなオーディオライブラリ用のPython拡張機能を作成中です。オーディオストリームを開くと、コールバック関数がパラメーターとして渡されます(もちろん他のパラメーターの中でも)。わずかに簡略化されたユースケース:

AudioThingy *a = new AudioThingy();
a->openStream(..., callbackFunction);
a->startStream();

私のPython拡張機能は、これをPythonクラス内にラップします。

thingy = AudioThingy()
thingy.openStream(..., pythonCallbackFunction)
thingy.startStream()

現在、拡張機能には、C++ライブラリに渡すC関数としてのコールバックがあります。ストリームティックごとに、コールバックは、ストリーム形式パラメーターに従って正しいデータ型にキャストするオーディオバッファーへのvoidポインターとともに、ストリームに関する情報を受け取ります。もちろん、私の意図は、Cで実装されたこのコールバック関数が、引数としてある種の配列を使用してユーザー指定のPython関数を呼び出すことです。この関数は、たとえばPythonで開かれたwavファイルからのオーディオデータで埋められます。

これは私がコードでやりたいことです:

static int __audiothingy_callback(void *buffer, ...) {
  PyGILState_STATE state = PyGILState_Ensure();
  /*
      cast the void pointer to the correct data type (short, int, long, etc.)
      wrap it for Python somehow
  */
  PyEval_CallObject(the_python_function, arglist);
  PyGILState_Release(state);
  //proceed to fill the buffer with stuff passed back from python
  for (...)
    *casted_buffer++ = ????
  Py_DECREF(arglist);
  return 0;
}

TL; DR:正しいタイプの可変配列をスレッド内のCからPython関数に渡すにはどうすればよいですか?Python関数を使用してオーディオバッファーにデータを入力できますか?多分それは私が上で説明したのとは異なる方法で行うことができますか?すべての入力を歓迎します。

4

1 に答える 1

2

私はあなたがいくつかのことをすることができると思います。Python 2.7を使用している場合は、新しいバッファープロトコルを使用してmemoryviewオブジェクトを作成できます。

次に、バッファからmemoryviewオブジェクトを作成する必要があります。

もう1つの戦略は、配列モジュールをインポートし、これを使用して目的のタイプの配列を作成することです。あなたが使う:

次に、必要なタイプに応じて配列を作成します。

PyObject *array = PyObject_CallFunction(array_type, "c", 'd');   

さらに簡単に、bytearrayオブジェクトを使用することもできます。

  • PyByteArray_FromStringAndSizeは、配列要素のサイズを気にする必要がないように構造化できる場合にバイト配列を作成します。
于 2013-02-23T01:05:03.020 に答える