|
@@ -0,0 +1,627 @@
|
|
|
+{
|
|
|
+ "cells": [
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 1,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "import queue\n",
|
|
|
+ "import sys\n",
|
|
|
+ "\n",
|
|
|
+ "import sounddevice as sd\n",
|
|
|
+ "import soundfile as sf\n",
|
|
|
+ "import numpy # Make sure NumPy is loaded before it is used in the callback\n",
|
|
|
+ "assert numpy # avoid \"imported but unused\" message (W0611)\n",
|
|
|
+ "\n",
|
|
|
+ "from situtils import FPSTimes\n",
|
|
|
+ "\n",
|
|
|
+ "import threading\n",
|
|
|
+ "\n",
|
|
|
+ "import time"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "## Class method version"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 1,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Overwriting microphones.py\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "%%writefile microphones.py \n",
|
|
|
+ "#^IMPORTANT: essential to make multiprocessing work\n",
|
|
|
+ "\n",
|
|
|
+ "import queue\n",
|
|
|
+ "import sys\n",
|
|
|
+ "\n",
|
|
|
+ "import sounddevice as sd\n",
|
|
|
+ "import soundfile as sf\n",
|
|
|
+ "import numpy # Make sure NumPy is loaded before it is used in the callback\n",
|
|
|
+ "assert numpy # avoid \"imported but unused\" message (W0611)\n",
|
|
|
+ "\n",
|
|
|
+ "from situtils import FPSTimes\n",
|
|
|
+ "\n",
|
|
|
+ "import time\n",
|
|
|
+ "\n",
|
|
|
+ "class MicrophoneController(FPSTimes):\n",
|
|
|
+ " # https://python-sounddevice.readthedocs.io/en/0.3.15/examples.html#recording-with-arbitrary-duration\n",
|
|
|
+ " \n",
|
|
|
+ " @staticmethod\n",
|
|
|
+ " def callback(indata, frames, time, status):\n",
|
|
|
+ " \"\"\"This is called (from a separate thread) for each audio block.\"\"\"\n",
|
|
|
+ " if status:\n",
|
|
|
+ " print(status, file=sys.stderr)\n",
|
|
|
+ " MicrophoneController.queue.put(indata.copy())\n",
|
|
|
+ " \n",
|
|
|
+ " \n",
|
|
|
+ " @classmethod\n",
|
|
|
+ " def run(cls, status, cfg):\n",
|
|
|
+ " # MicrophoneController.initialize(cfg)\n",
|
|
|
+ " print(\"Running.\")\n",
|
|
|
+ " import sounddevice as sd # must be inside the function\n",
|
|
|
+ " \n",
|
|
|
+ " if cfg['channel_selectors']: # make it work without ASIO\n",
|
|
|
+ " # https://python-sounddevice.readthedocs.io/en/0.3.15/api/platform-specific-settings.html\n",
|
|
|
+ " asio_in = sd.AsioSettings(channel_selectors=cfg['channel_selectors'])\n",
|
|
|
+ " else:\n",
|
|
|
+ " asio_in = None\n",
|
|
|
+ "\n",
|
|
|
+ " MicrophoneController.queue = queue.Queue() # kind of a hack\n",
|
|
|
+ "\n",
|
|
|
+ " stream = sd.InputStream(samplerate=cfg['sample_rate'], device=cfg['device'], channels=cfg['number_channels'], callback=MicrophoneController.callback, extra_settings = asio_in)\n",
|
|
|
+ " \n",
|
|
|
+ " filename = cfg['file_path']\n",
|
|
|
+ " file = sf.SoundFile(filename, mode='w', samplerate=cfg['sample_rate'], channels=cfg['number_channels'],subtype='PCM_32') # 'w': overwrite mode, 'x': raises error if file exists\n",
|
|
|
+ "\n",
|
|
|
+ " # experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ " with file as f:\n",
|
|
|
+ " while status.value > 0:\n",
|
|
|
+ " try:\n",
|
|
|
+ " if status.value == 2:\n",
|
|
|
+ "\n",
|
|
|
+ " # start stream if not active yet\n",
|
|
|
+ " if not stream.active:\n",
|
|
|
+ " print(\"Audio input stream started.\")\n",
|
|
|
+ " t0 = time.time()\n",
|
|
|
+ " stream.start()\n",
|
|
|
+ " with open(cfg['csv_path'], 'a') as f:\n",
|
|
|
+ " f.write(\",\".join([str(x) for x in (t0,)]) + \"\\n\")\n",
|
|
|
+ "\n",
|
|
|
+ " f.write(MicrophoneController.queue.get())\n",
|
|
|
+ "\n",
|
|
|
+ " else:\n",
|
|
|
+ " time.sleep(0.005)\n",
|
|
|
+ " except KeyboardInterrupt:\n",
|
|
|
+ " stream.stop()\n",
|
|
|
+ " stream.close()\n",
|
|
|
+ " break\n",
|
|
|
+ " "
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "## Instance version"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 22,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Writing microphones_instance.py\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "%%writefile microphones_instance.py \n",
|
|
|
+ "#^IMPORTANT: essential to make multiprocessing work\n",
|
|
|
+ "\n",
|
|
|
+ "import queue\n",
|
|
|
+ "import sys\n",
|
|
|
+ "\n",
|
|
|
+ "import sounddevice as sd\n",
|
|
|
+ "import soundfile as sf\n",
|
|
|
+ "import numpy # Make sure NumPy is loaded before it is used in the callback\n",
|
|
|
+ "assert numpy # avoid \"imported but unused\" message (W0611)\n",
|
|
|
+ "\n",
|
|
|
+ "from situtils import FPSTimes\n",
|
|
|
+ "\n",
|
|
|
+ "import time\n",
|
|
|
+ "\n",
|
|
|
+ "import threading\n",
|
|
|
+ "\n",
|
|
|
+ "class MicrophoneControllerInstance(FPSTimes):\n",
|
|
|
+ " # https://python-sounddevice.readthedocs.io/en/0.3.15/examples.html#recording-with-arbitrary-duration\n",
|
|
|
+ " def __init__(self, status, cfg):\n",
|
|
|
+ " import sounddevice as sd # must be inside the function? TODO\n",
|
|
|
+ " self.cfg = cfg\n",
|
|
|
+ " self.samplerate = cfg['sample_rate']\n",
|
|
|
+ " self.device = cfg['device']\n",
|
|
|
+ " self.channels = cfg['number_channels']\n",
|
|
|
+ " self.status = status\n",
|
|
|
+ " \n",
|
|
|
+ " if cfg['channel_selectors']: # make it work without ASIO\n",
|
|
|
+ " # https://python-sounddevice.readthedocs.io/en/0.3.15/api/platform-specific-settings.html\n",
|
|
|
+ " self.channel_selectors = cfg['channel_selectors']\n",
|
|
|
+ " asio_in = sd.AsioSettings(channel_selectors=self.channel_selectors)\n",
|
|
|
+ " else:\n",
|
|
|
+ " asio_in = None\n",
|
|
|
+ "\n",
|
|
|
+ " MicrophoneControllerInstance.queue = queue.Queue() # kind of a hack\n",
|
|
|
+ " \n",
|
|
|
+ " self.stream = sd.InputStream(samplerate=self.samplerate, device=self.device, channels=self.channels, callback=self.callback, extra_settings = asio_in)\n",
|
|
|
+ "\n",
|
|
|
+ " self.filename = cfg['file_path']\n",
|
|
|
+ " self.file = sf.SoundFile(self.filename, mode='w', samplerate=self.samplerate, channels=self.channels) # 'w': overwrite mode, 'x': raises error if file exists\n",
|
|
|
+ " \n",
|
|
|
+ " \n",
|
|
|
+ " def start(self):\n",
|
|
|
+ " self._th = threading.Thread(target=self.run, args=())\n",
|
|
|
+ " self._th.start()\n",
|
|
|
+ "\n",
|
|
|
+ " def stop(self):\n",
|
|
|
+ " time.sleep(0.2) # wait until device is released\n",
|
|
|
+ " self._th.join()\n",
|
|
|
+ " print('Microphones recording stopped')\n",
|
|
|
+ "\n",
|
|
|
+ " def start_stream(self):\n",
|
|
|
+ " self.stream.start()\n",
|
|
|
+ "\n",
|
|
|
+ " def stop_stream(self):\n",
|
|
|
+ " self.stream.stop()\n",
|
|
|
+ " self.stream.close()\n",
|
|
|
+ "\n",
|
|
|
+ " # Used in all versions\n",
|
|
|
+ " @staticmethod\n",
|
|
|
+ " def callback(indata, frames, time, status):\n",
|
|
|
+ " \"\"\"This is called (from a separate thread) for each audio block.\"\"\"\n",
|
|
|
+ " if status:\n",
|
|
|
+ " print(status, file=sys.stderr)\n",
|
|
|
+ " MicrophoneControllerInstance.queue.put(indata.copy())\n",
|
|
|
+ " \n",
|
|
|
+ " # instance method\n",
|
|
|
+ " def run(self):\n",
|
|
|
+ " import sounddevice as sd # must be inside the function? TODO\n",
|
|
|
+ " # experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ " with self.file as file:\n",
|
|
|
+ " while self.status.value > 0:\n",
|
|
|
+ " if self.status.value == 2:\n",
|
|
|
+ " \n",
|
|
|
+ " # start stream if not active yet\n",
|
|
|
+ " if not self.stream.active:\n",
|
|
|
+ " print(\"Audio input stream started.\")\n",
|
|
|
+ " self.stream.start()\n",
|
|
|
+ " \n",
|
|
|
+ " file.write(MicrophoneControllerInstance.queue.get())\n",
|
|
|
+ " \n",
|
|
|
+ " self.stop_stream()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "## Test microphones"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "attachments": {},
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "Import config file"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 47,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "text/plain": [
|
|
|
+ "{'record_audio': True,\n",
|
|
|
+ " 'sample_rate': 44000,\n",
|
|
|
+ " 'device': 1,\n",
|
|
|
+ " 'number_channels': 2,\n",
|
|
|
+ " 'channel_selectors': False,\n",
|
|
|
+ " 'file_path': 'audio_new.mat5'}"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "execution_count": 47,
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "execute_result"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "import json\n",
|
|
|
+ "import os\n",
|
|
|
+ "import multiprocess as mp\n",
|
|
|
+ "\n",
|
|
|
+ "# cfg_filename = os.path.join('..','profiles', 'miguel_socialSIT_test.json')\n",
|
|
|
+ "cfg_filename = os.path.join('..','profiles', 'miguel_socialSIT_test_lord_sith.json')\n",
|
|
|
+ "with open(cfg_filename) as json_file:\n",
|
|
|
+ " cfg = json.load(json_file)\n",
|
|
|
+ "\n",
|
|
|
+ "cfg[\"microphones\"]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "### Test version using instance methods and no parallelization -> Works!"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 9,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Recording started\n",
|
|
|
+ "Audio input stream started.\n",
|
|
|
+ "Recording stopped\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ "status = mp.Value('i', 1)\n",
|
|
|
+ "\n",
|
|
|
+ "mc = MicrophoneControllerInstance(status, cfg[\"microphones\"])\n",
|
|
|
+ "try:\n",
|
|
|
+ " status.value = 2\n",
|
|
|
+ " print(\"Recording started\")\n",
|
|
|
+ " mc.run()\n",
|
|
|
+ "except KeyboardInterrupt:\n",
|
|
|
+ " status.value = 0\n",
|
|
|
+ " mc.stop_stream()\n",
|
|
|
+ " print(\"Recording stopped\")\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "### Test with class method instead of instance method -> Works!"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 22,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Running.\n",
|
|
|
+ "Audio input stream started.\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "ename": "TypeError",
|
|
|
+ "evalue": "write() argument must be str, not numpy.ndarray",
|
|
|
+ "output_type": "error",
|
|
|
+ "traceback": [
|
|
|
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
|
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
|
|
|
+ "Cell \u001b[1;32mIn[22], line 4\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[39m# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\u001b[39;00m\n\u001b[0;32m 3\u001b[0m status \u001b[39m=\u001b[39m mp\u001b[39m.\u001b[39mValue(\u001b[39m'\u001b[39m\u001b[39mi\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m2\u001b[39m)\n\u001b[1;32m----> 4\u001b[0m MicrophoneController\u001b[39m.\u001b[39;49mrun(status,cfg[\u001b[39m\"\u001b[39;49m\u001b[39mmicrophones\u001b[39;49m\u001b[39m\"\u001b[39;49m])\n\u001b[0;32m 5\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mRecording stopped\u001b[39m\u001b[39m\"\u001b[39m)\n",
|
|
|
+ "File \u001b[1;32mn:\\Miguel\\runSIT\\controllers\\microphones.py:77\u001b[0m, in \u001b[0;36mMicrophoneController.run\u001b[1;34m(cls, status, cfg)\u001b[0m\n\u001b[0;32m 75\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mAudio input stream started.\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 76\u001b[0m stream\u001b[39m.\u001b[39mstart()\n\u001b[1;32m---> 77\u001b[0m \u001b[39mprint\u001b[39m(MicrophoneController\u001b[39m.\u001b[39mqueue\u001b[39m.\u001b[39mget())\n\u001b[0;32m 79\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 80\u001b[0m time\u001b[39m.\u001b[39msleep(\u001b[39m0.01\u001b[39m)\n",
|
|
|
+ "\u001b[1;31mTypeError\u001b[0m: write() argument must be str, not numpy.ndarray"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "from microphones import MicrophoneController\n",
|
|
|
+ "# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ "status = mp.Value('i', 2)\n",
|
|
|
+ "MicrophoneController.run(status,cfg[\"microphones\"])\n",
|
|
|
+ "print(\"Recording stopped\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "attachments": {},
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "### Test with multiprocessing using class method -> Works!"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 83,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "from microphones import MicrophoneController # IMPORTANT: class must be imported from separate .py file, not from the notebook\n",
|
|
|
+ "\n",
|
|
|
+ "# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ "status = mp.Value('i', 1)\n",
|
|
|
+ "\n",
|
|
|
+ "mc = mp.Process(target=MicrophoneController.run, args=(status,cfg[\"microphones\"]))\n",
|
|
|
+ "mc.start()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 84,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "text/plain": [
|
|
|
+ "<Process name='Process-12' pid=11076 parent=11092 started>"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "execution_count": 84,
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "execute_result"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "mc"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 85,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Recording started\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "status.value = 2\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Recording started\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 86,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "status.value = 0\n",
|
|
|
+ "\n",
|
|
|
+ "mc.join()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "### Test with multiprocessing using instance method -> Error!"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 23,
|
|
|
+ "metadata": {
|
|
|
+ "scrolled": true
|
|
|
+ },
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "ename": "TypeError",
|
|
|
+ "evalue": "cannot pickle '_cffi_backend.__CDataOwnGC' object",
|
|
|
+ "output_type": "error",
|
|
|
+ "traceback": [
|
|
|
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
|
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
|
|
|
+ "Cell \u001b[1;32mIn[23], line 9\u001b[0m\n\u001b[0;32m 6\u001b[0m microphoneController \u001b[39m=\u001b[39m MicrophoneControllerInstance(status, cfg[\u001b[39m\"\u001b[39m\u001b[39mmicrophones\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m 8\u001b[0m mc \u001b[39m=\u001b[39m mp\u001b[39m.\u001b[39mProcess(target\u001b[39m=\u001b[39mmicrophoneController\u001b[39m.\u001b[39mrun, args\u001b[39m=\u001b[39m())\n\u001b[1;32m----> 9\u001b[0m mc\u001b[39m.\u001b[39;49mstart()\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\multiprocess\\process.py:121\u001b[0m, in \u001b[0;36mBaseProcess.start\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 118\u001b[0m \u001b[39massert\u001b[39;00m \u001b[39mnot\u001b[39;00m _current_process\u001b[39m.\u001b[39m_config\u001b[39m.\u001b[39mget(\u001b[39m'\u001b[39m\u001b[39mdaemon\u001b[39m\u001b[39m'\u001b[39m), \\\n\u001b[0;32m 119\u001b[0m \u001b[39m'\u001b[39m\u001b[39mdaemonic processes are not allowed to have children\u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m 120\u001b[0m _cleanup()\n\u001b[1;32m--> 121\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_popen \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_Popen(\u001b[39mself\u001b[39;49m)\n\u001b[0;32m 122\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sentinel \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_popen\u001b[39m.\u001b[39msentinel\n\u001b[0;32m 123\u001b[0m \u001b[39m# Avoid a refcycle if the target function holds an indirect\u001b[39;00m\n\u001b[0;32m 124\u001b[0m \u001b[39m# reference to the process object (see bpo-30775)\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\multiprocess\\context.py:224\u001b[0m, in \u001b[0;36mProcess._Popen\u001b[1;34m(process_obj)\u001b[0m\n\u001b[0;32m 222\u001b[0m \u001b[39m@staticmethod\u001b[39m\n\u001b[0;32m 223\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_Popen\u001b[39m(process_obj):\n\u001b[1;32m--> 224\u001b[0m \u001b[39mreturn\u001b[39;00m _default_context\u001b[39m.\u001b[39;49mget_context()\u001b[39m.\u001b[39;49mProcess\u001b[39m.\u001b[39;49m_Popen(process_obj)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\multiprocess\\context.py:336\u001b[0m, in \u001b[0;36mSpawnProcess._Popen\u001b[1;34m(process_obj)\u001b[0m\n\u001b[0;32m 333\u001b[0m \u001b[39m@staticmethod\u001b[39m\n\u001b[0;32m 334\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_Popen\u001b[39m(process_obj):\n\u001b[0;32m 335\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39m.\u001b[39;00m\u001b[39mpopen_spawn_win32\u001b[39;00m \u001b[39mimport\u001b[39;00m Popen\n\u001b[1;32m--> 336\u001b[0m \u001b[39mreturn\u001b[39;00m Popen(process_obj)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\multiprocess\\popen_spawn_win32.py:93\u001b[0m, in \u001b[0;36mPopen.__init__\u001b[1;34m(self, process_obj)\u001b[0m\n\u001b[0;32m 91\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m 92\u001b[0m reduction\u001b[39m.\u001b[39mdump(prep_data, to_child)\n\u001b[1;32m---> 93\u001b[0m reduction\u001b[39m.\u001b[39;49mdump(process_obj, to_child)\n\u001b[0;32m 94\u001b[0m \u001b[39mfinally\u001b[39;00m:\n\u001b[0;32m 95\u001b[0m set_spawning_popen(\u001b[39mNone\u001b[39;00m)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\multiprocess\\reduction.py:63\u001b[0m, in \u001b[0;36mdump\u001b[1;34m(obj, file, protocol, *args, **kwds)\u001b[0m\n\u001b[0;32m 61\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdump\u001b[39m(obj, file, protocol\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwds):\n\u001b[0;32m 62\u001b[0m \u001b[39m \u001b[39m\u001b[39m'''Replacement for pickle.dump() using ForkingPickler.'''\u001b[39;00m\n\u001b[1;32m---> 63\u001b[0m ForkingPickler(file, protocol, \u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\u001b[39m.\u001b[39;49mdump(obj)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:394\u001b[0m, in \u001b[0;36mPickler.dump\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 392\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdump\u001b[39m(\u001b[39mself\u001b[39m, obj): \u001b[39m#NOTE: if settings change, need to update attributes\u001b[39;00m\n\u001b[0;32m 393\u001b[0m logger\u001b[39m.\u001b[39mtrace_setup(\u001b[39mself\u001b[39m)\n\u001b[1;32m--> 394\u001b[0m StockPickler\u001b[39m.\u001b[39;49mdump(\u001b[39mself\u001b[39;49m, obj)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:487\u001b[0m, in \u001b[0;36m_Pickler.dump\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 485\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproto \u001b[39m>\u001b[39m\u001b[39m=\u001b[39m \u001b[39m4\u001b[39m:\n\u001b[0;32m 486\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mframer\u001b[39m.\u001b[39mstart_framing()\n\u001b[1;32m--> 487\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msave(obj)\n\u001b[0;32m 488\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwrite(STOP)\n\u001b[0;32m 489\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mframer\u001b[39m.\u001b[39mend_framing()\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:603\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 599\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(\u001b[39m\"\u001b[39m\u001b[39mTuple returned by \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m must have \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 600\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mtwo to six elements\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m reduce)\n\u001b[0;32m 602\u001b[0m \u001b[39m# Save the reduce() output and finally memoize the object\u001b[39;00m\n\u001b[1;32m--> 603\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msave_reduce(obj\u001b[39m=\u001b[39;49mobj, \u001b[39m*\u001b[39;49mrv)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:717\u001b[0m, in \u001b[0;36m_Pickler.save_reduce\u001b[1;34m(self, func, args, state, listitems, dictitems, state_setter, obj)\u001b[0m\n\u001b[0;32m 715\u001b[0m \u001b[39mif\u001b[39;00m state \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 716\u001b[0m \u001b[39mif\u001b[39;00m state_setter \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 717\u001b[0m save(state)\n\u001b[0;32m 718\u001b[0m write(BUILD)\n\u001b[0;32m 719\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[39m# If a state_setter is specified, call it instead of load_build\u001b[39;00m\n\u001b[0;32m 721\u001b[0m \u001b[39m# to update obj's with its previous state.\u001b[39;00m\n\u001b[0;32m 722\u001b[0m \u001b[39m# First, push state_setter and its tuple of expected arguments\u001b[39;00m\n\u001b[0;32m 723\u001b[0m \u001b[39m# (obj, state) onto the stack.\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:560\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 558\u001b[0m f \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdispatch\u001b[39m.\u001b[39mget(t)\n\u001b[0;32m 559\u001b[0m \u001b[39mif\u001b[39;00m f \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 560\u001b[0m f(\u001b[39mself\u001b[39;49m, obj) \u001b[39m# Call unbound method with explicit self\u001b[39;00m\n\u001b[0;32m 561\u001b[0m \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m 563\u001b[0m \u001b[39m# Check private dispatch table if any, or else\u001b[39;00m\n\u001b[0;32m 564\u001b[0m \u001b[39m# copyreg.dispatch_table\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:1186\u001b[0m, in \u001b[0;36msave_module_dict\u001b[1;34m(pickler, obj)\u001b[0m\n\u001b[0;32m 1183\u001b[0m \u001b[39mif\u001b[39;00m is_dill(pickler, child\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m) \u001b[39mand\u001b[39;00m pickler\u001b[39m.\u001b[39m_session:\n\u001b[0;32m 1184\u001b[0m \u001b[39m# we only care about session the first pass thru\u001b[39;00m\n\u001b[0;32m 1185\u001b[0m pickler\u001b[39m.\u001b[39m_first_pass \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[1;32m-> 1186\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave_dict(pickler, obj)\n\u001b[0;32m 1187\u001b[0m logger\u001b[39m.\u001b[39mtrace(pickler, \u001b[39m\"\u001b[39m\u001b[39m# D2\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 1188\u001b[0m \u001b[39mreturn\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:972\u001b[0m, in \u001b[0;36m_Pickler.save_dict\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 969\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwrite(MARK \u001b[39m+\u001b[39m DICT)\n\u001b[0;32m 971\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmemoize(obj)\n\u001b[1;32m--> 972\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_batch_setitems(obj\u001b[39m.\u001b[39;49mitems())\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:998\u001b[0m, in \u001b[0;36m_Pickler._batch_setitems\u001b[1;34m(self, items)\u001b[0m\n\u001b[0;32m 996\u001b[0m \u001b[39mfor\u001b[39;00m k, v \u001b[39min\u001b[39;00m tmp:\n\u001b[0;32m 997\u001b[0m save(k)\n\u001b[1;32m--> 998\u001b[0m save(v)\n\u001b[0;32m 999\u001b[0m write(SETITEMS)\n\u001b[0;32m 1000\u001b[0m \u001b[39melif\u001b[39;00m n:\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:560\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 558\u001b[0m f \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdispatch\u001b[39m.\u001b[39mget(t)\n\u001b[0;32m 559\u001b[0m \u001b[39mif\u001b[39;00m f \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 560\u001b[0m f(\u001b[39mself\u001b[39;49m, obj) \u001b[39m# Call unbound method with explicit self\u001b[39;00m\n\u001b[0;32m 561\u001b[0m \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m 563\u001b[0m \u001b[39m# Check private dispatch table if any, or else\u001b[39;00m\n\u001b[0;32m 564\u001b[0m \u001b[39m# copyreg.dispatch_table\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:1427\u001b[0m, in \u001b[0;36msave_instancemethod0\u001b[1;34m(pickler, obj)\u001b[0m\n\u001b[0;32m 1424\u001b[0m \u001b[39m@register\u001b[39m(MethodType)\n\u001b[0;32m 1425\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39msave_instancemethod0\u001b[39m(pickler, obj):\n\u001b[0;32m 1426\u001b[0m logger\u001b[39m.\u001b[39mtrace(pickler, \u001b[39m\"\u001b[39m\u001b[39mMe1: \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m, obj)\n\u001b[1;32m-> 1427\u001b[0m pickler\u001b[39m.\u001b[39;49msave_reduce(MethodType, (obj\u001b[39m.\u001b[39;49m\u001b[39m__func__\u001b[39;49m, obj\u001b[39m.\u001b[39;49m\u001b[39m__self__\u001b[39;49m), obj\u001b[39m=\u001b[39;49mobj)\n\u001b[0;32m 1428\u001b[0m logger\u001b[39m.\u001b[39mtrace(pickler, \u001b[39m\"\u001b[39m\u001b[39m# Me1\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 1429\u001b[0m \u001b[39mreturn\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:692\u001b[0m, in \u001b[0;36m_Pickler.save_reduce\u001b[1;34m(self, func, args, state, listitems, dictitems, state_setter, obj)\u001b[0m\n\u001b[0;32m 690\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 691\u001b[0m save(func)\n\u001b[1;32m--> 692\u001b[0m save(args)\n\u001b[0;32m 693\u001b[0m write(REDUCE)\n\u001b[0;32m 695\u001b[0m \u001b[39mif\u001b[39;00m obj \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 696\u001b[0m \u001b[39m# If the object is already in the memo, this means it is\u001b[39;00m\n\u001b[0;32m 697\u001b[0m \u001b[39m# recursive. In this case, throw away everything we put on the\u001b[39;00m\n\u001b[0;32m 698\u001b[0m \u001b[39m# stack, and fetch the object back from the memo.\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:560\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 558\u001b[0m f \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdispatch\u001b[39m.\u001b[39mget(t)\n\u001b[0;32m 559\u001b[0m \u001b[39mif\u001b[39;00m f \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 560\u001b[0m f(\u001b[39mself\u001b[39;49m, obj) \u001b[39m# Call unbound method with explicit self\u001b[39;00m\n\u001b[0;32m 561\u001b[0m \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m 563\u001b[0m \u001b[39m# Check private dispatch table if any, or else\u001b[39;00m\n\u001b[0;32m 564\u001b[0m \u001b[39m# copyreg.dispatch_table\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:887\u001b[0m, in \u001b[0;36m_Pickler.save_tuple\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 885\u001b[0m \u001b[39mif\u001b[39;00m n \u001b[39m<\u001b[39m\u001b[39m=\u001b[39m \u001b[39m3\u001b[39m \u001b[39mand\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproto \u001b[39m>\u001b[39m\u001b[39m=\u001b[39m \u001b[39m2\u001b[39m:\n\u001b[0;32m 886\u001b[0m \u001b[39mfor\u001b[39;00m element \u001b[39min\u001b[39;00m obj:\n\u001b[1;32m--> 887\u001b[0m save(element)\n\u001b[0;32m 888\u001b[0m \u001b[39m# Subtle. Same as in the big comment below.\u001b[39;00m\n\u001b[0;32m 889\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mid\u001b[39m(obj) \u001b[39min\u001b[39;00m memo:\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:603\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 599\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(\u001b[39m\"\u001b[39m\u001b[39mTuple returned by \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m must have \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 600\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mtwo to six elements\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m reduce)\n\u001b[0;32m 602\u001b[0m \u001b[39m# Save the reduce() output and finally memoize the object\u001b[39;00m\n\u001b[1;32m--> 603\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msave_reduce(obj\u001b[39m=\u001b[39;49mobj, \u001b[39m*\u001b[39;49mrv)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:717\u001b[0m, in \u001b[0;36m_Pickler.save_reduce\u001b[1;34m(self, func, args, state, listitems, dictitems, state_setter, obj)\u001b[0m\n\u001b[0;32m 715\u001b[0m \u001b[39mif\u001b[39;00m state \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 716\u001b[0m \u001b[39mif\u001b[39;00m state_setter \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 717\u001b[0m save(state)\n\u001b[0;32m 718\u001b[0m write(BUILD)\n\u001b[0;32m 719\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[39m# If a state_setter is specified, call it instead of load_build\u001b[39;00m\n\u001b[0;32m 721\u001b[0m \u001b[39m# to update obj's with its previous state.\u001b[39;00m\n\u001b[0;32m 722\u001b[0m \u001b[39m# First, push state_setter and its tuple of expected arguments\u001b[39;00m\n\u001b[0;32m 723\u001b[0m \u001b[39m# (obj, state) onto the stack.\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:560\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 558\u001b[0m f \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdispatch\u001b[39m.\u001b[39mget(t)\n\u001b[0;32m 559\u001b[0m \u001b[39mif\u001b[39;00m f \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 560\u001b[0m f(\u001b[39mself\u001b[39;49m, obj) \u001b[39m# Call unbound method with explicit self\u001b[39;00m\n\u001b[0;32m 561\u001b[0m \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m 563\u001b[0m \u001b[39m# Check private dispatch table if any, or else\u001b[39;00m\n\u001b[0;32m 564\u001b[0m \u001b[39m# copyreg.dispatch_table\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:1186\u001b[0m, in \u001b[0;36msave_module_dict\u001b[1;34m(pickler, obj)\u001b[0m\n\u001b[0;32m 1183\u001b[0m \u001b[39mif\u001b[39;00m is_dill(pickler, child\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m) \u001b[39mand\u001b[39;00m pickler\u001b[39m.\u001b[39m_session:\n\u001b[0;32m 1184\u001b[0m \u001b[39m# we only care about session the first pass thru\u001b[39;00m\n\u001b[0;32m 1185\u001b[0m pickler\u001b[39m.\u001b[39m_first_pass \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[1;32m-> 1186\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave_dict(pickler, obj)\n\u001b[0;32m 1187\u001b[0m logger\u001b[39m.\u001b[39mtrace(pickler, \u001b[39m\"\u001b[39m\u001b[39m# D2\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 1188\u001b[0m \u001b[39mreturn\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:972\u001b[0m, in \u001b[0;36m_Pickler.save_dict\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 969\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwrite(MARK \u001b[39m+\u001b[39m DICT)\n\u001b[0;32m 971\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmemoize(obj)\n\u001b[1;32m--> 972\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_batch_setitems(obj\u001b[39m.\u001b[39;49mitems())\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:998\u001b[0m, in \u001b[0;36m_Pickler._batch_setitems\u001b[1;34m(self, items)\u001b[0m\n\u001b[0;32m 996\u001b[0m \u001b[39mfor\u001b[39;00m k, v \u001b[39min\u001b[39;00m tmp:\n\u001b[0;32m 997\u001b[0m save(k)\n\u001b[1;32m--> 998\u001b[0m save(v)\n\u001b[0;32m 999\u001b[0m write(SETITEMS)\n\u001b[0;32m 1000\u001b[0m \u001b[39melif\u001b[39;00m n:\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:603\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 599\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(\u001b[39m\"\u001b[39m\u001b[39mTuple returned by \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m must have \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 600\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mtwo to six elements\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m reduce)\n\u001b[0;32m 602\u001b[0m \u001b[39m# Save the reduce() output and finally memoize the object\u001b[39;00m\n\u001b[1;32m--> 603\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msave_reduce(obj\u001b[39m=\u001b[39;49mobj, \u001b[39m*\u001b[39;49mrv)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:717\u001b[0m, in \u001b[0;36m_Pickler.save_reduce\u001b[1;34m(self, func, args, state, listitems, dictitems, state_setter, obj)\u001b[0m\n\u001b[0;32m 715\u001b[0m \u001b[39mif\u001b[39;00m state \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m 716\u001b[0m \u001b[39mif\u001b[39;00m state_setter \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 717\u001b[0m save(state)\n\u001b[0;32m 718\u001b[0m write(BUILD)\n\u001b[0;32m 719\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 720\u001b[0m \u001b[39m# If a state_setter is specified, call it instead of load_build\u001b[39;00m\n\u001b[0;32m 721\u001b[0m \u001b[39m# to update obj's with its previous state.\u001b[39;00m\n\u001b[0;32m 722\u001b[0m \u001b[39m# First, push state_setter and its tuple of expected arguments\u001b[39;00m\n\u001b[0;32m 723\u001b[0m \u001b[39m# (obj, state) onto the stack.\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:560\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 558\u001b[0m f \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdispatch\u001b[39m.\u001b[39mget(t)\n\u001b[0;32m 559\u001b[0m \u001b[39mif\u001b[39;00m f \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 560\u001b[0m f(\u001b[39mself\u001b[39;49m, obj) \u001b[39m# Call unbound method with explicit self\u001b[39;00m\n\u001b[0;32m 561\u001b[0m \u001b[39mreturn\u001b[39;00m\n\u001b[0;32m 563\u001b[0m \u001b[39m# Check private dispatch table if any, or else\u001b[39;00m\n\u001b[0;32m 564\u001b[0m \u001b[39m# copyreg.dispatch_table\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:1186\u001b[0m, in \u001b[0;36msave_module_dict\u001b[1;34m(pickler, obj)\u001b[0m\n\u001b[0;32m 1183\u001b[0m \u001b[39mif\u001b[39;00m is_dill(pickler, child\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m) \u001b[39mand\u001b[39;00m pickler\u001b[39m.\u001b[39m_session:\n\u001b[0;32m 1184\u001b[0m \u001b[39m# we only care about session the first pass thru\u001b[39;00m\n\u001b[0;32m 1185\u001b[0m pickler\u001b[39m.\u001b[39m_first_pass \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[1;32m-> 1186\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave_dict(pickler, obj)\n\u001b[0;32m 1187\u001b[0m logger\u001b[39m.\u001b[39mtrace(pickler, \u001b[39m\"\u001b[39m\u001b[39m# D2\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 1188\u001b[0m \u001b[39mreturn\u001b[39;00m\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:972\u001b[0m, in \u001b[0;36m_Pickler.save_dict\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 969\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mwrite(MARK \u001b[39m+\u001b[39m DICT)\n\u001b[0;32m 971\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmemoize(obj)\n\u001b[1;32m--> 972\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_batch_setitems(obj\u001b[39m.\u001b[39;49mitems())\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:998\u001b[0m, in \u001b[0;36m_Pickler._batch_setitems\u001b[1;34m(self, items)\u001b[0m\n\u001b[0;32m 996\u001b[0m \u001b[39mfor\u001b[39;00m k, v \u001b[39min\u001b[39;00m tmp:\n\u001b[0;32m 997\u001b[0m save(k)\n\u001b[1;32m--> 998\u001b[0m save(v)\n\u001b[0;32m 999\u001b[0m write(SETITEMS)\n\u001b[0;32m 1000\u001b[0m \u001b[39melif\u001b[39;00m n:\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\site-packages\\dill\\_dill.py:388\u001b[0m, in \u001b[0;36mPickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 386\u001b[0m msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mCan\u001b[39m\u001b[39m'\u001b[39m\u001b[39mt pickle \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m: attribute lookup builtins.generator failed\u001b[39m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m GeneratorType\n\u001b[0;32m 387\u001b[0m \u001b[39mraise\u001b[39;00m PicklingError(msg)\n\u001b[1;32m--> 388\u001b[0m StockPickler\u001b[39m.\u001b[39;49msave(\u001b[39mself\u001b[39;49m, obj, save_persistent_id)\n",
|
|
|
+ "File \u001b[1;32md:\\miniconda3\\lib\\pickle.py:578\u001b[0m, in \u001b[0;36m_Pickler.save\u001b[1;34m(self, obj, save_persistent_id)\u001b[0m\n\u001b[0;32m 576\u001b[0m reduce \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(obj, \u001b[39m\"\u001b[39m\u001b[39m__reduce_ex__\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39mNone\u001b[39;00m)\n\u001b[0;32m 577\u001b[0m \u001b[39mif\u001b[39;00m reduce \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 578\u001b[0m rv \u001b[39m=\u001b[39m reduce(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mproto)\n\u001b[0;32m 579\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 580\u001b[0m reduce \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(obj, \u001b[39m\"\u001b[39m\u001b[39m__reduce__\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39mNone\u001b[39;00m)\n",
|
|
|
+ "\u001b[1;31mTypeError\u001b[0m: cannot pickle '_cffi_backend.__CDataOwnGC' object"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "from microphones_instance import MicrophoneControllerInstance\n",
|
|
|
+ "\n",
|
|
|
+ "# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ "status = mp.Value('i', 1)\n",
|
|
|
+ "\n",
|
|
|
+ "microphoneController = MicrophoneControllerInstance(status, cfg[\"microphones\"])\n",
|
|
|
+ "\n",
|
|
|
+ "mc = mp.Process(target=microphoneController.run, args=())\n",
|
|
|
+ "mc.start()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "status.value = 2\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Recording started\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "status.value = 0\n",
|
|
|
+ "\n",
|
|
|
+ "mc.join()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "### Test with threading (instance methods) -> Works!"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 8,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "# experiment status: 1 - idle, 2 - running (recording, logging), 0 - stopped\n",
|
|
|
+ "status = mp.Value('i', 1)\n",
|
|
|
+ "\n",
|
|
|
+ "mc = MicrophoneControllerInstance(status,cfg[\"microphones\"])\n",
|
|
|
+ "\n",
|
|
|
+ "mc.start()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 9,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Audio input stream started.\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "status.value = 2"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 10,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "import time"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 11,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": [
|
|
|
+ "status.value = 0"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 12,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Microphones recording stopped\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "mc.stop()"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": []
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "metadata": {
|
|
|
+ "kernelspec": {
|
|
|
+ "display_name": "Python 3",
|
|
|
+ "language": "python",
|
|
|
+ "name": "python3"
|
|
|
+ },
|
|
|
+ "language_info": {
|
|
|
+ "codemirror_mode": {
|
|
|
+ "name": "ipython",
|
|
|
+ "version": 3
|
|
|
+ },
|
|
|
+ "file_extension": ".py",
|
|
|
+ "mimetype": "text/x-python",
|
|
|
+ "name": "python",
|
|
|
+ "nbconvert_exporter": "python",
|
|
|
+ "pygments_lexer": "ipython3",
|
|
|
+ "version": "3.10.8"
|
|
|
+ },
|
|
|
+ "vscode": {
|
|
|
+ "interpreter": {
|
|
|
+ "hash": "af8259ad5c1c9c7a69bd6ea085234cf8fd3a6a37a71ca551828b314c4d89b0ad"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "nbformat": 4,
|
|
|
+ "nbformat_minor": 2
|
|
|
+}
|