[
  {
    "path": ".gitignore",
    "content": "/logs/*.log\n/exp/*/\n/inference/*.npz\n/inference/*.mid\n#!/inference/wzk.npz\n/src_no_pos/\n/src/*.jpg\n/src/*.npz\n!/src/midi2mp3.py\n/src/metadata.json\n/dataset/*.npz\n/dataset/json_*/\n/src/video2npz/VisBeatAssets/\n/src/video2npz/image/*\n/src/video2npz/examples/*\n/src/video2npz/fig/*\n/src/video2npz/flow/*\n/src/video2npz/optical_flow/*\n\n.DS_Store\n__pycache__/\n*.pt\n.idea/\n/new/\n*.mp4\n*.mp3\n*.m4a\n*.pyc\ncookies.txt\nmetadata.json\n*.sf2\n"
  },
  {
    "path": "CMT.ipynb",
    "content": "{\n  \"nbformat\": 4,\n  \"nbformat_minor\": 0,\n  \"metadata\": {\n    \"colab\": {\n      \"name\": \"CMT.ipynb\",\n      \"private_outputs\": true,\n      \"provenance\": [],\n      \"collapsed_sections\": [],\n      \"include_colab_link\": true\n    },\n    \"kernelspec\": {\n      \"name\": \"python3\",\n      \"display_name\": \"Python 3\"\n    },\n    \"language_info\": {\n      \"name\": \"python\"\n    },\n    \"accelerator\": \"GPU\"\n  },\n  \"cells\": [\n    {\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"view-in-github\",\n        \"colab_type\": \"text\"\n      },\n      \"source\": [\n        \"<a href=\\\"https://colab.research.google.com/github/wzk1015/video-bgm-generation/blob/develop/CMT.ipynb\\\" target=\\\"_parent\\\"><img src=\\\"https://colab.research.google.com/assets/colab-badge.svg\\\" alt=\\\"Open In Colab\\\"/></a>\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"# **Demo of Controllable Music Transformer**\\n\",\n        \"\\n\",\n        \"We provide a colab notebook for running inference with CMT. You can upload a video and generate a background music using this notebook.\"\n      ],\n      \"metadata\": {\n        \"id\": \"Qx-JUsBYpv3X\"\n      }\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"# 1. Preparation\"\n      ],\n      \"metadata\": {\n        \"id\": \"iGsKCYiR8ZBy\"\n      }\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Clone the repo\"\n      ],\n      \"metadata\": {\n        \"id\": \"t34LcwtQGq7_\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"id\": \"YMTYugKn6NNp\"\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"import os\\n\",\n        \"from google.colab import files\\n\",\n        \"import json\\n\",\n        \"\\n\",\n        \"os.chdir('/content')\\n\",\n        \"!git clone https://github.com/wzk1015/video-bgm-generation\\n\",\n        \"os.chdir('/content/video-bgm-generation')\"\n      ]\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Download checkpoint and soundfont\\n\",\n        \"\\n\"\n      ],\n      \"metadata\": {\n        \"id\": \"X9ZN2EbvG9J4\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"!gsutil -m cp gs://cmt/loss_8_params.pt /content/video-bgm-generation/exp/\\n\",\n        \"!gsutil -m cp gs://magentadata/soundfonts/SGM-v2.01-Sal-Guit-Bass-V1.3.sf2 /content/video-bgm-generation/\"\n      ],\n      \"metadata\": {\n        \"id\": \"c7XER9vH8mfb\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Install dependencies\"\n      ],\n      \"metadata\": {\n        \"id\": \"b4RRCIybl7_I\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"!apt-get update && apt-get install libfluidsynth1 build-essential libasound2-dev libjack-dev fluidsynth\"\n      ],\n      \"metadata\": {\n        \"id\": \"efg5Ya8cJL5o\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"!pip install --upgrade pip\\n\",\n        \"# this may take ~15 minutes\\n\",\n        \"!pip install pytorch-fast-transformers==0.3.0\\n\",\n        \"# Note: Version of pytorch-fast-transformers is tricky - depends on your randomly assigned colab GPU, it could be 0.3.0 or 0.4.0 or others.\\n\",\n        \"# Incorrect fast-transformers version could lead to Errors or generating awful results for unknown reasons,\\n\",\n        \"# so you should try different versions, or refer to https://github.com/idiap/fast-transformers\\n\",\n        \"\\n\",\n        \"!pip install -r py3_requirements.txt\\n\",\n        \"os.chdir(\\\"/content/video-bgm-generation/src/video2npz/visbeat3/\\\")\\n\",\n        \"!python setup.py install\"\n      ],\n      \"metadata\": {\n        \"id\": \"SkRSrynzSrA-\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"# 2. Process input video\"\n      ],\n      \"metadata\": {\n        \"id\": \"ygRjsNf5F0FT\"\n      }\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Upload your video\\n\",\n        \"\\n\",\n        \"It is recommended to use videos **less than 2 minutes**, otherwise it gets really slow\"\n      ],\n      \"metadata\": {\n        \"id\": \"QMS5SlFOrVv-\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/\\\")\\n\",\n        \"uploaded = files.upload()\\n\",\n        \"assert len(uploaded) == 1, \\\"upload one video file only\\\"\\n\",\n        \"filename = list(uploaded.keys())[0]\\n\",\n        \"os.system(f'mv {filename} videos/test_raw.mp4')\"\n      ],\n      \"metadata\": {\n        \"id\": \"gczMG7TyQYCC\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Convert to 360p to speed up extracting optical flow and visbeats\"\n      ],\n      \"metadata\": {\n        \"id\": \"dR5dCMo5qfk-\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/videos/\\\")\\n\",\n        \"!rm test.mp4\\n\",\n        \"!ffmpeg -i test_raw.mp4 -strict -2 -vf scale=-1:360 test.mp4\"\n      ],\n      \"metadata\": {\n        \"id\": \"RzRrVu9RqTZ6\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Extracting optical flow and visbeats, convert video into npz file\"\n      ],\n      \"metadata\": {\n        \"id\": \"sgm_TOq7QYXn\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/src/video2npz/\\\")\\n\",\n        \"!rm -r VisBeatAssets/ fig/ flow/ image/ optical_flow/\\n\",\n        \"!bash video2npz.sh ../../videos/test.mp4\\n\",\n        \"# extracting optical flow and visbeats may be slow\"\n      ],\n      \"metadata\": {\n        \"id\": \"y_l8VDLFFE-c\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"# 3. Run the model to generate background music\"\n      ],\n      \"metadata\": {\n        \"id\": \"-JASD-zxJZJt\"\n      }\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Run inference to generate MIDI (.mid) output\"\n      ],\n      \"metadata\": {\n        \"id\": \"TpZnfeIsHhyM\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/src/\\\")\\n\",\n        \"!python gen_midi_conditional.py -f \\\"../inference/test.npz\\\" -c \\\"../exp/loss_8_params.pt\\\" -n 1\"\n      ],\n      \"metadata\": {\n        \"id\": \"Xxus1H-XGHXj\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Convert midi into audio: use **GarageBand (recommended)** or midi2audio\\n\",\n        \"\\n\",\n        \"Remember to **set tempo to the value of tempo in video2npz/metadata.json**\"\n      ],\n      \"metadata\": {\n        \"id\": \"pR3rUJWIJnVp\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/src/\\\")\\n\",\n        \"files.download('../inference/test.npz_0.mid')\\n\",\n        \"\\n\",\n        \"with open(\\\"video2npz/metadata.json\\\") as f:\\n\",\n        \"    tempo = json.load(f)['tempo']\\n\",\n        \"    print(\\\"tempo:\\\", tempo)\"\n      ],\n      \"metadata\": {\n        \"id\": \"lKR7qWinMUFM\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Generate audio with midi2audio\\n\",\n        \"\\n\",\n        \"Instead of running this cell, we recommend using GarageBand or other softwares, since their soundfonts are better. But this also works fine\"\n      ],\n      \"metadata\": {\n        \"id\": \"GzEb08C4ovjD\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"import note_seq\\n\",\n        \"from pretty_midi import PrettyMIDI\\n\",\n        \"import midi2audio\\n\",\n        \"import numpy as np\\n\",\n        \"import io\\n\",\n        \"import scipy\\n\",\n        \"\\n\",\n        \"SAMPLE_RATE = 16000\\n\",\n        \"SF2_PATH = '/content/video-bgm-generation/SGM-v2.01-Sal-Guit-Bass-V1.3.sf2'\\n\",\n        \"os.chdir(\\\"/content/video-bgm-generation/inference/\\\")\\n\",\n        \"\\n\",\n        \"input_mid = 'test.npz_0.mid'\\n\",\n        \"midi_obj = PrettyMIDI(input_mid)\\n\",\n        \"# convert tempo\\n\",\n        \"midi_length = midi_obj.get_end_time()\\n\",\n        \"midi_obj.adjust_times([0, midi_length], [0, midi_length*120/tempo])\\n\",\n        \"processed_mid = input_mid[:-4] + \\\"_processed.mid\\\"\\n\",\n        \"midi_obj.write(processed_mid)\\n\",\n        \"print(\\\"converting into mp3\\\")\\n\",\n        \"fs = midi2audio.FluidSynth(SF2_PATH, sample_rate=SAMPLE_RATE)\\n\",\n        \"fs.midi_to_audio(processed_mid, \\\"music.mp3\\\")\\n\",\n        \"\\n\",\n        \"print(\\\"playing music\\\")\\n\",\n        \"ns = note_seq.midi_io.midi_to_note_sequence(midi_obj)\\n\",\n        \"note_seq.play_sequence(ns, synth=note_seq.fluidsynth, sample_rate=SAMPLE_RATE, sf2_path=SF2_PATH)\\n\",\n        \"note_seq.plot_sequence(ns)\\n\",\n        \"  \"\n      ],\n      \"metadata\": {\n        \"id\": \"fZHzA0UtKDWa\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    },\n    {\n      \"cell_type\": \"markdown\",\n      \"source\": [\n        \"Combine original video and audio into video with BGM\\n\",\n        \"\\n\",\n        \"Generate/upload the audio file under `inference`, name it as `music.mp3`, and run this to combine video and music\"\n      ],\n      \"metadata\": {\n        \"id\": \"KKObBCKBKlU1\"\n      }\n    },\n    {\n      \"cell_type\": \"code\",\n      \"source\": [\n        \"os.chdir(\\\"/content/video-bgm-generation/inference/\\\")\\n\",\n        \"!rm output.mp4\\n\",\n        \"!ffmpeg -i ../videos/test_raw.mp4 -i music.mp3 -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 output.mp4\\n\",\n        \"files.download('output.mp4')\"\n      ],\n      \"metadata\": {\n        \"id\": \"SqNLXFzmLPjP\"\n      },\n      \"execution_count\": null,\n      \"outputs\": []\n    }\n  ]\n}"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Shangzhe Di\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Controllable Music Transformer\n\nOfficial code for our paper *Video Background Music Generation with Controllable Music Transformer* (ACM MM 2021 **Best Paper Award**) \n\n[[Paper]](https://arxiv.org/abs/2111.08380) [[Project Page]](https://wzk1015.github.io/cmt/) [[Colab Demo]](https://colab.research.google.com/github/wzk1015/video-bgm-generation/blob/main/CMT.ipynb)\n\n\n\n## News\n\n[2025.3] **Take a look at our survey on vision-to-music generation, published in ISMIR 2025 ([Paper](https://arxiv.org/abs/2503.21254), [Repo](https://github.com/wzk1015/Awesome-Vision-to-Music-Generation))**, with the latest methods, datasets and evaluation in video-to-music and image-to-music generation.\n\n[2024.12] 🚀🚀 **Check out our new [paper](https://github.com/wbs2788/VMB/tree/main) for multimodal music generation!** We propose a novel multimodal music generation approach with explicit text and music bridges for video-to-music, image-to-music, text-to-music, and controllable music generation tasks.\n\n[2023.9] **Check out our new [ICCV 2023 paper](https://arxiv.org/abs/2211.11248) for video background music generation.** We provide a video and symbolic music dataset with rich annotations, an objective metric for video-music correspondence, and a benchmark model that utilizes music priors of chords, melody, and accompaniment along with video-music relations of semantic, color, and motion features.\n\n[2022.5] **We provide a [colab notebook](https://colab.research.google.com/github/wzk1015/video-bgm-generation/blob/main/CMT.ipynb) for demo!** You can run inference code and generate background music for your input video.\n\n[2021.10] 🏆 We won the **ACM MM 2021 [Best Paper Award](https://www.wzk.plus/award_imgs/mm.jpg)**!\n\n## Introduction\n\nWe address the unexplored task – *video background music generation*. We first establish three rhythmic relations between video and background music. We then propose a **C**ontrollable **M**usic **T**ransformer (CMT) to achieve local and global control of the music generation process. Our proposed method does not require paired video and music data for training while generating melodious and compatible music with the given video. \n\n![](https://raw.githubusercontent.com/wzk1015/wzk1015.github.io/master/cmt/img/head.png)\n\n\n\n## Directory Structure\n\n* `src/`: code of the whole pipeline\n  * `train.py`: training script, take an npz file as input music data to train the model \n  * `model.py`: code of the model\n  * `gen_midi_conditional.py`: inference script, take an npz file (represents a video) as input to generate several songs\n  \n  * `midi2mp3.py`: script of converting midi into mp3\n  \n  * `src/video2npz/`: convert video into npz by extracting motion saliency and motion speed\n* `dataset/`: processed dataset for training, in the format of npz\n* `logs/`: logs that automatically generated during training, can be used to track the training process\n* `exp/`: checkpoints, named after val loss (e.g. `loss_8_params.pt`)\n* `inference/`: processed video for inference (.npz), and generated music(.mid) \n\n\n\n\n## Preparation\n\n* Clone this repo\n\n* Download the processed training data `lpd_5_prcem_mix_v8_10000.npz`  from [HERE](https://drive.google.com/file/d/19f_DytIbEiSDCwz8FPpScrHqmnqNtVYT/view?usp=sharing) and put it under `dataset/` \n\n* Download the pre-trained model `loss_8_params.pt` from [HERE](https://drive.google.com/file/d/1KvIRRm0KqTlEFDjAgs4fMtLRQBq0rBWy/view?usp=sharing) and put it under `exp/` \n\n* Install `ffmpeg=3.2.4` \n\n* Install Python3 dependencies `pip install -r py3_requirements.txt`\n\n  * Choose the correct version of `torch` and `pytorch-fast-transformers` based on your CUDA version (see [fast-transformers repo](https://github.com/idiap/fast-transformers) and [this issue](https://github.com/wzk1015/video-bgm-generation/issues/3))\n\n* Install `visbeat3` package: `cd src/video2npz/visbeat3; python setup.py install`\n\n* (Optional) If you want to convert midi into mp3 with midi2audio:\n\n  * Install fluidsynth following [this](https://github.com/FluidSynth/fluidsynth/wiki/Download)\n  * Download soundfont `SGM-v2.01-Sal-Guit-Bass-V1.3.sf2` from [HERE](https://drive.google.com/file/d/1zDg0P-0rCXDl_wX4zeLcKRNmOFobq6u8/view?usp=sharing) and put it directly under this folder (`video-bgm-generation`)\n\n  \n\n## Training\n\n- A quick start by using the processed data `lpd_5_prcem_mix_v8_10000.npz` (1~2 days on 8x 1080Ti GPUs):\n\n  ```shell\n  python train.py --name train_default -b 8 --gpus 0 1 2 3 4 5 6 7\n  ```\n\n* (Optional) If you want to reproduce the whole process:\n\n  1. Download the lpd-5-cleansed dataset from [HERE](https://drive.google.com/file/d/1AzLZ4fHrcek1rVNlOC3pzxsMaNSITZsG/view?usp=sharing) and put the extracted files under `dataset/lpd_5_cleansed/`\n\n  2. Go to `src/` and convert the pianoroll files (.npz) to midi files (~3 files / sec):\n\n     ```shell\n     python pianoroll2midi.py --in_dir ../dataset/lpd_5_cleansed/ --out_dir ../dataset/lpd_5_cleansed_midi/\n     ```\n\n  3. Convert midi files to .npz files with our proposed representation (~5 files / sec):\n\n       ```shell\n       python midi2numpy_mix.py --midi_dir ../dataset/lpd_5_cleansed_midi/ --out_name data.npz \n       ```\n\n  4. Train the model (1~2 days on 8x 1080Ti GPUs):\n\n      ```shell\n      python train.py --name train_exp --train_data ../dataset/data.npz -b 8 --gpus 0 1 2 3 4 5 6 7\n      ```\n\n**Note:** If you want to train with another MIDI dataset, please ensure that each track belongs to one of the five instruments (Drums, Piano, Guitar, Bass, or Strings) and is named exactly with its instrument. Otherwise, you may have to change the track names in the MIDI files. You can check this with [Muspy](https://salu133445.github.io/muspy/):\n\n```python\nimport muspy\nmidi = muspy.read_midi('xxx.mid')\nprint([track.name for track in midi.tracks]) # Should be like ['Drums', 'Guitar', 'Bass', 'Strings']\n```\n\n\n\n## Inference\n\nInference requires one GPU. You can try our [colab notebook](https://colab.research.google.com/github/wzk1015/video-bgm-generation/blob/main/CMT.ipynb) to run inference.\n\nIt is recommended to use videos *less than 2 minutes*, otherwise, it gets really slow\n\n* Resize the video into 360p\n\n  ```shell\n  ffmpeg -i xxx.mp4 -strict -2 -vf scale=-1:360 test.mp4\n  ```\n\n* Convert input video (MP4 format) into npz\n\n  ```shell\n  cd src/video2npz\n  sh video2npz.sh ../../videos/test.mp4\n  ```\n  \n* Run model to generate `.mid` : \n\n  ```shell\n  python gen_midi_conditional.py -f \"../inference/test.npz\" -c \"../exp/loss_8_params.pt\" -n 5\n  \n  # If using another training set, change `decoder_n_class` in `gen_midi_conditional` to the one in `train.py`\n  ```\n\n* Convert midi into audio\n\n  * Get tempo of the music: \n\n  * ```python\n     # metadata.json is generated when running `video2npz.sh`\n    with open(\"video2npz/metadata.json\") as f:\n        tempo = json.load(f)['tempo']\n        print(\"tempo:\", tempo)\n    ```\n  * (A) Use GarageBand to convert midi into audio\n\n    * this is **recommended** since their soundfonts are better, and no need to install fluidsynth and soundfonts\n    * remember to set tempo\n\n  * (B) Use midi2audio\n\n    ```shell\n    # Make sure you have installed fluidsynth and downloaded soundfont\n    python midi2mp3.py --input ../inference/get_0.mid --output ../inference/get_0.mp3\n    ```\n\n* Combine original video and audio into video with BGM:\n\n  ````shell\n  ffmpeg -i test.mp4 -i get_0.mp3 -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 output.mp4\n  \n  # test.mp4: input video\n  # get_0.mp3: audio file generated in the previous step\n  # output.mp4: output video with BGM\n  ````\n\n\n\n## Matching Method\n\nThe matching method finds the five most matching music pieces from the music library for a given video.\n\n```shell\npython src/match.py inference/test.npz dataset/lpd_5_prcem_mix_v8_10000.npz\n```\n\n\n\n## Citation\n\n```bibtex\n@inproceedings{di2021video,\n  title={Video Background Music Generation with Controllable Music Transformer},\n  author={Di, Shangzhe and Jiang, Zeren and Liu, Si and Wang, Zhaokai and Zhu, Leyan and He, Zexin and Liu, Hongming and Yan, Shuicheng},\n  booktitle={ACM Multimedia},\n  year={2021}\n}\n\n@inproceedings{zhuo2023video,\n  title={Video background music generation: Dataset, method and evaluation},\n  author={Zhuo, Le and Wang, Zhaokai and Wang, Baisen and Liao, Yue and Bao, Chenxi and Peng, Stanley and Han, Songhao and Zhang, Aixi and Fang, Fei and Liu, Si},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={15637--15647},\n  year={2023}\n}\n\n@article{vmb,\n  title={Multimodal Music Generation with Explicit Bridges and Retrieval Augmentation},\n  author={Wang, Baisen and Zhuo, Le and Wang, Zhaokai and Bao, Chenxi and Wu, Chengjing and Nie, Xuecheng and Dai, Jiao and Han, Jizhong and Liao, Yue and Liu, Si},\n  journal={arXiv preprint arXiv:2412.09428},\n  year={2024}\n}\n\n@inproceedings{wang2025vision,\n  title={Vision-to-Music Generation: A Survey},\n  author={Wang, Zhaokai and Bao, Chenxi and Zhuo, Le and Han, Jingrui and Yue, Yang and Tang, Yihong and Huang, Victor Shea-Jay and Liao, Yue},\n  booktitle={ISMIR},\n  year={2025}\n}\n```\n\n\n\n## Acknowledgements\n\nOur code is based on [Compound Word Transformer](https://github.com/YatingMusic/compound-word-transformer).\n\n`src/video2npz/visbeat3` is built upon [haofanwang/visbeat3](https://github.com/haofanwang/visbeat3) and the original [visbeat](http://abedavis.com/visualbeat/).\n"
  },
  {
    "path": "dataset/.gitkeep",
    "content": ""
  },
  {
    "path": "exp/.gitkeep",
    "content": ""
  },
  {
    "path": "inference/.gitkeep",
    "content": ""
  },
  {
    "path": "logs/.gitkeep",
    "content": ""
  },
  {
    "path": "py3_requirements.txt",
    "content": "tqdm\nurllib3==1.26.9\nsix==1.16.0\nthreadpoolctl==2.1.0\nh5py==2.10.0\nmatplotlib==3.3.4\nnumpy==1.23.1\nmiditoolkit==0.1.15\nmuspy==0.4.0\nscikit_learn==1.0\ntorch==1.9.0\npytorch-fast-transformers\nopencv-python==4.5.3.56\nscikit-video==1.1.11\npypianoroll\nscipy\nbs4\nlibrosa==0.6.2\nimageio==2.9.0\nrequests\nmoviepy==1.0.3\ntermcolor==1.1.0\nyoutube-dl==2021.12.17\nnumba==0.48.0\npretty_midi\npyfluidsynth==1.2.5\nnote_seq\nmidi2audio\n"
  },
  {
    "path": "src/dictionary_mix.py",
    "content": "preset_event2word = {\r\n    \"tempo\"     : {\r\n        0          : 0,\r\n        \"CONTI\"    : 1,\r\n        \"Tempo_0\"  : 2,\r\n        \"Tempo_1\"  : 3,\r\n        \"Tempo_2\"  : 4,\r\n        \"Tempo_3\"  : 5,\r\n        \"Tempo_4\"  : 6,\r\n        \"Tempo_5\"  : 7,\r\n        \"Tempo_6\"  : 8,\r\n        \"Tempo_7\"  : 9,\r\n        \"Tempo_8\"  : 10,\r\n        \"Tempo_9\"  : 11,\r\n        \"Tempo_10\" : 12,\r\n        \"Tempo_11\" : 13,\r\n        \"Tempo_12\" : 14,\r\n        \"Tempo_13\" : 15,\r\n        \"Tempo_14\" : 16,\r\n        \"Tempo_15\" : 17,\r\n        \"Tempo_16\" : 18,\r\n        \"Tempo_17\" : 19,\r\n        \"Tempo_18\" : 20,\r\n        \"Tempo_19\" : 21,\r\n        \"Tempo_20\" : 22,\r\n        \"Tempo_21\" : 23,\r\n        \"Tempo_22\" : 24,\r\n        \"Tempo_23\" : 25,\r\n        \"Tempo_24\" : 26,\r\n        \"Tempo_25\" : 27,\r\n        \"Tempo_26\" : 28,\r\n        \"Tempo_27\" : 29,\r\n        \"Tempo_28\" : 30,\r\n        \"Tempo_29\" : 31,\r\n        \"Tempo_30\" : 32,\r\n        \"Tempo_31\" : 33,\r\n        \"Tempo_32\" : 34,\r\n        \"Tempo_33\" : 35,\r\n        \"Tempo_34\" : 36,\r\n        \"Tempo_35\" : 37,\r\n        \"Tempo_36\" : 38,\r\n        \"Tempo_37\" : 39,\r\n        \"Tempo_38\" : 40,\r\n        \"Tempo_39\" : 41,\r\n        \"Tempo_40\" : 42,\r\n        \"Tempo_41\" : 43,\r\n        \"Tempo_42\" : 44,\r\n        \"Tempo_43\" : 45,\r\n        \"Tempo_44\" : 46,\r\n        \"Tempo_45\" : 47,\r\n        \"Tempo_46\" : 48,\r\n        \"Tempo_47\" : 49,\r\n        \"Tempo_48\" : 50,\r\n        \"Tempo_49\" : 51,\r\n        \"Tempo_50\" : 52,\r\n        \"Tempo_51\" : 53,\r\n        \"Tempo_52\" : 54,\r\n        \"Tempo_53\" : 55,\r\n        \"Tempo_54\" : 56,\r\n        \"Tempo_55\" : 57,\r\n        \"Tempo_56\" : 58,\r\n        \"Tempo_57\" : 59,\r\n        \"Tempo_58\" : 60,\r\n        \"Tempo_59\" : 61,\r\n        \"Tempo_60\" : 62,\r\n        \"Tempo_61\" : 63,\r\n        \"Tempo_62\" : 64,\r\n        \"Tempo_63\" : 65,\r\n        \"Tempo_64\" : 66,\r\n        \"Tempo_65\" : 67,\r\n        \"Tempo_66\" : 68,\r\n        \"Tempo_67\" : 69,\r\n        \"Tempo_68\" : 70,\r\n        \"Tempo_69\" : 71,\r\n        \"Tempo_70\" : 72,\r\n        \"Tempo_71\" : 73,\r\n        \"Tempo_72\" : 74,\r\n        \"Tempo_73\" : 75,\r\n        \"Tempo_74\" : 76,\r\n        \"Tempo_75\" : 77,\r\n        \"Tempo_76\" : 78,\r\n        \"Tempo_77\" : 79,\r\n        \"Tempo_78\" : 80,\r\n        \"Tempo_79\" : 81,\r\n        \"Tempo_80\" : 82,\r\n        \"Tempo_81\" : 83,\r\n        \"Tempo_82\" : 84,\r\n        \"Tempo_83\" : 85,\r\n        \"Tempo_84\" : 86,\r\n        \"Tempo_85\" : 87,\r\n        \"Tempo_86\" : 88,\r\n        \"Tempo_87\" : 89,\r\n        \"Tempo_88\" : 90,\r\n        \"Tempo_89\" : 91,\r\n        \"Tempo_90\" : 92,\r\n        \"Tempo_91\" : 93,\r\n        \"Tempo_92\" : 94,\r\n        \"Tempo_93\" : 95,\r\n        \"Tempo_94\" : 96,\r\n        \"Tempo_95\" : 97,\r\n        \"Tempo_96\" : 98,\r\n        \"Tempo_97\" : 99,\r\n        \"Tempo_98\" : 100,\r\n        \"Tempo_99\" : 101,\r\n        \"Tempo_100\": 102,\r\n        \"Tempo_101\": 103,\r\n        \"Tempo_102\": 104,\r\n        \"Tempo_103\": 105,\r\n        \"Tempo_104\": 106,\r\n        \"Tempo_105\": 107,\r\n        \"Tempo_106\": 108,\r\n        \"Tempo_107\": 109,\r\n        \"Tempo_108\": 110,\r\n        \"Tempo_109\": 111,\r\n        \"Tempo_110\": 112,\r\n        \"Tempo_111\": 113,\r\n        \"Tempo_112\": 114,\r\n        \"Tempo_113\": 115,\r\n        \"Tempo_114\": 116,\r\n        \"Tempo_115\": 117,\r\n        \"Tempo_116\": 118,\r\n        \"Tempo_117\": 119,\r\n        \"Tempo_118\": 120,\r\n        \"Tempo_119\": 121,\r\n        \"Tempo_120\": 122,\r\n        \"Tempo_121\": 123,\r\n        \"Tempo_122\": 124,\r\n        \"Tempo_123\": 125,\r\n        \"Tempo_124\": 126,\r\n        \"Tempo_125\": 127,\r\n        \"Tempo_126\": 128,\r\n        \"Tempo_127\": 129,\r\n        \"Tempo_128\": 130,\r\n        \"Tempo_129\": 131,\r\n        \"Tempo_130\": 132,\r\n        \"Tempo_131\": 133,\r\n        \"Tempo_132\": 134,\r\n        \"Tempo_133\": 135,\r\n        \"Tempo_134\": 136,\r\n        \"Tempo_135\": 137,\r\n        \"Tempo_136\": 138,\r\n        \"Tempo_137\": 139,\r\n        \"Tempo_138\": 140,\r\n        \"Tempo_139\": 141,\r\n        \"Tempo_140\": 142,\r\n        \"Tempo_141\": 143,\r\n        \"Tempo_142\": 144,\r\n        \"Tempo_143\": 145,\r\n        \"Tempo_144\": 146,\r\n        \"Tempo_145\": 147,\r\n        \"Tempo_146\": 148,\r\n        \"Tempo_147\": 149,\r\n        \"Tempo_148\": 150,\r\n        \"Tempo_149\": 151,\r\n        \"Tempo_150\": 152,\r\n        \"Tempo_151\": 153,\r\n        \"Tempo_152\": 154,\r\n        \"Tempo_153\": 155,\r\n        \"Tempo_154\": 156,\r\n        \"Tempo_155\": 157,\r\n        \"Tempo_156\": 158,\r\n        \"Tempo_157\": 159,\r\n        \"Tempo_158\": 160,\r\n        \"Tempo_159\": 161,\r\n        \"Tempo_160\": 162,\r\n        \"Tempo_161\": 163,\r\n        \"Tempo_162\": 164,\r\n        \"Tempo_163\": 165,\r\n        \"Tempo_164\": 166,\r\n        \"Tempo_165\": 167,\r\n        \"Tempo_166\": 168,\r\n        \"Tempo_167\": 169,\r\n        \"Tempo_168\": 170,\r\n        \"Tempo_169\": 171,\r\n        \"Tempo_170\": 172,\r\n        \"Tempo_171\": 173,\r\n        \"Tempo_172\": 174,\r\n        \"Tempo_173\": 175,\r\n        \"Tempo_174\": 176,\r\n        \"Tempo_175\": 177,\r\n        \"Tempo_176\": 178,\r\n        \"Tempo_177\": 179,\r\n        \"Tempo_178\": 180,\r\n        \"Tempo_179\": 181,\r\n        \"Tempo_180\": 182,\r\n        \"Tempo_181\": 183,\r\n        \"Tempo_182\": 184,\r\n        \"Tempo_183\": 185,\r\n        \"Tempo_184\": 186,\r\n        \"Tempo_185\": 187,\r\n        \"Tempo_186\": 188,\r\n        \"Tempo_187\": 189,\r\n        \"Tempo_188\": 190,\r\n        \"Tempo_189\": 191,\r\n        \"Tempo_190\": 192,\r\n        \"Tempo_191\": 193,\r\n        \"Tempo_192\": 194,\r\n        \"Tempo_193\": 195,\r\n        \"Tempo_194\": 196,\r\n        \"Tempo_195\": 197,\r\n        \"Tempo_196\": 198,\r\n        \"Tempo_197\": 199,\r\n        \"Tempo_198\": 200,\r\n        \"Tempo_199\": 201,\r\n        \"Tempo_200\": 202,\r\n        \"Tempo_201\": 203,\r\n        \"Tempo_202\": 204,\r\n        \"Tempo_203\": 205,\r\n        \"Tempo_204\": 206,\r\n        \"Tempo_205\": 207,\r\n        \"Tempo_206\": 208,\r\n        \"Tempo_207\": 209,\r\n        \"Tempo_208\": 210,\r\n        \"Tempo_209\": 211,\r\n        \"Tempo_210\": 212,\r\n        \"Tempo_211\": 213,\r\n        \"Tempo_212\": 214,\r\n        \"Tempo_213\": 215,\r\n        \"Tempo_214\": 216,\r\n        \"Tempo_215\": 217,\r\n        \"Tempo_216\": 218,\r\n        \"Tempo_217\": 219,\r\n        \"Tempo_218\": 220,\r\n        \"Tempo_219\": 221,\r\n        \"Tempo_220\": 222,\r\n        \"Tempo_221\": 223,\r\n        \"Tempo_222\": 224,\r\n        \"Tempo_223\": 225,\r\n        \"Tempo_224\": 226,\r\n        \"Tempo_225\": 227,\r\n        \"Tempo_226\": 228,\r\n        \"Tempo_227\": 229,\r\n        \"Tempo_228\": 230,\r\n        \"Tempo_229\": 231,\r\n        \"Tempo_230\": 232,\r\n        \"Tempo_231\": 233,\r\n        \"Tempo_232\": 234,\r\n        \"Tempo_233\": 235,\r\n        \"Tempo_234\": 236,\r\n        \"Tempo_235\": 237,\r\n        \"Tempo_236\": 238,\r\n        \"Tempo_237\": 239,\r\n        \"Tempo_238\": 240,\r\n        \"Tempo_239\": 241,\r\n        \"Tempo_240\": 242,\r\n        \"Tempo_241\": 243,\r\n        \"Tempo_242\": 244,\r\n        \"Tempo_243\": 245,\r\n        \"Tempo_244\": 246,\r\n        \"Tempo_245\": 247,\r\n        \"Tempo_246\": 248,\r\n        \"Tempo_247\": 249,\r\n        \"Tempo_248\": 250,\r\n        \"Tempo_249\": 251,\r\n        \"Tempo_250\": 252,\r\n        \"Tempo_251\": 253,\r\n        \"Tempo_252\": 254,\r\n        \"Tempo_253\": 255,\r\n        \"Tempo_254\": 256,\r\n        \"Tempo_255\": 257,\r\n        \"Tempo_256\": 258,\r\n        \"Tempo_257\": 259,\r\n        \"Tempo_258\": 260,\r\n        \"Tempo_259\": 261,\r\n        \"Tempo_260\": 262,\r\n        \"Tempo_261\": 263,\r\n        \"Tempo_262\": 264,\r\n        \"Tempo_263\": 265,\r\n        \"Tempo_264\": 266,\r\n        \"Tempo_265\": 267,\r\n        \"Tempo_266\": 268,\r\n        \"Tempo_267\": 269,\r\n        \"Tempo_268\": 270,\r\n        \"Tempo_269\": 271,\r\n        \"Tempo_270\": 272,\r\n        \"Tempo_271\": 273,\r\n        \"Tempo_272\": 274,\r\n        \"Tempo_273\": 275,\r\n        \"Tempo_274\": 276,\r\n        \"Tempo_275\": 277,\r\n        \"Tempo_276\": 278,\r\n        \"Tempo_277\": 279,\r\n        \"Tempo_278\": 280,\r\n        \"Tempo_279\": 281,\r\n        \"Tempo_280\": 282,\r\n        \"Tempo_281\": 283,\r\n        \"Tempo_282\": 284,\r\n        \"Tempo_283\": 285,\r\n        \"Tempo_284\": 286,\r\n        \"Tempo_285\": 287,\r\n        \"Tempo_286\": 288,\r\n        \"Tempo_287\": 289,\r\n        \"Tempo_288\": 290,\r\n        \"Tempo_289\": 291,\r\n        \"Tempo_290\": 292,\r\n        \"Tempo_291\": 293,\r\n        \"Tempo_292\": 294,\r\n        \"Tempo_293\": 295,\r\n        \"Tempo_294\": 296,\r\n        \"Tempo_295\": 297,\r\n        \"Tempo_296\": 298,\r\n        \"Tempo_297\": 299,\r\n        \"Tempo_298\": 300,\r\n        \"Tempo_299\": 301,\r\n        \"Tempo_300\": 302,\r\n        \"Tempo_301\": 303,\r\n        \"Tempo_302\": 304,\r\n        \"Tempo_303\": 305,\r\n        \"Tempo_304\": 306,\r\n        \"Tempo_305\": 307,\r\n        \"Tempo_306\": 308,\r\n        \"Tempo_307\": 309,\r\n        \"Tempo_308\": 310,\r\n        \"Tempo_309\": 311,\r\n        \"Tempo_310\": 312,\r\n        \"Tempo_311\": 313,\r\n        \"Tempo_312\": 314,\r\n        \"Tempo_313\": 315,\r\n        \"Tempo_314\": 316,\r\n        \"Tempo_315\": 317,\r\n        \"Tempo_316\": 318,\r\n        \"Tempo_317\": 319,\r\n        \"Tempo_318\": 320,\r\n        \"Tempo_319\": 321,\r\n        \"Tempo_320\": 322,\r\n        \"Tempo_321\": 323,\r\n        \"Tempo_322\": 324,\r\n        \"Tempo_323\": 325,\r\n        \"Tempo_324\": 326,\r\n        \"Tempo_325\": 327,\r\n        \"Tempo_326\": 328,\r\n        \"Tempo_327\": 329,\r\n        \"Tempo_328\": 330,\r\n        \"Tempo_329\": 331,\r\n        \"Tempo_330\": 332,\r\n        \"Tempo_331\": 333,\r\n        \"Tempo_332\": 334,\r\n        \"Tempo_333\": 335,\r\n        \"Tempo_334\": 336,\r\n        \"Tempo_335\": 337,\r\n        \"Tempo_336\": 338,\r\n        \"Tempo_337\": 339,\r\n        \"Tempo_338\": 340,\r\n        \"Tempo_339\": 341,\r\n        \"Tempo_340\": 342,\r\n        \"Tempo_341\": 343,\r\n        \"Tempo_342\": 344,\r\n        \"Tempo_343\": 345,\r\n        \"Tempo_344\": 346,\r\n        \"Tempo_345\": 347,\r\n        \"Tempo_346\": 348,\r\n        \"Tempo_347\": 349,\r\n        \"Tempo_348\": 350,\r\n        \"Tempo_349\": 351,\r\n        \"Tempo_350\": 352,\r\n        \"Tempo_351\": 353,\r\n        \"Tempo_352\": 354,\r\n        \"Tempo_353\": 355,\r\n        \"Tempo_354\": 356,\r\n        \"Tempo_355\": 357,\r\n        \"Tempo_356\": 358,\r\n        \"Tempo_357\": 359,\r\n        \"Tempo_358\": 360,\r\n        \"Tempo_359\": 361,\r\n        \"Tempo_360\": 362\r\n    },\r\n    \"chord\"     : {\r\n        0      : 0,\r\n        \"CONTI\": 1\r\n    },\r\n    \"beat\"      : {\r\n        0        : 0,\r\n        \"Beat_0\" : 1,\r\n        \"Beat_1\" : 2,\r\n        \"Beat_2\" : 3,\r\n        \"Beat_3\" : 4,\r\n        \"Beat_4\" : 5,\r\n        \"Beat_5\" : 6,\r\n        \"Beat_6\" : 7,\r\n        \"Beat_7\" : 8,\r\n        \"Beat_8\" : 9,\r\n        \"Beat_9\" : 10,\r\n        \"Beat_10\": 11,\r\n        \"Beat_11\": 12,\r\n        \"Beat_12\": 13,\r\n        \"Beat_13\": 14,\r\n        \"Beat_14\": 15,\r\n        \"Beat_15\": 16,\r\n        \"Bar\"    : 17,\r\n    },\r\n    \"type\"      : {\r\n        \"EOS\"   : 0,\r\n        \"M\"     : 1,\r\n        \"Note\"  : 2,\r\n        'Global': 3,\r\n    },\r\n    \"instr_type\": {\r\n        'None'   : 0,\r\n        'Drums'  : 1,\r\n        'Piano'  : 2,\r\n        'Guitar' : 3,\r\n        'Bass'   : 4,\r\n        'Strings': 5,\r\n    },\r\n    \"key/genre\" : {\r\n        \"None\"      : 0,\r\n        'C'         : 5,\r\n        'C#'        : 6,\r\n        'D'         : 7,\r\n        'D#'        : 8,\r\n        'E'         : 9,\r\n        'F'         : 10,\r\n        'F#'        : 11,\r\n        'G'         : 12,\r\n        'G#'        : 13,\r\n        'A'         : 14,\r\n        'A#'        : 15,\r\n        'B'         : 16,\r\n        'c'         : 17,\r\n        'c#'        : 18,\r\n        'd'         : 19,\r\n        'd#'        : 20,\r\n        'e'         : 21,\r\n        'f'         : 22,\r\n        'f#'        : 23,\r\n        'g'         : 24,\r\n        'g#'        : 25,\r\n        'a'         : 26,\r\n        'a#'        : 27,\r\n        'b'         : 28,\r\n\r\n        'Pop'       : 29,\r\n        'Rock'      : 30,\r\n        'Country'   : 31,\r\n        'Electronic': 32,\r\n        'Metal'     : 33,\r\n\r\n    },\r\n    \"pitch\"     : {\r\n        0               : 0,\r\n        \"Note_Pitch_0\"  : 1,\r\n        \"Note_Pitch_1\"  : 2,\r\n        \"Note_Pitch_2\"  : 3,\r\n        \"Note_Pitch_3\"  : 4,\r\n        \"Note_Pitch_4\"  : 5,\r\n        \"Note_Pitch_5\"  : 6,\r\n        \"Note_Pitch_6\"  : 7,\r\n        \"Note_Pitch_7\"  : 8,\r\n        \"Note_Pitch_8\"  : 9,\r\n        \"Note_Pitch_9\"  : 10,\r\n        \"Note_Pitch_10\" : 11,\r\n        \"Note_Pitch_11\" : 12,\r\n        \"Note_Pitch_12\" : 13,\r\n        \"Note_Pitch_13\" : 14,\r\n        \"Note_Pitch_14\" : 15,\r\n        \"Note_Pitch_15\" : 16,\r\n        \"Note_Pitch_16\" : 17,\r\n        \"Note_Pitch_17\" : 18,\r\n        \"Note_Pitch_18\" : 19,\r\n        \"Note_Pitch_19\" : 20,\r\n        \"Note_Pitch_20\" : 21,\r\n        \"Note_Pitch_21\" : 22,\r\n        \"Note_Pitch_22\" : 23,\r\n        \"Note_Pitch_23\" : 24,\r\n        \"Note_Pitch_24\" : 25,\r\n        \"Note_Pitch_25\" : 26,\r\n        \"Note_Pitch_26\" : 27,\r\n        \"Note_Pitch_27\" : 28,\r\n        \"Note_Pitch_28\" : 29,\r\n        \"Note_Pitch_29\" : 30,\r\n        \"Note_Pitch_30\" : 31,\r\n        \"Note_Pitch_31\" : 32,\r\n        \"Note_Pitch_32\" : 33,\r\n        \"Note_Pitch_33\" : 34,\r\n        \"Note_Pitch_34\" : 35,\r\n        \"Note_Pitch_35\" : 36,\r\n        \"Note_Pitch_36\" : 37,\r\n        \"Note_Pitch_37\" : 38,\r\n        \"Note_Pitch_38\" : 39,\r\n        \"Note_Pitch_39\" : 40,\r\n        \"Note_Pitch_40\" : 41,\r\n        \"Note_Pitch_41\" : 42,\r\n        \"Note_Pitch_42\" : 43,\r\n        \"Note_Pitch_43\" : 44,\r\n        \"Note_Pitch_44\" : 45,\r\n        \"Note_Pitch_45\" : 46,\r\n        \"Note_Pitch_46\" : 47,\r\n        \"Note_Pitch_47\" : 48,\r\n        \"Note_Pitch_48\" : 49,\r\n        \"Note_Pitch_49\" : 50,\r\n        \"Note_Pitch_50\" : 51,\r\n        \"Note_Pitch_51\" : 52,\r\n        \"Note_Pitch_52\" : 53,\r\n        \"Note_Pitch_53\" : 54,\r\n        \"Note_Pitch_54\" : 55,\r\n        \"Note_Pitch_55\" : 56,\r\n        \"Note_Pitch_56\" : 57,\r\n        \"Note_Pitch_57\" : 58,\r\n        \"Note_Pitch_58\" : 59,\r\n        \"Note_Pitch_59\" : 60,\r\n        \"Note_Pitch_60\" : 61,\r\n        \"Note_Pitch_61\" : 62,\r\n        \"Note_Pitch_62\" : 63,\r\n        \"Note_Pitch_63\" : 64,\r\n        \"Note_Pitch_64\" : 65,\r\n        \"Note_Pitch_65\" : 66,\r\n        \"Note_Pitch_66\" : 67,\r\n        \"Note_Pitch_67\" : 68,\r\n        \"Note_Pitch_68\" : 69,\r\n        \"Note_Pitch_69\" : 70,\r\n        \"Note_Pitch_70\" : 71,\r\n        \"Note_Pitch_71\" : 72,\r\n        \"Note_Pitch_72\" : 73,\r\n        \"Note_Pitch_73\" : 74,\r\n        \"Note_Pitch_74\" : 75,\r\n        \"Note_Pitch_75\" : 76,\r\n        \"Note_Pitch_76\" : 77,\r\n        \"Note_Pitch_77\" : 78,\r\n        \"Note_Pitch_78\" : 79,\r\n        \"Note_Pitch_79\" : 80,\r\n        \"Note_Pitch_80\" : 81,\r\n        \"Note_Pitch_81\" : 82,\r\n        \"Note_Pitch_82\" : 83,\r\n        \"Note_Pitch_83\" : 84,\r\n        \"Note_Pitch_84\" : 85,\r\n        \"Note_Pitch_85\" : 86,\r\n        \"Note_Pitch_86\" : 87,\r\n        \"Note_Pitch_87\" : 88,\r\n        \"Note_Pitch_88\" : 89,\r\n        \"Note_Pitch_89\" : 90,\r\n        \"Note_Pitch_90\" : 91,\r\n        \"Note_Pitch_91\" : 92,\r\n        \"Note_Pitch_92\" : 93,\r\n        \"Note_Pitch_93\" : 94,\r\n        \"Note_Pitch_94\" : 95,\r\n        \"Note_Pitch_95\" : 96,\r\n        \"Note_Pitch_96\" : 97,\r\n        \"Note_Pitch_97\" : 98,\r\n        \"Note_Pitch_98\" : 99,\r\n        \"Note_Pitch_99\" : 100,\r\n        \"Note_Pitch_100\": 101,\r\n        \"Note_Pitch_101\": 102,\r\n        \"Note_Pitch_102\": 103,\r\n        \"Note_Pitch_103\": 104,\r\n        \"Note_Pitch_104\": 105,\r\n        \"Note_Pitch_105\": 106,\r\n        \"Note_Pitch_106\": 107,\r\n        \"Note_Pitch_107\": 108,\r\n        \"Note_Pitch_108\": 109,\r\n        \"Note_Pitch_109\": 110,\r\n        \"Note_Pitch_110\": 111,\r\n        \"Note_Pitch_111\": 112,\r\n        \"Note_Pitch_112\": 113,\r\n        \"Note_Pitch_113\": 114,\r\n        \"Note_Pitch_114\": 115,\r\n        \"Note_Pitch_115\": 116,\r\n        \"Note_Pitch_116\": 117,\r\n        \"Note_Pitch_117\": 118,\r\n        \"Note_Pitch_118\": 119,\r\n        \"Note_Pitch_119\": 120,\r\n        \"Note_Pitch_120\": 121,\r\n        \"Note_Pitch_121\": 122,\r\n        \"Note_Pitch_122\": 123,\r\n        \"Note_Pitch_123\": 124,\r\n        \"Note_Pitch_124\": 125,\r\n        \"Note_Pitch_125\": 126,\r\n        \"Note_Pitch_126\": 127,\r\n        \"Note_Pitch_127\": 128,\r\n    },\r\n    \"duration\"  : {\r\n        0                   : 0,\r\n        \"Note_Duration_0\"   : 1,\r\n        \"Note_Duration_120\" : 2,\r\n        \"Note_Duration_240\" : 3,\r\n        \"Note_Duration_360\" : 4,\r\n        \"Note_Duration_480\" : 5,\r\n        \"Note_Duration_600\" : 6,\r\n        \"Note_Duration_720\" : 7,\r\n        \"Note_Duration_840\" : 8,\r\n        \"Note_Duration_960\" : 9,\r\n        \"Note_Duration_1080\": 10,\r\n        \"Note_Duration_1200\": 11,\r\n        \"Note_Duration_1320\": 12,\r\n        \"Note_Duration_1440\": 13,\r\n        \"Note_Duration_1560\": 14,\r\n        \"Note_Duration_1680\": 15,\r\n        \"Note_Duration_1800\": 16,\r\n        \"Note_Duration_1920\": 17\r\n    },\r\n    \"velocity\"  : {\r\n        0                  : 0,\r\n        \"Note_Velocity_0\"  : 1,\r\n        \"Note_Velocity_1\"  : 2,\r\n        \"Note_Velocity_2\"  : 3,\r\n        \"Note_Velocity_3\"  : 4,\r\n        \"Note_Velocity_4\"  : 5,\r\n        \"Note_Velocity_5\"  : 6,\r\n        \"Note_Velocity_6\"  : 7,\r\n        \"Note_Velocity_7\"  : 8,\r\n        \"Note_Velocity_8\"  : 9,\r\n        \"Note_Velocity_9\"  : 10,\r\n        \"Note_Velocity_10\" : 11,\r\n        \"Note_Velocity_11\" : 12,\r\n        \"Note_Velocity_12\" : 13,\r\n        \"Note_Velocity_13\" : 14,\r\n        \"Note_Velocity_14\" : 15,\r\n        \"Note_Velocity_15\" : 16,\r\n        \"Note_Velocity_16\" : 17,\r\n        \"Note_Velocity_17\" : 18,\r\n        \"Note_Velocity_18\" : 19,\r\n        \"Note_Velocity_19\" : 20,\r\n        \"Note_Velocity_20\" : 21,\r\n        \"Note_Velocity_21\" : 22,\r\n        \"Note_Velocity_22\" : 23,\r\n        \"Note_Velocity_23\" : 24,\r\n        \"Note_Velocity_24\" : 25,\r\n        \"Note_Velocity_25\" : 26,\r\n        \"Note_Velocity_26\" : 27,\r\n        \"Note_Velocity_27\" : 28,\r\n        \"Note_Velocity_28\" : 29,\r\n        \"Note_Velocity_29\" : 30,\r\n        \"Note_Velocity_30\" : 31,\r\n        \"Note_Velocity_31\" : 32,\r\n        \"Note_Velocity_32\" : 33,\r\n        \"Note_Velocity_33\" : 34,\r\n        \"Note_Velocity_34\" : 35,\r\n        \"Note_Velocity_35\" : 36,\r\n        \"Note_Velocity_36\" : 37,\r\n        \"Note_Velocity_37\" : 38,\r\n        \"Note_Velocity_38\" : 39,\r\n        \"Note_Velocity_39\" : 40,\r\n        \"Note_Velocity_40\" : 41,\r\n        \"Note_Velocity_41\" : 42,\r\n        \"Note_Velocity_42\" : 43,\r\n        \"Note_Velocity_43\" : 44,\r\n        \"Note_Velocity_44\" : 45,\r\n        \"Note_Velocity_45\" : 46,\r\n        \"Note_Velocity_46\" : 47,\r\n        \"Note_Velocity_47\" : 48,\r\n        \"Note_Velocity_48\" : 49,\r\n        \"Note_Velocity_49\" : 50,\r\n        \"Note_Velocity_50\" : 51,\r\n        \"Note_Velocity_51\" : 52,\r\n        \"Note_Velocity_52\" : 53,\r\n        \"Note_Velocity_53\" : 54,\r\n        \"Note_Velocity_54\" : 55,\r\n        \"Note_Velocity_55\" : 56,\r\n        \"Note_Velocity_56\" : 57,\r\n        \"Note_Velocity_57\" : 58,\r\n        \"Note_Velocity_58\" : 59,\r\n        \"Note_Velocity_59\" : 60,\r\n        \"Note_Velocity_60\" : 61,\r\n        \"Note_Velocity_61\" : 62,\r\n        \"Note_Velocity_62\" : 63,\r\n        \"Note_Velocity_63\" : 64,\r\n        \"Note_Velocity_64\" : 65,\r\n        \"Note_Velocity_65\" : 66,\r\n        \"Note_Velocity_66\" : 67,\r\n        \"Note_Velocity_67\" : 68,\r\n        \"Note_Velocity_68\" : 69,\r\n        \"Note_Velocity_69\" : 70,\r\n        \"Note_Velocity_70\" : 71,\r\n        \"Note_Velocity_71\" : 72,\r\n        \"Note_Velocity_72\" : 73,\r\n        \"Note_Velocity_73\" : 74,\r\n        \"Note_Velocity_74\" : 75,\r\n        \"Note_Velocity_75\" : 76,\r\n        \"Note_Velocity_76\" : 77,\r\n        \"Note_Velocity_77\" : 78,\r\n        \"Note_Velocity_78\" : 79,\r\n        \"Note_Velocity_79\" : 80,\r\n        \"Note_Velocity_80\" : 81,\r\n        \"Note_Velocity_81\" : 82,\r\n        \"Note_Velocity_82\" : 83,\r\n        \"Note_Velocity_83\" : 84,\r\n        \"Note_Velocity_84\" : 85,\r\n        \"Note_Velocity_85\" : 86,\r\n        \"Note_Velocity_86\" : 87,\r\n        \"Note_Velocity_87\" : 88,\r\n        \"Note_Velocity_88\" : 89,\r\n        \"Note_Velocity_89\" : 90,\r\n        \"Note_Velocity_90\" : 91,\r\n        \"Note_Velocity_91\" : 92,\r\n        \"Note_Velocity_92\" : 93,\r\n        \"Note_Velocity_93\" : 94,\r\n        \"Note_Velocity_94\" : 95,\r\n        \"Note_Velocity_95\" : 96,\r\n        \"Note_Velocity_96\" : 97,\r\n        \"Note_Velocity_97\" : 98,\r\n        \"Note_Velocity_98\" : 99,\r\n        \"Note_Velocity_99\" : 100,\r\n        \"Note_Velocity_100\": 101,\r\n        \"Note_Velocity_101\": 102,\r\n        \"Note_Velocity_102\": 103,\r\n        \"Note_Velocity_103\": 104,\r\n        \"Note_Velocity_104\": 105,\r\n        \"Note_Velocity_105\": 106,\r\n        \"Note_Velocity_106\": 107,\r\n        \"Note_Velocity_107\": 108,\r\n        \"Note_Velocity_108\": 109,\r\n        \"Note_Velocity_109\": 110,\r\n        \"Note_Velocity_110\": 111,\r\n        \"Note_Velocity_111\": 112,\r\n        \"Note_Velocity_112\": 113,\r\n        \"Note_Velocity_113\": 114,\r\n        \"Note_Velocity_114\": 115,\r\n        \"Note_Velocity_115\": 116,\r\n        \"Note_Velocity_116\": 117,\r\n        \"Note_Velocity_117\": 118,\r\n        \"Note_Velocity_118\": 119,\r\n        \"Note_Velocity_119\": 120,\r\n        \"Note_Velocity_120\": 121,\r\n        \"Note_Velocity_121\": 122,\r\n        \"Note_Velocity_122\": 123,\r\n        \"Note_Velocity_123\": 124,\r\n        \"Note_Velocity_124\": 125,\r\n        \"Note_Velocity_125\": 126,\r\n        \"Note_Velocity_126\": 127,\r\n        \"Note_Velocity_127\": 128,\r\n        \"Note_Velocity_128\": 129,\r\n        \"Note_Velocity_129\": 130,\r\n        \"Note_Velocity_130\": 131,\r\n        \"Note_Velocity_131\": 132,\r\n        \"Note_Velocity_132\": 133,\r\n        \"Note_Velocity_133\": 134,\r\n        \"Note_Velocity_134\": 135,\r\n        \"Note_Velocity_135\": 136,\r\n        \"Note_Velocity_136\": 137,\r\n        \"Note_Velocity_137\": 138,\r\n        \"Note_Velocity_138\": 139,\r\n        \"Note_Velocity_139\": 140,\r\n        \"Note_Velocity_140\": 141,\r\n        \"Note_Velocity_141\": 142,\r\n        \"Note_Velocity_142\": 143,\r\n        \"Note_Velocity_143\": 144,\r\n        \"Note_Velocity_144\": 145,\r\n        \"Note_Velocity_145\": 146,\r\n        \"Note_Velocity_146\": 147,\r\n        \"Note_Velocity_147\": 148,\r\n        \"Note_Velocity_148\": 149,\r\n        \"Note_Velocity_149\": 150,\r\n        \"Note_Velocity_150\": 151,\r\n        \"Note_Velocity_151\": 152,\r\n        \"Note_Velocity_152\": 153,\r\n        \"Note_Velocity_153\": 154,\r\n        \"Note_Velocity_154\": 155,\r\n        \"Note_Velocity_155\": 156,\r\n        \"Note_Velocity_156\": 157,\r\n        \"Note_Velocity_157\": 158,\r\n        \"Note_Velocity_158\": 159,\r\n        \"Note_Velocity_159\": 160,\r\n        \"Note_Velocity_160\": 161,\r\n        \"Note_Velocity_161\": 162,\r\n        \"Note_Velocity_162\": 163,\r\n        \"Note_Velocity_163\": 164,\r\n        \"Note_Velocity_164\": 165,\r\n        \"Note_Velocity_165\": 166,\r\n        \"Note_Velocity_166\": 167,\r\n        \"Note_Velocity_167\": 168,\r\n        \"Note_Velocity_168\": 169,\r\n        \"Note_Velocity_169\": 170,\r\n        \"Note_Velocity_170\": 171,\r\n        \"Note_Velocity_171\": 172,\r\n        \"Note_Velocity_172\": 173,\r\n        \"Note_Velocity_173\": 174,\r\n        \"Note_Velocity_174\": 175,\r\n        \"Note_Velocity_175\": 176,\r\n        \"Note_Velocity_176\": 177,\r\n        \"Note_Velocity_177\": 178,\r\n        \"Note_Velocity_178\": 179,\r\n        \"Note_Velocity_179\": 180,\r\n        \"Note_Velocity_180\": 181,\r\n        \"Note_Velocity_181\": 182,\r\n        \"Note_Velocity_182\": 183,\r\n        \"Note_Velocity_183\": 184,\r\n        \"Note_Velocity_184\": 185,\r\n        \"Note_Velocity_185\": 186,\r\n        \"Note_Velocity_186\": 187,\r\n        \"Note_Velocity_187\": 188,\r\n        \"Note_Velocity_188\": 189,\r\n        \"Note_Velocity_189\": 190,\r\n        \"Note_Velocity_190\": 191,\r\n        \"Note_Velocity_191\": 192,\r\n        \"Note_Velocity_192\": 193,\r\n        \"Note_Velocity_193\": 194,\r\n        \"Note_Velocity_194\": 195,\r\n        \"Note_Velocity_195\": 196,\r\n        \"Note_Velocity_196\": 197,\r\n        \"Note_Velocity_197\": 198,\r\n        \"Note_Velocity_198\": 199,\r\n        \"Note_Velocity_199\": 200,\r\n        \"Note_Velocity_200\": 201,\r\n        \"Note_Velocity_201\": 202,\r\n        \"Note_Velocity_202\": 203,\r\n        \"Note_Velocity_203\": 204,\r\n        \"Note_Velocity_204\": 205,\r\n        \"Note_Velocity_205\": 206,\r\n        \"Note_Velocity_206\": 207,\r\n        \"Note_Velocity_207\": 208,\r\n        \"Note_Velocity_208\": 209,\r\n        \"Note_Velocity_209\": 210,\r\n        \"Note_Velocity_210\": 211,\r\n        \"Note_Velocity_211\": 212,\r\n        \"Note_Velocity_212\": 213,\r\n        \"Note_Velocity_213\": 214,\r\n        \"Note_Velocity_214\": 215,\r\n        \"Note_Velocity_215\": 216,\r\n        \"Note_Velocity_216\": 217,\r\n        \"Note_Velocity_217\": 218,\r\n        \"Note_Velocity_218\": 219,\r\n        \"Note_Velocity_219\": 220,\r\n        \"Note_Velocity_220\": 221,\r\n        \"Note_Velocity_221\": 222,\r\n        \"Note_Velocity_222\": 223,\r\n        \"Note_Velocity_223\": 224,\r\n        \"Note_Velocity_224\": 225,\r\n        \"Note_Velocity_225\": 226,\r\n        \"Note_Velocity_226\": 227,\r\n        \"Note_Velocity_227\": 228,\r\n        \"Note_Velocity_228\": 229,\r\n        \"Note_Velocity_229\": 230,\r\n        \"Note_Velocity_230\": 231,\r\n        \"Note_Velocity_231\": 232,\r\n        \"Note_Velocity_232\": 233,\r\n        \"Note_Velocity_233\": 234,\r\n        \"Note_Velocity_234\": 235,\r\n        \"Note_Velocity_235\": 236,\r\n        \"Note_Velocity_236\": 237,\r\n        \"Note_Velocity_237\": 238,\r\n        \"Note_Velocity_238\": 239,\r\n        \"Note_Velocity_239\": 240,\r\n        \"Note_Velocity_240\": 241,\r\n        \"Note_Velocity_241\": 242,\r\n        \"Note_Velocity_242\": 243,\r\n        \"Note_Velocity_243\": 244,\r\n        \"Note_Velocity_244\": 245,\r\n        \"Note_Velocity_245\": 246,\r\n        \"Note_Velocity_246\": 247,\r\n        \"Note_Velocity_247\": 248,\r\n        \"Note_Velocity_248\": 249,\r\n        \"Note_Velocity_249\": 250,\r\n        \"Note_Velocity_250\": 251,\r\n        \"Note_Velocity_251\": 252,\r\n        \"Note_Velocity_252\": 253,\r\n        \"Note_Velocity_253\": 254,\r\n        \"Note_Velocity_254\": 255,\r\n        \"Note_Velocity_255\": 256,\r\n        \"Note_Velocity_256\": 257,\r\n        \"Note_Velocity_257\": 258,\r\n        \"Note_Velocity_258\": 259,\r\n        \"Note_Velocity_259\": 260,\r\n        \"Note_Velocity_260\": 261,\r\n        \"Note_Velocity_261\": 262,\r\n        \"Note_Velocity_262\": 263,\r\n        \"Note_Velocity_263\": 264,\r\n        \"Note_Velocity_264\": 265,\r\n        \"Note_Velocity_265\": 266,\r\n        \"Note_Velocity_266\": 267,\r\n        \"Note_Velocity_267\": 268,\r\n        \"Note_Velocity_268\": 269,\r\n        \"Note_Velocity_269\": 270,\r\n        \"Note_Velocity_270\": 271,\r\n        \"Note_Velocity_271\": 272,\r\n        \"Note_Velocity_272\": 273,\r\n        \"Note_Velocity_273\": 274,\r\n        \"Note_Velocity_274\": 275,\r\n        \"Note_Velocity_275\": 276,\r\n        \"Note_Velocity_276\": 277,\r\n        \"Note_Velocity_277\": 278,\r\n        \"Note_Velocity_278\": 279,\r\n        \"Note_Velocity_279\": 280,\r\n        \"Note_Velocity_280\": 281,\r\n        \"Note_Velocity_281\": 282,\r\n        \"Note_Velocity_282\": 283,\r\n        \"Note_Velocity_283\": 284,\r\n        \"Note_Velocity_284\": 285,\r\n        \"Note_Velocity_285\": 286,\r\n        \"Note_Velocity_286\": 287,\r\n        \"Note_Velocity_287\": 288,\r\n        \"Note_Velocity_288\": 289,\r\n        \"Note_Velocity_289\": 290,\r\n        \"Note_Velocity_290\": 291,\r\n        \"Note_Velocity_291\": 292,\r\n        \"Note_Velocity_292\": 293,\r\n        \"Note_Velocity_293\": 294,\r\n        \"Note_Velocity_294\": 295,\r\n        \"Note_Velocity_295\": 296,\r\n        \"Note_Velocity_296\": 297,\r\n        \"Note_Velocity_297\": 298,\r\n        \"Note_Velocity_298\": 299,\r\n        \"Note_Velocity_299\": 300,\r\n        \"Note_Velocity_300\": 301,\r\n        \"Note_Velocity_301\": 302,\r\n        \"Note_Velocity_302\": 303,\r\n        \"Note_Velocity_303\": 304,\r\n        \"Note_Velocity_304\": 305,\r\n        \"Note_Velocity_305\": 306,\r\n        \"Note_Velocity_306\": 307,\r\n        \"Note_Velocity_307\": 308,\r\n        \"Note_Velocity_308\": 309,\r\n        \"Note_Velocity_309\": 310,\r\n        \"Note_Velocity_310\": 311,\r\n        \"Note_Velocity_311\": 312,\r\n        \"Note_Velocity_312\": 313,\r\n        \"Note_Velocity_313\": 314,\r\n        \"Note_Velocity_314\": 315,\r\n        \"Note_Velocity_315\": 316,\r\n        \"Note_Velocity_316\": 317,\r\n        \"Note_Velocity_317\": 318,\r\n        \"Note_Velocity_318\": 319,\r\n        \"Note_Velocity_319\": 320,\r\n        \"Note_Velocity_320\": 321,\r\n        \"Note_Velocity_321\": 322,\r\n        \"Note_Velocity_322\": 323,\r\n        \"Note_Velocity_323\": 324,\r\n        \"Note_Velocity_324\": 325,\r\n        \"Note_Velocity_325\": 326,\r\n        \"Note_Velocity_326\": 327,\r\n        \"Note_Velocity_327\": 328,\r\n        \"Note_Velocity_328\": 329,\r\n        \"Note_Velocity_329\": 330,\r\n        \"Note_Velocity_330\": 331,\r\n        \"Note_Velocity_331\": 332,\r\n        \"Note_Velocity_332\": 333,\r\n        \"Note_Velocity_333\": 334,\r\n        \"Note_Velocity_334\": 335,\r\n        \"Note_Velocity_335\": 336,\r\n        \"Note_Velocity_336\": 337,\r\n        \"Note_Velocity_337\": 338,\r\n        \"Note_Velocity_338\": 339,\r\n        \"Note_Velocity_339\": 340,\r\n        \"Note_Velocity_340\": 341,\r\n        \"Note_Velocity_341\": 342,\r\n        \"Note_Velocity_342\": 343,\r\n        \"Note_Velocity_343\": 344,\r\n        \"Note_Velocity_344\": 345,\r\n        \"Note_Velocity_345\": 346,\r\n        \"Note_Velocity_346\": 347,\r\n        \"Note_Velocity_347\": 348,\r\n        \"Note_Velocity_348\": 349,\r\n        \"Note_Velocity_349\": 350,\r\n        \"Note_Velocity_350\": 351,\r\n        \"Note_Velocity_351\": 352,\r\n        \"Note_Velocity_352\": 353,\r\n        \"Note_Velocity_353\": 354,\r\n        \"Note_Velocity_354\": 355,\r\n        \"Note_Velocity_355\": 356,\r\n        \"Note_Velocity_356\": 357,\r\n        \"Note_Velocity_357\": 358,\r\n        \"Note_Velocity_358\": 359,\r\n        \"Note_Velocity_359\": 360,\r\n        \"Note_Velocity_360\": 361\r\n    },\r\n    \"boundary\"  : {\r\n        0         : 0,\r\n        \"None\"    : 1,\r\n        \"Boundary\": 2,\r\n    },\r\n    # 'density': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],\r\n    'variance'  : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],\r\n}\r\n\r\npreset_word2event = {\r\n    \"tempo\"     : {\r\n        0  : 0,\r\n        1  : \"CONTI\",\r\n        2  : \"Tempo_0\",\r\n        3  : \"Tempo_1\",\r\n        4  : \"Tempo_2\",\r\n        5  : \"Tempo_3\",\r\n        6  : \"Tempo_4\",\r\n        7  : \"Tempo_5\",\r\n        8  : \"Tempo_6\",\r\n        9  : \"Tempo_7\",\r\n        10 : \"Tempo_8\",\r\n        11 : \"Tempo_9\",\r\n        12 : \"Tempo_10\",\r\n        13 : \"Tempo_11\",\r\n        14 : \"Tempo_12\",\r\n        15 : \"Tempo_13\",\r\n        16 : \"Tempo_14\",\r\n        17 : \"Tempo_15\",\r\n        18 : \"Tempo_16\",\r\n        19 : \"Tempo_17\",\r\n        20 : \"Tempo_18\",\r\n        21 : \"Tempo_19\",\r\n        22 : \"Tempo_20\",\r\n        23 : \"Tempo_21\",\r\n        24 : \"Tempo_22\",\r\n        25 : \"Tempo_23\",\r\n        26 : \"Tempo_24\",\r\n        27 : \"Tempo_25\",\r\n        28 : \"Tempo_26\",\r\n        29 : \"Tempo_27\",\r\n        30 : \"Tempo_28\",\r\n        31 : \"Tempo_29\",\r\n        32 : \"Tempo_30\",\r\n        33 : \"Tempo_31\",\r\n        34 : \"Tempo_32\",\r\n        35 : \"Tempo_33\",\r\n        36 : \"Tempo_34\",\r\n        37 : \"Tempo_35\",\r\n        38 : \"Tempo_36\",\r\n        39 : \"Tempo_37\",\r\n        40 : \"Tempo_38\",\r\n        41 : \"Tempo_39\",\r\n        42 : \"Tempo_40\",\r\n        43 : \"Tempo_41\",\r\n        44 : \"Tempo_42\",\r\n        45 : \"Tempo_43\",\r\n        46 : \"Tempo_44\",\r\n        47 : \"Tempo_45\",\r\n        48 : \"Tempo_46\",\r\n        49 : \"Tempo_47\",\r\n        50 : \"Tempo_48\",\r\n        51 : \"Tempo_49\",\r\n        52 : \"Tempo_50\",\r\n        53 : \"Tempo_51\",\r\n        54 : \"Tempo_52\",\r\n        55 : \"Tempo_53\",\r\n        56 : \"Tempo_54\",\r\n        57 : \"Tempo_55\",\r\n        58 : \"Tempo_56\",\r\n        59 : \"Tempo_57\",\r\n        60 : \"Tempo_58\",\r\n        61 : \"Tempo_59\",\r\n        62 : \"Tempo_60\",\r\n        63 : \"Tempo_61\",\r\n        64 : \"Tempo_62\",\r\n        65 : \"Tempo_63\",\r\n        66 : \"Tempo_64\",\r\n        67 : \"Tempo_65\",\r\n        68 : \"Tempo_66\",\r\n        69 : \"Tempo_67\",\r\n        70 : \"Tempo_68\",\r\n        71 : \"Tempo_69\",\r\n        72 : \"Tempo_70\",\r\n        73 : \"Tempo_71\",\r\n        74 : \"Tempo_72\",\r\n        75 : \"Tempo_73\",\r\n        76 : \"Tempo_74\",\r\n        77 : \"Tempo_75\",\r\n        78 : \"Tempo_76\",\r\n        79 : \"Tempo_77\",\r\n        80 : \"Tempo_78\",\r\n        81 : \"Tempo_79\",\r\n        82 : \"Tempo_80\",\r\n        83 : \"Tempo_81\",\r\n        84 : \"Tempo_82\",\r\n        85 : \"Tempo_83\",\r\n        86 : \"Tempo_84\",\r\n        87 : \"Tempo_85\",\r\n        88 : \"Tempo_86\",\r\n        89 : \"Tempo_87\",\r\n        90 : \"Tempo_88\",\r\n        91 : \"Tempo_89\",\r\n        92 : \"Tempo_90\",\r\n        93 : \"Tempo_91\",\r\n        94 : \"Tempo_92\",\r\n        95 : \"Tempo_93\",\r\n        96 : \"Tempo_94\",\r\n        97 : \"Tempo_95\",\r\n        98 : \"Tempo_96\",\r\n        99 : \"Tempo_97\",\r\n        100: \"Tempo_98\",\r\n        101: \"Tempo_99\",\r\n        102: \"Tempo_100\",\r\n        103: \"Tempo_101\",\r\n        104: \"Tempo_102\",\r\n        105: \"Tempo_103\",\r\n        106: \"Tempo_104\",\r\n        107: \"Tempo_105\",\r\n        108: \"Tempo_106\",\r\n        109: \"Tempo_107\",\r\n        110: \"Tempo_108\",\r\n        111: \"Tempo_109\",\r\n        112: \"Tempo_110\",\r\n        113: \"Tempo_111\",\r\n        114: \"Tempo_112\",\r\n        115: \"Tempo_113\",\r\n        116: \"Tempo_114\",\r\n        117: \"Tempo_115\",\r\n        118: \"Tempo_116\",\r\n        119: \"Tempo_117\",\r\n        120: \"Tempo_118\",\r\n        121: \"Tempo_119\",\r\n        122: \"Tempo_120\",\r\n        123: \"Tempo_121\",\r\n        124: \"Tempo_122\",\r\n        125: \"Tempo_123\",\r\n        126: \"Tempo_124\",\r\n        127: \"Tempo_125\",\r\n        128: \"Tempo_126\",\r\n        129: \"Tempo_127\",\r\n        130: \"Tempo_128\",\r\n        131: \"Tempo_129\",\r\n        132: \"Tempo_130\",\r\n        133: \"Tempo_131\",\r\n        134: \"Tempo_132\",\r\n        135: \"Tempo_133\",\r\n        136: \"Tempo_134\",\r\n        137: \"Tempo_135\",\r\n        138: \"Tempo_136\",\r\n        139: \"Tempo_137\",\r\n        140: \"Tempo_138\",\r\n        141: \"Tempo_139\",\r\n        142: \"Tempo_140\",\r\n        143: \"Tempo_141\",\r\n        144: \"Tempo_142\",\r\n        145: \"Tempo_143\",\r\n        146: \"Tempo_144\",\r\n        147: \"Tempo_145\",\r\n        148: \"Tempo_146\",\r\n        149: \"Tempo_147\",\r\n        150: \"Tempo_148\",\r\n        151: \"Tempo_149\",\r\n        152: \"Tempo_150\",\r\n        153: \"Tempo_151\",\r\n        154: \"Tempo_152\",\r\n        155: \"Tempo_153\",\r\n        156: \"Tempo_154\",\r\n        157: \"Tempo_155\",\r\n        158: \"Tempo_156\",\r\n        159: \"Tempo_157\",\r\n        160: \"Tempo_158\",\r\n        161: \"Tempo_159\",\r\n        162: \"Tempo_160\",\r\n        163: \"Tempo_161\",\r\n        164: \"Tempo_162\",\r\n        165: \"Tempo_163\",\r\n        166: \"Tempo_164\",\r\n        167: \"Tempo_165\",\r\n        168: \"Tempo_166\",\r\n        169: \"Tempo_167\",\r\n        170: \"Tempo_168\",\r\n        171: \"Tempo_169\",\r\n        172: \"Tempo_170\",\r\n        173: \"Tempo_171\",\r\n        174: \"Tempo_172\",\r\n        175: \"Tempo_173\",\r\n        176: \"Tempo_174\",\r\n        177: \"Tempo_175\",\r\n        178: \"Tempo_176\",\r\n        179: \"Tempo_177\",\r\n        180: \"Tempo_178\",\r\n        181: \"Tempo_179\",\r\n        182: \"Tempo_180\",\r\n        183: \"Tempo_181\",\r\n        184: \"Tempo_182\",\r\n        185: \"Tempo_183\",\r\n        186: \"Tempo_184\",\r\n        187: \"Tempo_185\",\r\n        188: \"Tempo_186\",\r\n        189: \"Tempo_187\",\r\n        190: \"Tempo_188\",\r\n        191: \"Tempo_189\",\r\n        192: \"Tempo_190\",\r\n        193: \"Tempo_191\",\r\n        194: \"Tempo_192\",\r\n        195: \"Tempo_193\",\r\n        196: \"Tempo_194\",\r\n        197: \"Tempo_195\",\r\n        198: \"Tempo_196\",\r\n        199: \"Tempo_197\",\r\n        200: \"Tempo_198\",\r\n        201: \"Tempo_199\",\r\n        202: \"Tempo_200\",\r\n        203: \"Tempo_201\",\r\n        204: \"Tempo_202\",\r\n        205: \"Tempo_203\",\r\n        206: \"Tempo_204\",\r\n        207: \"Tempo_205\",\r\n        208: \"Tempo_206\",\r\n        209: \"Tempo_207\",\r\n        210: \"Tempo_208\",\r\n        211: \"Tempo_209\",\r\n        212: \"Tempo_210\",\r\n        213: \"Tempo_211\",\r\n        214: \"Tempo_212\",\r\n        215: \"Tempo_213\",\r\n        216: \"Tempo_214\",\r\n        217: \"Tempo_215\",\r\n        218: \"Tempo_216\",\r\n        219: \"Tempo_217\",\r\n        220: \"Tempo_218\",\r\n        221: \"Tempo_219\",\r\n        222: \"Tempo_220\",\r\n        223: \"Tempo_221\",\r\n        224: \"Tempo_222\",\r\n        225: \"Tempo_223\",\r\n        226: \"Tempo_224\",\r\n        227: \"Tempo_225\",\r\n        228: \"Tempo_226\",\r\n        229: \"Tempo_227\",\r\n        230: \"Tempo_228\",\r\n        231: \"Tempo_229\",\r\n        232: \"Tempo_230\",\r\n        233: \"Tempo_231\",\r\n        234: \"Tempo_232\",\r\n        235: \"Tempo_233\",\r\n        236: \"Tempo_234\",\r\n        237: \"Tempo_235\",\r\n        238: \"Tempo_236\",\r\n        239: \"Tempo_237\",\r\n        240: \"Tempo_238\",\r\n        241: \"Tempo_239\",\r\n        242: \"Tempo_240\",\r\n        243: \"Tempo_241\",\r\n        244: \"Tempo_242\",\r\n        245: \"Tempo_243\",\r\n        246: \"Tempo_244\",\r\n        247: \"Tempo_245\",\r\n        248: \"Tempo_246\",\r\n        249: \"Tempo_247\",\r\n        250: \"Tempo_248\",\r\n        251: \"Tempo_249\",\r\n        252: \"Tempo_250\",\r\n        253: \"Tempo_251\",\r\n        254: \"Tempo_252\",\r\n        255: \"Tempo_253\",\r\n        256: \"Tempo_254\",\r\n        257: \"Tempo_255\",\r\n        258: \"Tempo_256\",\r\n        259: \"Tempo_257\",\r\n        260: \"Tempo_258\",\r\n        261: \"Tempo_259\",\r\n        262: \"Tempo_260\",\r\n        263: \"Tempo_261\",\r\n        264: \"Tempo_262\",\r\n        265: \"Tempo_263\",\r\n        266: \"Tempo_264\",\r\n        267: \"Tempo_265\",\r\n        268: \"Tempo_266\",\r\n        269: \"Tempo_267\",\r\n        270: \"Tempo_268\",\r\n        271: \"Tempo_269\",\r\n        272: \"Tempo_270\",\r\n        273: \"Tempo_271\",\r\n        274: \"Tempo_272\",\r\n        275: \"Tempo_273\",\r\n        276: \"Tempo_274\",\r\n        277: \"Tempo_275\",\r\n        278: \"Tempo_276\",\r\n        279: \"Tempo_277\",\r\n        280: \"Tempo_278\",\r\n        281: \"Tempo_279\",\r\n        282: \"Tempo_280\",\r\n        283: \"Tempo_281\",\r\n        284: \"Tempo_282\",\r\n        285: \"Tempo_283\",\r\n        286: \"Tempo_284\",\r\n        287: \"Tempo_285\",\r\n        288: \"Tempo_286\",\r\n        289: \"Tempo_287\",\r\n        290: \"Tempo_288\",\r\n        291: \"Tempo_289\",\r\n        292: \"Tempo_290\",\r\n        293: \"Tempo_291\",\r\n        294: \"Tempo_292\",\r\n        295: \"Tempo_293\",\r\n        296: \"Tempo_294\",\r\n        297: \"Tempo_295\",\r\n        298: \"Tempo_296\",\r\n        299: \"Tempo_297\",\r\n        300: \"Tempo_298\",\r\n        301: \"Tempo_299\",\r\n        302: \"Tempo_300\",\r\n        303: \"Tempo_301\",\r\n        304: \"Tempo_302\",\r\n        305: \"Tempo_303\",\r\n        306: \"Tempo_304\",\r\n        307: \"Tempo_305\",\r\n        308: \"Tempo_306\",\r\n        309: \"Tempo_307\",\r\n        310: \"Tempo_308\",\r\n        311: \"Tempo_309\",\r\n        312: \"Tempo_310\",\r\n        313: \"Tempo_311\",\r\n        314: \"Tempo_312\",\r\n        315: \"Tempo_313\",\r\n        316: \"Tempo_314\",\r\n        317: \"Tempo_315\",\r\n        318: \"Tempo_316\",\r\n        319: \"Tempo_317\",\r\n        320: \"Tempo_318\",\r\n        321: \"Tempo_319\",\r\n        322: \"Tempo_320\",\r\n        323: \"Tempo_321\",\r\n        324: \"Tempo_322\",\r\n        325: \"Tempo_323\",\r\n        326: \"Tempo_324\",\r\n        327: \"Tempo_325\",\r\n        328: \"Tempo_326\",\r\n        329: \"Tempo_327\",\r\n        330: \"Tempo_328\",\r\n        331: \"Tempo_329\",\r\n        332: \"Tempo_330\",\r\n        333: \"Tempo_331\",\r\n        334: \"Tempo_332\",\r\n        335: \"Tempo_333\",\r\n        336: \"Tempo_334\",\r\n        337: \"Tempo_335\",\r\n        338: \"Tempo_336\",\r\n        339: \"Tempo_337\",\r\n        340: \"Tempo_338\",\r\n        341: \"Tempo_339\",\r\n        342: \"Tempo_340\",\r\n        343: \"Tempo_341\",\r\n        344: \"Tempo_342\",\r\n        345: \"Tempo_343\",\r\n        346: \"Tempo_344\",\r\n        347: \"Tempo_345\",\r\n        348: \"Tempo_346\",\r\n        349: \"Tempo_347\",\r\n        350: \"Tempo_348\",\r\n        351: \"Tempo_349\",\r\n        352: \"Tempo_350\",\r\n        353: \"Tempo_351\",\r\n        354: \"Tempo_352\",\r\n        355: \"Tempo_353\",\r\n        356: \"Tempo_354\",\r\n        357: \"Tempo_355\",\r\n        358: \"Tempo_356\",\r\n        359: \"Tempo_357\",\r\n        360: \"Tempo_358\",\r\n        361: \"Tempo_359\",\r\n        362: \"Tempo_360\"\r\n    },\r\n    \"chord\"     : {\r\n        0: \"0\",\r\n        1: \"CONTI\"\r\n    },\r\n    \"bar-beat\"  : {\r\n        0 : 0,\r\n        1 : \"Bar\",\r\n        2 : \"Beat_0\",\r\n        3 : \"Beat_1\",\r\n        4 : \"Beat_2\",\r\n        5 : \"Beat_3\",\r\n        6 : \"Beat_4\",\r\n        7 : \"Beat_5\",\r\n        8 : \"Beat_6\",\r\n        9 : \"Beat_7\",\r\n        10: \"Beat_8\",\r\n        11: \"Beat_9\",\r\n        12: \"Beat_10\",\r\n        13: \"Beat_11\",\r\n        14: \"Beat_12\",\r\n        15: \"Beat_13\",\r\n        16: \"Beat_14\",\r\n        17: \"Beat_15\"\r\n    },\r\n    \"type\"      : {\r\n        0: \"EOS\",\r\n        1: \"Metrical\",\r\n        2: \"Note\",\r\n        3: \"Seg\",\r\n    },\r\n    \"instr_type\": {\r\n        0: 'None',\r\n        1: 'Drums',\r\n        2: 'Piano',\r\n        3: 'Guitar',\r\n        4: 'Bass',\r\n        5: 'Strings',\r\n    },\r\n    \"pitch\"     : {\r\n        0  : 0,\r\n        1  : \"Note_Pitch_0\",\r\n        2  : \"Note_Pitch_1\",\r\n        3  : \"Note_Pitch_2\",\r\n        4  : \"Note_Pitch_3\",\r\n        5  : \"Note_Pitch_4\",\r\n        6  : \"Note_Pitch_5\",\r\n        7  : \"Note_Pitch_6\",\r\n        8  : \"Note_Pitch_7\",\r\n        9  : \"Note_Pitch_8\",\r\n        10 : \"Note_Pitch_9\",\r\n        11 : \"Note_Pitch_10\",\r\n        12 : \"Note_Pitch_11\",\r\n        13 : \"Note_Pitch_12\",\r\n        14 : \"Note_Pitch_13\",\r\n        15 : \"Note_Pitch_14\",\r\n        16 : \"Note_Pitch_15\",\r\n        17 : \"Note_Pitch_16\",\r\n        18 : \"Note_Pitch_17\",\r\n        19 : \"Note_Pitch_18\",\r\n        20 : \"Note_Pitch_19\",\r\n        21 : \"Note_Pitch_20\",\r\n        22 : \"Note_Pitch_21\",\r\n        23 : \"Note_Pitch_22\",\r\n        24 : \"Note_Pitch_23\",\r\n        25 : \"Note_Pitch_24\",\r\n        26 : \"Note_Pitch_25\",\r\n        27 : \"Note_Pitch_26\",\r\n        28 : \"Note_Pitch_27\",\r\n        29 : \"Note_Pitch_28\",\r\n        30 : \"Note_Pitch_29\",\r\n        31 : \"Note_Pitch_30\",\r\n        32 : \"Note_Pitch_31\",\r\n        33 : \"Note_Pitch_32\",\r\n        34 : \"Note_Pitch_33\",\r\n        35 : \"Note_Pitch_34\",\r\n        36 : \"Note_Pitch_35\",\r\n        37 : \"Note_Pitch_36\",\r\n        38 : \"Note_Pitch_37\",\r\n        39 : \"Note_Pitch_38\",\r\n        40 : \"Note_Pitch_39\",\r\n        41 : \"Note_Pitch_40\",\r\n        42 : \"Note_Pitch_41\",\r\n        43 : \"Note_Pitch_42\",\r\n        44 : \"Note_Pitch_43\",\r\n        45 : \"Note_Pitch_44\",\r\n        46 : \"Note_Pitch_45\",\r\n        47 : \"Note_Pitch_46\",\r\n        48 : \"Note_Pitch_47\",\r\n        49 : \"Note_Pitch_48\",\r\n        50 : \"Note_Pitch_49\",\r\n        51 : \"Note_Pitch_50\",\r\n        52 : \"Note_Pitch_51\",\r\n        53 : \"Note_Pitch_52\",\r\n        54 : \"Note_Pitch_53\",\r\n        55 : \"Note_Pitch_54\",\r\n        56 : \"Note_Pitch_55\",\r\n        57 : \"Note_Pitch_56\",\r\n        58 : \"Note_Pitch_57\",\r\n        59 : \"Note_Pitch_58\",\r\n        60 : \"Note_Pitch_59\",\r\n        61 : \"Note_Pitch_60\",\r\n        62 : \"Note_Pitch_61\",\r\n        63 : \"Note_Pitch_62\",\r\n        64 : \"Note_Pitch_63\",\r\n        65 : \"Note_Pitch_64\",\r\n        66 : \"Note_Pitch_65\",\r\n        67 : \"Note_Pitch_66\",\r\n        68 : \"Note_Pitch_67\",\r\n        69 : \"Note_Pitch_68\",\r\n        70 : \"Note_Pitch_69\",\r\n        71 : \"Note_Pitch_70\",\r\n        72 : \"Note_Pitch_71\",\r\n        73 : \"Note_Pitch_72\",\r\n        74 : \"Note_Pitch_73\",\r\n        75 : \"Note_Pitch_74\",\r\n        76 : \"Note_Pitch_75\",\r\n        77 : \"Note_Pitch_76\",\r\n        78 : \"Note_Pitch_77\",\r\n        79 : \"Note_Pitch_78\",\r\n        80 : \"Note_Pitch_79\",\r\n        81 : \"Note_Pitch_80\",\r\n        82 : \"Note_Pitch_81\",\r\n        83 : \"Note_Pitch_82\",\r\n        84 : \"Note_Pitch_83\",\r\n        85 : \"Note_Pitch_84\",\r\n        86 : \"Note_Pitch_85\",\r\n        87 : \"Note_Pitch_86\",\r\n        88 : \"Note_Pitch_87\",\r\n        89 : \"Note_Pitch_88\",\r\n        90 : \"Note_Pitch_89\",\r\n        91 : \"Note_Pitch_90\",\r\n        92 : \"Note_Pitch_91\",\r\n        93 : \"Note_Pitch_92\",\r\n        94 : \"Note_Pitch_93\",\r\n        95 : \"Note_Pitch_94\",\r\n        96 : \"Note_Pitch_95\",\r\n        97 : \"Note_Pitch_96\",\r\n        98 : \"Note_Pitch_97\",\r\n        99 : \"Note_Pitch_98\",\r\n        100: \"Note_Pitch_99\",\r\n        101: \"Note_Pitch_100\",\r\n        102: \"Note_Pitch_101\",\r\n        103: \"Note_Pitch_102\",\r\n        104: \"Note_Pitch_103\",\r\n        105: \"Note_Pitch_104\",\r\n        106: \"Note_Pitch_105\",\r\n        107: \"Note_Pitch_106\",\r\n        108: \"Note_Pitch_107\",\r\n        109: \"Note_Pitch_108\",\r\n        110: \"Note_Pitch_109\",\r\n        111: \"Note_Pitch_110\",\r\n        112: \"Note_Pitch_111\",\r\n        113: \"Note_Pitch_112\",\r\n        114: \"Note_Pitch_113\",\r\n        115: \"Note_Pitch_114\",\r\n        116: \"Note_Pitch_115\",\r\n        117: \"Note_Pitch_116\",\r\n        118: \"Note_Pitch_117\",\r\n        119: \"Note_Pitch_118\",\r\n        120: \"Note_Pitch_119\",\r\n        121: \"Note_Pitch_120\",\r\n        122: \"Note_Pitch_121\",\r\n        123: \"Note_Pitch_122\",\r\n        124: \"Note_Pitch_123\",\r\n        125: \"Note_Pitch_124\",\r\n        126: \"Note_Pitch_125\",\r\n        127: \"Note_Pitch_126\",\r\n        128: \"Note_Pitch_127\",\r\n        129: \"Note_Pitch_128\",\r\n    },\r\n    \"duration\"  : {\r\n        0 : 0,\r\n        1 : \"Note_Duration_0\",\r\n        2 : \"Note_Duration_120\",\r\n        3 : \"Note_Duration_240\",\r\n        4 : \"Note_Duration_360\",\r\n        5 : \"Note_Duration_480\",\r\n        6 : \"Note_Duration_600\",\r\n        7 : \"Note_Duration_720\",\r\n        8 : \"Note_Duration_840\",\r\n        9 : \"Note_Duration_960\",\r\n        10: \"Note_Duration_1080\",\r\n        11: \"Note_Duration_1200\",\r\n        12: \"Note_Duration_1320\",\r\n        13: \"Note_Duration_1440\",\r\n        14: \"Note_Duration_1560\",\r\n        15: \"Note_Duration_1680\",\r\n        16: \"Note_Duration_1800\",\r\n        17: \"Note_Duration_1920\"\r\n    },\r\n    \"velocity\"  : {\r\n        0  : 0,\r\n        1  : \"Note_Velocity_0\",\r\n        2  : \"Note_Velocity_1\",\r\n        3  : \"Note_Velocity_2\",\r\n        4  : \"Note_Velocity_3\",\r\n        5  : \"Note_Velocity_4\",\r\n        6  : \"Note_Velocity_5\",\r\n        7  : \"Note_Velocity_6\",\r\n        8  : \"Note_Velocity_7\",\r\n        9  : \"Note_Velocity_8\",\r\n        10 : \"Note_Velocity_9\",\r\n        11 : \"Note_Velocity_10\",\r\n        12 : \"Note_Velocity_11\",\r\n        13 : \"Note_Velocity_12\",\r\n        14 : \"Note_Velocity_13\",\r\n        15 : \"Note_Velocity_14\",\r\n        16 : \"Note_Velocity_15\",\r\n        17 : \"Note_Velocity_16\",\r\n        18 : \"Note_Velocity_17\",\r\n        19 : \"Note_Velocity_18\",\r\n        20 : \"Note_Velocity_19\",\r\n        21 : \"Note_Velocity_20\",\r\n        22 : \"Note_Velocity_21\",\r\n        23 : \"Note_Velocity_22\",\r\n        24 : \"Note_Velocity_23\",\r\n        25 : \"Note_Velocity_24\",\r\n        26 : \"Note_Velocity_25\",\r\n        27 : \"Note_Velocity_26\",\r\n        28 : \"Note_Velocity_27\",\r\n        29 : \"Note_Velocity_28\",\r\n        30 : \"Note_Velocity_29\",\r\n        31 : \"Note_Velocity_30\",\r\n        32 : \"Note_Velocity_31\",\r\n        33 : \"Note_Velocity_32\",\r\n        34 : \"Note_Velocity_33\",\r\n        35 : \"Note_Velocity_34\",\r\n        36 : \"Note_Velocity_35\",\r\n        37 : \"Note_Velocity_36\",\r\n        38 : \"Note_Velocity_37\",\r\n        39 : \"Note_Velocity_38\",\r\n        40 : \"Note_Velocity_39\",\r\n        41 : \"Note_Velocity_40\",\r\n        42 : \"Note_Velocity_41\",\r\n        43 : \"Note_Velocity_42\",\r\n        44 : \"Note_Velocity_43\",\r\n        45 : \"Note_Velocity_44\",\r\n        46 : \"Note_Velocity_45\",\r\n        47 : \"Note_Velocity_46\",\r\n        48 : \"Note_Velocity_47\",\r\n        49 : \"Note_Velocity_48\",\r\n        50 : \"Note_Velocity_49\",\r\n        51 : \"Note_Velocity_50\",\r\n        52 : \"Note_Velocity_51\",\r\n        53 : \"Note_Velocity_52\",\r\n        54 : \"Note_Velocity_53\",\r\n        55 : \"Note_Velocity_54\",\r\n        56 : \"Note_Velocity_55\",\r\n        57 : \"Note_Velocity_56\",\r\n        58 : \"Note_Velocity_57\",\r\n        59 : \"Note_Velocity_58\",\r\n        60 : \"Note_Velocity_59\",\r\n        61 : \"Note_Velocity_60\",\r\n        62 : \"Note_Velocity_61\",\r\n        63 : \"Note_Velocity_62\",\r\n        64 : \"Note_Velocity_63\",\r\n        65 : \"Note_Velocity_64\",\r\n        66 : \"Note_Velocity_65\",\r\n        67 : \"Note_Velocity_66\",\r\n        68 : \"Note_Velocity_67\",\r\n        69 : \"Note_Velocity_68\",\r\n        70 : \"Note_Velocity_69\",\r\n        71 : \"Note_Velocity_70\",\r\n        72 : \"Note_Velocity_71\",\r\n        73 : \"Note_Velocity_72\",\r\n        74 : \"Note_Velocity_73\",\r\n        75 : \"Note_Velocity_74\",\r\n        76 : \"Note_Velocity_75\",\r\n        77 : \"Note_Velocity_76\",\r\n        78 : \"Note_Velocity_77\",\r\n        79 : \"Note_Velocity_78\",\r\n        80 : \"Note_Velocity_79\",\r\n        81 : \"Note_Velocity_80\",\r\n        82 : \"Note_Velocity_81\",\r\n        83 : \"Note_Velocity_82\",\r\n        84 : \"Note_Velocity_83\",\r\n        85 : \"Note_Velocity_84\",\r\n        86 : \"Note_Velocity_85\",\r\n        87 : \"Note_Velocity_86\",\r\n        88 : \"Note_Velocity_87\",\r\n        89 : \"Note_Velocity_88\",\r\n        90 : \"Note_Velocity_89\",\r\n        91 : \"Note_Velocity_90\",\r\n        92 : \"Note_Velocity_91\",\r\n        93 : \"Note_Velocity_92\",\r\n        94 : \"Note_Velocity_93\",\r\n        95 : \"Note_Velocity_94\",\r\n        96 : \"Note_Velocity_95\",\r\n        97 : \"Note_Velocity_96\",\r\n        98 : \"Note_Velocity_97\",\r\n        99 : \"Note_Velocity_98\",\r\n        100: \"Note_Velocity_99\",\r\n        101: \"Note_Velocity_100\",\r\n        102: \"Note_Velocity_101\",\r\n        103: \"Note_Velocity_102\",\r\n        104: \"Note_Velocity_103\",\r\n        105: \"Note_Velocity_104\",\r\n        106: \"Note_Velocity_105\",\r\n        107: \"Note_Velocity_106\",\r\n        108: \"Note_Velocity_107\",\r\n        109: \"Note_Velocity_108\",\r\n        110: \"Note_Velocity_109\",\r\n        111: \"Note_Velocity_110\",\r\n        112: \"Note_Velocity_111\",\r\n        113: \"Note_Velocity_112\",\r\n        114: \"Note_Velocity_113\",\r\n        115: \"Note_Velocity_114\",\r\n        116: \"Note_Velocity_115\",\r\n        117: \"Note_Velocity_116\",\r\n        118: \"Note_Velocity_117\",\r\n        119: \"Note_Velocity_118\",\r\n        120: \"Note_Velocity_119\",\r\n        121: \"Note_Velocity_120\",\r\n        122: \"Note_Velocity_121\",\r\n        123: \"Note_Velocity_122\",\r\n        124: \"Note_Velocity_123\",\r\n        125: \"Note_Velocity_124\",\r\n        126: \"Note_Velocity_125\",\r\n        127: \"Note_Velocity_126\",\r\n        128: \"Note_Velocity_127\",\r\n        129: \"Note_Velocity_128\",\r\n        130: \"Note_Velocity_129\",\r\n        131: \"Note_Velocity_130\",\r\n        132: \"Note_Velocity_131\",\r\n        133: \"Note_Velocity_132\",\r\n        134: \"Note_Velocity_133\",\r\n        135: \"Note_Velocity_134\",\r\n        136: \"Note_Velocity_135\",\r\n        137: \"Note_Velocity_136\",\r\n        138: \"Note_Velocity_137\",\r\n        139: \"Note_Velocity_138\",\r\n        140: \"Note_Velocity_139\",\r\n        141: \"Note_Velocity_140\",\r\n        142: \"Note_Velocity_141\",\r\n        143: \"Note_Velocity_142\",\r\n        144: \"Note_Velocity_143\",\r\n        145: \"Note_Velocity_144\",\r\n        146: \"Note_Velocity_145\",\r\n        147: \"Note_Velocity_146\",\r\n        148: \"Note_Velocity_147\",\r\n        149: \"Note_Velocity_148\",\r\n        150: \"Note_Velocity_149\",\r\n        151: \"Note_Velocity_150\",\r\n        152: \"Note_Velocity_151\",\r\n        153: \"Note_Velocity_152\",\r\n        154: \"Note_Velocity_153\",\r\n        155: \"Note_Velocity_154\",\r\n        156: \"Note_Velocity_155\",\r\n        157: \"Note_Velocity_156\",\r\n        158: \"Note_Velocity_157\",\r\n        159: \"Note_Velocity_158\",\r\n        160: \"Note_Velocity_159\",\r\n        161: \"Note_Velocity_160\",\r\n        162: \"Note_Velocity_161\",\r\n        163: \"Note_Velocity_162\",\r\n        164: \"Note_Velocity_163\",\r\n        165: \"Note_Velocity_164\",\r\n        166: \"Note_Velocity_165\",\r\n        167: \"Note_Velocity_166\",\r\n        168: \"Note_Velocity_167\",\r\n        169: \"Note_Velocity_168\",\r\n        170: \"Note_Velocity_169\",\r\n        171: \"Note_Velocity_170\",\r\n        172: \"Note_Velocity_171\",\r\n        173: \"Note_Velocity_172\",\r\n        174: \"Note_Velocity_173\",\r\n        175: \"Note_Velocity_174\",\r\n        176: \"Note_Velocity_175\",\r\n        177: \"Note_Velocity_176\",\r\n        178: \"Note_Velocity_177\",\r\n        179: \"Note_Velocity_178\",\r\n        180: \"Note_Velocity_179\",\r\n        181: \"Note_Velocity_180\",\r\n        182: \"Note_Velocity_181\",\r\n        183: \"Note_Velocity_182\",\r\n        184: \"Note_Velocity_183\",\r\n        185: \"Note_Velocity_184\",\r\n        186: \"Note_Velocity_185\",\r\n        187: \"Note_Velocity_186\",\r\n        188: \"Note_Velocity_187\",\r\n        189: \"Note_Velocity_188\",\r\n        190: \"Note_Velocity_189\",\r\n        191: \"Note_Velocity_190\",\r\n        192: \"Note_Velocity_191\",\r\n        193: \"Note_Velocity_192\",\r\n        194: \"Note_Velocity_193\",\r\n        195: \"Note_Velocity_194\",\r\n        196: \"Note_Velocity_195\",\r\n        197: \"Note_Velocity_196\",\r\n        198: \"Note_Velocity_197\",\r\n        199: \"Note_Velocity_198\",\r\n        200: \"Note_Velocity_199\",\r\n        201: \"Note_Velocity_200\",\r\n        202: \"Note_Velocity_201\",\r\n        203: \"Note_Velocity_202\",\r\n        204: \"Note_Velocity_203\",\r\n        205: \"Note_Velocity_204\",\r\n        206: \"Note_Velocity_205\",\r\n        207: \"Note_Velocity_206\",\r\n        208: \"Note_Velocity_207\",\r\n        209: \"Note_Velocity_208\",\r\n        210: \"Note_Velocity_209\",\r\n        211: \"Note_Velocity_210\",\r\n        212: \"Note_Velocity_211\",\r\n        213: \"Note_Velocity_212\",\r\n        214: \"Note_Velocity_213\",\r\n        215: \"Note_Velocity_214\",\r\n        216: \"Note_Velocity_215\",\r\n        217: \"Note_Velocity_216\",\r\n        218: \"Note_Velocity_217\",\r\n        219: \"Note_Velocity_218\",\r\n        220: \"Note_Velocity_219\",\r\n        221: \"Note_Velocity_220\",\r\n        222: \"Note_Velocity_221\",\r\n        223: \"Note_Velocity_222\",\r\n        224: \"Note_Velocity_223\",\r\n        225: \"Note_Velocity_224\",\r\n        226: \"Note_Velocity_225\",\r\n        227: \"Note_Velocity_226\",\r\n        228: \"Note_Velocity_227\",\r\n        229: \"Note_Velocity_228\",\r\n        230: \"Note_Velocity_229\",\r\n        231: \"Note_Velocity_230\",\r\n        232: \"Note_Velocity_231\",\r\n        233: \"Note_Velocity_232\",\r\n        234: \"Note_Velocity_233\",\r\n        235: \"Note_Velocity_234\",\r\n        236: \"Note_Velocity_235\",\r\n        237: \"Note_Velocity_236\",\r\n        238: \"Note_Velocity_237\",\r\n        239: \"Note_Velocity_238\",\r\n        240: \"Note_Velocity_239\",\r\n        241: \"Note_Velocity_240\",\r\n        242: \"Note_Velocity_241\",\r\n        243: \"Note_Velocity_242\",\r\n        244: \"Note_Velocity_243\",\r\n        245: \"Note_Velocity_244\",\r\n        246: \"Note_Velocity_245\",\r\n        247: \"Note_Velocity_246\",\r\n        248: \"Note_Velocity_247\",\r\n        249: \"Note_Velocity_248\",\r\n        250: \"Note_Velocity_249\",\r\n        251: \"Note_Velocity_250\",\r\n        252: \"Note_Velocity_251\",\r\n        253: \"Note_Velocity_252\",\r\n        254: \"Note_Velocity_253\",\r\n        255: \"Note_Velocity_254\",\r\n        256: \"Note_Velocity_255\",\r\n        257: \"Note_Velocity_256\",\r\n        258: \"Note_Velocity_257\",\r\n        259: \"Note_Velocity_258\",\r\n        260: \"Note_Velocity_259\",\r\n        261: \"Note_Velocity_260\",\r\n        262: \"Note_Velocity_261\",\r\n        263: \"Note_Velocity_262\",\r\n        264: \"Note_Velocity_263\",\r\n        265: \"Note_Velocity_264\",\r\n        266: \"Note_Velocity_265\",\r\n        267: \"Note_Velocity_266\",\r\n        268: \"Note_Velocity_267\",\r\n        269: \"Note_Velocity_268\",\r\n        270: \"Note_Velocity_269\",\r\n        271: \"Note_Velocity_270\",\r\n        272: \"Note_Velocity_271\",\r\n        273: \"Note_Velocity_272\",\r\n        274: \"Note_Velocity_273\",\r\n        275: \"Note_Velocity_274\",\r\n        276: \"Note_Velocity_275\",\r\n        277: \"Note_Velocity_276\",\r\n        278: \"Note_Velocity_277\",\r\n        279: \"Note_Velocity_278\",\r\n        280: \"Note_Velocity_279\",\r\n        281: \"Note_Velocity_280\",\r\n        282: \"Note_Velocity_281\",\r\n        283: \"Note_Velocity_282\",\r\n        284: \"Note_Velocity_283\",\r\n        285: \"Note_Velocity_284\",\r\n        286: \"Note_Velocity_285\",\r\n        287: \"Note_Velocity_286\",\r\n        288: \"Note_Velocity_287\",\r\n        289: \"Note_Velocity_288\",\r\n        290: \"Note_Velocity_289\",\r\n        291: \"Note_Velocity_290\",\r\n        292: \"Note_Velocity_291\",\r\n        293: \"Note_Velocity_292\",\r\n        294: \"Note_Velocity_293\",\r\n        295: \"Note_Velocity_294\",\r\n        296: \"Note_Velocity_295\",\r\n        297: \"Note_Velocity_296\",\r\n        298: \"Note_Velocity_297\",\r\n        299: \"Note_Velocity_298\",\r\n        300: \"Note_Velocity_299\",\r\n        301: \"Note_Velocity_300\",\r\n        302: \"Note_Velocity_301\",\r\n        303: \"Note_Velocity_302\",\r\n        304: \"Note_Velocity_303\",\r\n        305: \"Note_Velocity_304\",\r\n        306: \"Note_Velocity_305\",\r\n        307: \"Note_Velocity_306\",\r\n        308: \"Note_Velocity_307\",\r\n        309: \"Note_Velocity_308\",\r\n        310: \"Note_Velocity_309\",\r\n        311: \"Note_Velocity_310\",\r\n        312: \"Note_Velocity_311\",\r\n        313: \"Note_Velocity_312\",\r\n        314: \"Note_Velocity_313\",\r\n        315: \"Note_Velocity_314\",\r\n        316: \"Note_Velocity_315\",\r\n        317: \"Note_Velocity_316\",\r\n        318: \"Note_Velocity_317\",\r\n        319: \"Note_Velocity_318\",\r\n        320: \"Note_Velocity_319\",\r\n        321: \"Note_Velocity_320\",\r\n        322: \"Note_Velocity_321\",\r\n        323: \"Note_Velocity_322\",\r\n        324: \"Note_Velocity_323\",\r\n        325: \"Note_Velocity_324\",\r\n        326: \"Note_Velocity_325\",\r\n        327: \"Note_Velocity_326\",\r\n        328: \"Note_Velocity_327\",\r\n        329: \"Note_Velocity_328\",\r\n        330: \"Note_Velocity_329\",\r\n        331: \"Note_Velocity_330\",\r\n        332: \"Note_Velocity_331\",\r\n        333: \"Note_Velocity_332\",\r\n        334: \"Note_Velocity_333\",\r\n        335: \"Note_Velocity_334\",\r\n        336: \"Note_Velocity_335\",\r\n        337: \"Note_Velocity_336\",\r\n        338: \"Note_Velocity_337\",\r\n        339: \"Note_Velocity_338\",\r\n        340: \"Note_Velocity_339\",\r\n        341: \"Note_Velocity_340\",\r\n        342: \"Note_Velocity_341\",\r\n        343: \"Note_Velocity_342\",\r\n        344: \"Note_Velocity_343\",\r\n        345: \"Note_Velocity_344\",\r\n        346: \"Note_Velocity_345\",\r\n        347: \"Note_Velocity_346\",\r\n        348: \"Note_Velocity_347\",\r\n        349: \"Note_Velocity_348\",\r\n        350: \"Note_Velocity_349\",\r\n        351: \"Note_Velocity_350\",\r\n        352: \"Note_Velocity_351\",\r\n        353: \"Note_Velocity_352\",\r\n        354: \"Note_Velocity_353\",\r\n        355: \"Note_Velocity_354\",\r\n        356: \"Note_Velocity_355\",\r\n        357: \"Note_Velocity_356\",\r\n        358: \"Note_Velocity_357\",\r\n        359: \"Note_Velocity_358\",\r\n        360: \"Note_Velocity_359\",\r\n        361: \"Note_Velocity_360\"\r\n    },\r\n    \"boundary\"  : {\r\n        0: 0,\r\n        1: \"None\",\r\n        2: \"Boundary\",\r\n    },\r\n    \"key\"       : {\r\n        0 : 0,\r\n        1 : \"None\",\r\n        2 : 'C',\r\n        3 : 'C#',\r\n        4 : 'D',\r\n        5 : 'D#',\r\n        6 : 'E',\r\n        7 : 'F',\r\n        8 : 'F#',\r\n        9 : 'G',\r\n        10: 'G#',\r\n        11: 'A',\r\n        12: 'A#',\r\n        13: 'B',\r\n        14: 'c',\r\n        15: 'c#',\r\n        16: 'd',\r\n        17: 'd#',\r\n        18: 'e',\r\n        19: 'f',\r\n        20: 'f#',\r\n        21: 'g',\r\n        22: 'g#',\r\n        23: 'a',\r\n        24: 'a#',\r\n        25: 'b',\r\n    }\r\n}\r\n\r\ninit_dictionary = {\r\n    \"instr_type\": {\r\n        'None'   : 0,\r\n        'Drums'  : 1,\r\n        'Piano'  : 2,\r\n        'Guitar' : 3,\r\n        'Bass'   : 4,\r\n        'Strings': 5,\r\n    },\r\n    \"key\"       : {\r\n        \"None\": 0,\r\n        'C'   : 1,\r\n        'C#'  : 2,\r\n        'D'   : 3,\r\n        'D#'  : 4,\r\n        'E'   : 5,\r\n        'F'   : 6,\r\n        'F#'  : 7,\r\n        'G'   : 8,\r\n        'G#'  : 9,\r\n        'A'   : 10,\r\n        'A#'  : 11,\r\n        'B'   : 12,\r\n        'c'   : 13,\r\n        'c#'  : 14,\r\n        'd'   : 15,\r\n        'd#'  : 16,\r\n        'e'   : 17,\r\n        'f'   : 18,\r\n        'f#'  : 19,\r\n        'g'   : 20,\r\n        'g#'  : 21,\r\n        'a'   : 22,\r\n        'a#'  : 23,\r\n        'b'   : 24,\r\n    },\r\n    \"genre\"     : {\r\n        \"None\"      : 0,\r\n        'Metal'     : 1,\r\n        'Country'   : 2,\r\n        'dance'     : 3,\r\n        'Electronic': 4,\r\n        'Pop'       : 5,\r\n        'Rock'      : 6,\r\n    }\r\n}\r\n\r\ngenre = {\r\n    'Metal'     : 1,\r\n    'Country'   : 2,\r\n    'dance'     : 3,\r\n    'Electronic': 4,\r\n    'Pop'       : 5,\r\n    'Rock'      : 6,\r\n}"
  },
  {
    "path": "src/gen_midi_conditional.py",
    "content": "import sys\nimport os\n\nimport time\nimport glob\nimport numpy as np\n\nimport torch\nimport argparse\n\nsys.path.append(\"../dataset/\")\n\nfrom numpy2midi_mix import numpy2midi\nfrom model import CMT\n\n\ndef cal_control_error(err_note_number_list, err_beat_number_list):\n    print(\"err_note_number_list\", err_note_number_list)\n    print(\"err_beat_number_list\", err_beat_number_list)\n    print(\"strength control error\", np.mean(err_note_number_list) / 1.83)\n    print(\"density control error\", np.mean(err_beat_number_list) / 10.90)\n\n\ndef generate():\n    # path\n    parser = argparse.ArgumentParser(description=\"Args for generating background music\")\n    parser.add_argument('-c', '--ckpt', default=\"../exp/loss_8_params.pt\", help=\"Model checkpoint to be loaded\")\n    parser.add_argument('-f', '--files', required=True, help=\"Input npz file of a video\")\n    parser.add_argument('-g', '--gpus', help=\"Id of gpu. Only ONE gpu is needed\")\n    parser.add_argument('-n', '--num_songs', default=1, help=\"Number of generated songs\")\n    args = parser.parse_args()\n    \n    num_songs = int(args.num_songs)\n\n    if args.gpus is not None:\n        if not args.gpus.isnumeric():\n            raise RuntimeError('Only 1 GPU is needed for inference')\n        os.environ['CUDA_VISIBLE_DEVICES'] = args.gpus\n    else:\n        os.environ['CUDA_VISIBLE_DEVICES'] = '0'\n\n    path_saved_ckpt = args.ckpt\n    filelist = glob.glob(args.files)\n\n\n    # change this if using another training set (see the output of decoder_n_class in train.py)\n    decoder_n_class = [18, 3, 18, 129, 18, 6, 20, 102, 5025] \n    init_n_token = [7, 1, 6]\n\n\n    # init model\n    net = torch.nn.DataParallel(CMT(decoder_n_class, init_n_token))\n\n    # load model\n    print('[*] load model from:', path_saved_ckpt)\n    if torch.cuda.is_available():\n        net.cuda()\n        net.eval()\n        net.load_state_dict(torch.load(path_saved_ckpt))\n    else:\n        net.eval()\n        net.load_state_dict(torch.load(path_saved_ckpt, map_location=torch.device('cpu')))\n\n    if len(filelist) == 0:\n        raise RuntimeError('no npz file in ' + str(filelist))\n\n    for file_name in filelist:\n        # gen\n        start_time = time.time()\n        song_time_list = []\n        words_len_list = []\n\n        sidx = 0\n\n        while sidx < num_songs:\n            try:\n                print(\"new song\")\n                start_time = time.time()\n                vlog_npz = np.load(file_name)['input']\n\n                vlog_npz = vlog_npz[vlog_npz[:, 2] != 1]\n                print(vlog_npz)\n\n                res, err_note_number_list, err_beat_number_list = net(is_train=False, vlog=vlog_npz, C=0.7)\n\n                cal_control_error(err_note_number_list, err_beat_number_list)\n\n                numpy2midi(f\"{file_name}_{sidx}\", res[:, [1, 0, 2, 3, 4, 5, 6]].astype(np.int32))\n                song_time = time.time() - start_time\n                word_len = len(res)\n                print('song time:', song_time)\n                print('word_len:', word_len)\n                words_len_list.append(word_len)\n                song_time_list.append(song_time)\n\n                sidx += 1\n            except KeyboardInterrupt:\n                raise ValueError(' [x] terminated.')\n\n\nif __name__ == '__main__':\n    print(\"inference\")\n    generate()\n"
  },
  {
    "path": "src/match.py",
    "content": "import argparse\nfrom tqdm import tqdm\nimport numpy as np\n\n\ndef _get_density(bar_word):\n    assert _is_bar_word(bar_word)\n    if len(bar_word) == 10:\n        return bar_word[2] - 1\n    elif len(bar_word) == 6:\n        return bar_word[1] - 1\n    else:\n        raise NotImplementedError\n\n\ndef _get_strength_and_tick(beat_word):\n    assert _is_beat_word(beat_word)\n    if len(beat_word) == 10:\n        return beat_word[6], beat_word[1] - 1\n    elif len(beat_word) == 6:\n        return beat_word[2], beat_word[0] - 1\n    else:\n        raise NotImplementedError\n\n\ndef _is_bar_word(word):\n    if len(word) == 10:\n        return word[0] == 1 and word[1] == 17\n    elif len(word) == 6:\n        return word[0] == 17\n    else:\n        raise NotImplementedError\n\n\ndef _is_beat_word(word):\n    if len(word) == 10:\n        return word[0] == 1 and word[1] > 0 and word[1] < 17\n    elif len(word) == 6:\n        return word[0] > 0 and word[0] < 17\n    else:\n        raise NotImplementedError\n\n\ndef _get_density_and_strength_from_npz(npz):\n    l_density = []\n    l_strength = []\n    for word in npz:\n        if _is_bar_word(word):\n            l_density.append(_get_density(word))\n            l_strength.append([0] * 16)\n        elif _is_beat_word(word):\n            strength, tick = _get_strength_and_tick(word)\n            l_strength[-1][tick] = strength\n    return np.asarray(l_density), np.asarray(l_strength)\n\n\ndef cal_matchness(midi_npz, v_density, v_strength):\n    m_density, m_strength = _get_density_and_strength_from_npz(midi_npz)\n\n    n_bar = min(v_density.shape[0], m_density.shape[0])\n    v_density = v_density[:n_bar]\n    v_strength = v_strength[:n_bar]\n    m_density = m_density[:n_bar]\n    m_strength = m_strength[:n_bar]\n\n    m_strength *= (v_strength > 0)\n    dist = ((v_density - m_density) ** 2).mean() + ((v_strength - m_strength) ** 2).mean()\n    return 1. / dist\n\n\ndef match_midi(video_npz, all_midi_metadata, all_midi_npz):\n    res = []\n    v_density, v_strength = _get_density_and_strength_from_npz(video_npz)\n\n    print('Computing matching scores:')\n    for i, midi_npz in enumerate(tqdm(all_midi_npz)):\n        matchess = cal_matchness(midi_npz, v_density, v_strength)\n        res.append((all_midi_metadata[i]['id'], matchess))\n    res.sort(key=lambda x: x[1], reverse=True)\n\n    print('IDs and matching scores of the 5 most matching music pieces:')\n    for i in range(5):\n        print(res[i][0], res[i][1])\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('video', default='../inference/wzk.npz', help='Video npz path')\n    parser.add_argument('music_lib', default='../dataset/lpd_5_prcem_mix_v8_10000.npz', help='Music npz path')\n    args = parser.parse_args()\n\n    video_npz = np.load(args.video, allow_pickle=True)['input']\n    tmp = np.load(args.music_lib, allow_pickle=True)\n    all_midi_metadata = tmp['metadata']\n    all_midi_npz = tmp['x']\n    del tmp\n    match_midi(video_npz, all_midi_metadata, all_midi_npz)"
  },
  {
    "path": "src/midi2mp3.py",
    "content": "import note_seq\nfrom pretty_midi import PrettyMIDI\nimport midi2audio\nimport argparse\n\nSAMPLE_RATE = 16000\nSF2_PATH = '../SGM-v2.01-Sal-Guit-Bass-V1.3.sf2'\n\n\ndef midi_to_mp3(midi_path, tempo, mp3_path):\n    midi_obj = PrettyMIDI(midi_path)\n    # convert tempo\n    midi_length = midi_obj.get_end_time()\n    midi_obj.adjust_times([0, midi_length], [0, midi_length*120/tempo])\n    processed_mid = midi_path[:-4] + \"_processed.mid\"\n    midi_obj.write(processed_mid)\n\n    print(\"converting into mp3\")\n    fs = midi2audio.FluidSynth(SF2_PATH, sample_rate=SAMPLE_RATE)\n    fs.midi_to_audio(processed_mid, mp3_path)\n    \n    print(\"playing music\")\n    \n    ns = note_seq.midi_io.midi_to_note_sequence(midi_obj)\n    note_seq.play_sequence(ns, synth=note_seq.fluidsynth, sample_rate=SAMPLE_RATE, sf2_path=SF2_PATH)\n    note_seq.plot_sequence(ns)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--input\", default=\"../inference/get_0.mid\")\n    parser.add_argument(\"--tempo\", default=\"96\")\n    parser.add_argument(\"--output\", default=\"../inference/get_0.mp3\")\n    args = parser.parse_args()\n    midi_to_mp3(args.input, float(args.tempo), args.output)\n"
  },
  {
    "path": "src/midi2numpy_mix.py",
    "content": "import os\nimport math\nimport json\n\nimport muspy\nimport numpy as np\nfrom tqdm import tqdm\nimport argparse\n\nfrom dictionary_mix import preset_event2word, preset_word2event\n\n#np.random.seed(208)\n\nRESOLUTION = 16  # 每小节16个时间单位\nDECODER_MAX_LEN = 10000\n# DECODER_MAX_LEN = 3000\nDECODER_DIMENSION = {\n    'type'      : 0,\n    'beat'      : 1,\n    'density'   : 2,\n    'pitch'     : 3,\n    'duration'  : 4,\n    'instr_type': 5,\n    'strength'  : 6,\n    'i_beat'    : 7,\n    'n_beat'    : 8,\n    'p_beat'    : 9,\n}\nN_DECODER_DIMENSION = len(DECODER_DIMENSION)\nKEYS = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g',\n        'g#', 'a', 'a#', 'b']\n\n\nclass Note:\n    def __init__(self, muspy_note=None, instr_type=None):  # bar starts from 0\n        if muspy_note is not None and instr_type is not None:\n            self.time = muspy_note.time\n            self.bar = self.time // RESOLUTION  # 从0开始\n            self.beat = muspy_note.time % RESOLUTION  # 小节内部的第几个beat\n            self.i_beat = self.bar * RESOLUTION + self.beat  # 整首歌的第几个beat\n            self.pitch = muspy_note.pitch\n            self.duration = min(RESOLUTION, muspy_note.duration)  # TODO: 截断过长的note?\n            self.instr_type = instr_type\n            # self.velocity = muspy_note.velocity\n            self.velocity = 80\n\n    def to_decoder_list(self, n_beat: int) -> list:\n        l = [0] * N_DECODER_DIMENSION\n        l[DECODER_DIMENSION['type']] = preset_event2word['type']['Note']\n        l[DECODER_DIMENSION['pitch']] = preset_event2word['pitch']['Note_Pitch_%d' % self.pitch]\n        l[DECODER_DIMENSION['duration']] = preset_event2word['duration']['Note_Duration_%d' % (self.duration * 120)]\n        l[DECODER_DIMENSION['instr_type']] = preset_event2word['instr_type'][self.instr_type]\n        l[DECODER_DIMENSION['i_beat']] = self.i_beat\n        l[DECODER_DIMENSION['n_beat']] = n_beat\n        l[DECODER_DIMENSION['p_beat']] = int(self.i_beat / n_beat * 100)\n        return l\n\n    def to_muspy_note(self) -> muspy.Note:\n        return muspy.Note(time=self.time, pitch=self.pitch, duration=self.duration, velocity=self.velocity)\n\n    def from_decoder_array(self, np_array: np.ndarray, bar: int, beat: int) -> muspy.Note:\n        assert np_array[DECODER_DIMENSION['type']] == preset_event2word['type']['Note']\n        assert np_array[DECODER_DIMENSION['pitch']] > 0\n        assert np_array[DECODER_DIMENSION['duration']] > 0\n        assert np_array[DECODER_DIMENSION['instr_type']] > 0\n        self.time = bar * RESOLUTION + beat\n        self.pitch = np_array[DECODER_DIMENSION['pitch']] - 1\n        self.duration = np_array[DECODER_DIMENSION['duration']] - 1\n        self.instr_type = preset_word2event['instr_type'][np_array[DECODER_DIMENSION['instr_type']]]\n        self.velocity = 80\n        return self.to_muspy_note()\n\n\nclass Bar:\n    def __init__(self, notes, i_bar):\n        self.notes = notes\n        self.n_notes = len(self.notes)\n        self.i_bar = i_bar\n\n    def _get_beat_token(self, note, density, strength, n_beat: int) -> list:\n        l = [[0] * N_DECODER_DIMENSION]\n        l[0][DECODER_DIMENSION['type']] = preset_event2word['type']['M']\n        l[0][DECODER_DIMENSION['beat']] = preset_event2word['beat']['Beat_%d' % note.beat]\n        l[0][DECODER_DIMENSION['density']] = density + 1\n        l[0][DECODER_DIMENSION['instr_type']] = preset_event2word['instr_type'][note.instr_type]\n        l[0][DECODER_DIMENSION['strength']] = strength\n        l[0][DECODER_DIMENSION['i_beat']] = note.i_beat\n        l[0][DECODER_DIMENSION['n_beat']] = n_beat\n        l[0][DECODER_DIMENSION['p_beat']] = int(note.i_beat / n_beat * 100)\n        return l\n\n    def _get_bar_token(self, density, n_beat: int) -> list:\n        l = [[0] * N_DECODER_DIMENSION]\n        l[0][DECODER_DIMENSION['type']] = preset_event2word['type']['M']\n        l[0][DECODER_DIMENSION['beat']] = preset_event2word['beat']['Bar']\n        l[0][DECODER_DIMENSION['density']] = density + 1\n        l[0][DECODER_DIMENSION['i_beat']] = self.i_bar * RESOLUTION\n        l[0][DECODER_DIMENSION['n_beat']] = n_beat\n        l[0][DECODER_DIMENSION['p_beat']] = int(self.i_bar * RESOLUTION / n_beat * 100)\n        return l\n\n    def to_decoder_list(self, n_beat: int) -> list:\n        # 逆序构建\n        n_beats = 0\n        l = []\n        if len(self.notes) > 0:\n            # add the last note token\n            l = [self.notes[-1].to_decoder_list(n_beat)]\n            prev_note = self.notes[-1]\n            n_notes_per_beat = 1\n            for note in reversed(self.notes[:-1]):\n                if note.beat != prev_note.beat or note.instr_type != prev_note.instr_type:\n                    # add beat token\n                    l = self._get_beat_token(note=prev_note, density=n_beats, strength=n_notes_per_beat,\n                                             n_beat=n_beat) + l\n                    if note.beat != prev_note.beat:\n                        n_beats += 1\n                    n_notes_per_beat = 0\n                # add note token\n                l = [note.to_decoder_list(n_beat)] + l\n                n_notes_per_beat += 1\n                prev_note = note\n            # add the first beat token\n            l = self._get_beat_token(note=prev_note, density=n_beats, strength=n_notes_per_beat, n_beat=n_beat) + l\n            n_beats += 1\n        # add bar token\n        l = self._get_bar_token(density=n_beats, n_beat=n_beat) + l\n        return l\n\n\nclass MIDI:\n    def __init__(self, id: str):\n        self.id = id\n        self.midi = muspy.read_midi(os.path.join(midi_dir, id + '.mid'))\n        self.midi.adjust_resolution(target=RESOLUTION // 4)\n\n        self.n_beat = self.midi.get_end_time()\n        self.n_bars = math.ceil((self.n_beat + 1) / RESOLUTION)\n\n        muspy_tracks = []\n        for track in self.midi.tracks:  # filter tracks with <=20 notes\n            if len(track.notes) > 20:\n                muspy_tracks.append(track)\n        self.midi.tracks = muspy_tracks\n        self.instruments = [track.name for track in muspy_tracks]\n        self.bars = self._get_bars()\n\n    def _get_bars(self):\n        bars = [[] for i in range(self.n_bars)]\n        for i, track in enumerate(self.midi.tracks):\n            for j, muspy_note in enumerate(track.notes):\n                note = Note(muspy_note, track.name)\n                bars[note.bar].append(note)\n        new_bars = []\n        for i in range(len(bars)):\n            bars[i].sort(key=lambda x: x.time)\n            new_bars.append(Bar(notes=bars[i], i_bar=i))\n        return new_bars\n\n    def to_decoder_list(self) -> list:\n        l = []\n        for bar in self.bars:\n            l += bar.to_decoder_list(self.n_beat)\n        l += [[0] * N_DECODER_DIMENSION]  # 多一个EOS\n        mask = [1] * len(l)\n        return l, mask, len(l)\n\n\ndef midi2numpy(id_list: list):\n    if not os.path.exists(json_dir):\n        os.makedirs(json_dir)\n\n    decoder = []\n    decoder_mask = []\n    metadata_list = []\n    decoder_len = []\n\n    for id in tqdm(id_list):\n        id_filename = os.path.join(json_dir, id + '.json')\n        if os.path.exists(id_filename):\n            with open(id_filename, 'r') as f:\n                load_dict = json.load(f)\n                decoder_list = load_dict['decoder_list']\n                de_mask = load_dict['de_mask']\n                de_len = load_dict['de_len']\n                decoder_len.append(de_len)\n                metadata = load_dict['metadata']\n        else:\n\n            midi = MIDI(id)\n            decoder_list, de_mask, de_len = midi.to_decoder_list()\n\n            decoder_len.append(de_len)\n            if de_len > DECODER_MAX_LEN:\n                continue\n\n            # Padding to MAX_LEN\n            decoder_list += [[0] * N_DECODER_DIMENSION] * (DECODER_MAX_LEN - de_len)\n            de_mask += [0] * (DECODER_MAX_LEN - de_len)\n\n            metadata = {'id': id, 'de_len': de_len, 'instruments': midi.instruments, 'genre': \"N/A\"}\n            ##### genre set to empty\n\n            dic = {'decoder_list': decoder_list, 'de_mask': de_mask, 'de_len': de_len, 'metadata': metadata}\n            with open(id_filename, 'w') as f:\n                json.dump(dic, f)\n\n        decoder.append(decoder_list)\n        decoder_mask.append(de_mask)\n        metadata_list.append(metadata)\n\n    print('max decoder length: %d' % max(decoder_len))\n\n    decoder = np.asarray(decoder, dtype=int)\n    x = decoder[:, :-1]\n    y = decoder[:, 1:]\n    decoder_mask = np.asarray(decoder_mask, dtype=int)\n\n    np.savez(npz_filename, x=x, y=y, decoder_mask=decoder_mask, metadata=metadata_list)\n    print(npz_filename)\n    print('%d songs' % len(decoder))\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--midi_dir\", default=\"../../lpd_5_cleansed_midi/\", required=True)\n    parser.add_argument(\"--out_name\", default=\"data.npz\", required=True)\n    args = parser.parse_args()\n\n    midi_dir = args.midi_dir\n    npz_filename = os.path.join(\"../dataset/\", args.out_name)\n    json_dir = os.path.join(\"../dataset/json/\")\n\n    id_list = []\n    for name in os.listdir(midi_dir):\n        if name.endswith(\".mid\"):\n            id_list.append(name[:-4])\n        elif name.endswith(\".midi\"):\n            id_list.append(name[:-5])\n    \n    midi2numpy(id_list)\n"
  },
  {
    "path": "src/model.py",
    "content": "import numpy as np\nimport torch\nimport torch.cuda\nfrom torch import nn\n\nfrom utils import Embeddings, BeatPositionalEncoding\n\nfrom fast_transformers.builders import TransformerEncoderBuilder\nfrom fast_transformers.masking import TriangularCausalMask\n\nD_MODEL = 512\nN_LAYER_ENCODER = 12\nN_HEAD = 8\n\nATTN_DECODER = \"causal-linear\"\n\n\n################################################################################\n# Sampling\n################################################################################\n# -- temperature -- #\ndef softmax_with_temperature(logits, temperature):\n    logits -= np.max(logits)\n    probs = np.exp(logits / temperature) / np.sum(np.exp(logits / temperature))\n    return probs\n\n\ndef weighted_sampling(probs):\n    probs /= (sum(probs) + 1e-10)\n    sorted_probs = np.sort(probs)[::-1]\n    sorted_index = np.argsort(probs)[::-1]\n    try:\n        word = np.random.choice(sorted_index, size=1, p=sorted_probs)[0]\n    except:\n        word = sorted_index[0]\n    return word\n\n\n# -- nucleus -- #\ndef nucleus(probs, p):\n    probs /= (sum(probs) + 1e-5)\n    sorted_probs = np.sort(probs)[::-1]\n    sorted_index = np.argsort(probs)[::-1]\n    cusum_sorted_probs = np.cumsum(sorted_probs)\n    after_threshold = cusum_sorted_probs > p\n    if sum(after_threshold) > 0:\n        last_index = np.where(after_threshold)[0][0] + 1\n        candi_index = sorted_index[:last_index]\n    else:\n        candi_index = sorted_index[:]\n    candi_probs = [probs[i] for i in candi_index]\n    candi_probs /= sum(candi_probs)\n    word = np.random.choice(candi_index, size=1, p=candi_probs)[0]\n    return word\n\n\ndef sampling(logit, p=None, t=1.0):\n    logit = logit.squeeze().cpu().numpy()\n    probs = softmax_with_temperature(logits=logit, temperature=t)\n\n    if p is not None:\n        cur_word = nucleus(probs, p=p)\n    else:\n        cur_word = weighted_sampling(probs)\n    return cur_word\n\n\n'''\nlast dimension of input data | attribute:\n0: bar/beat\n1: type\n2: density\n3: pitch\n4: duration\n5: instr\n6: strength onset_density\n7: time_encoding\n'''\n\n\nclass CMT(nn.Module):\n    def __init__(self, n_token, init_n_token, is_training=True):\n        super(CMT, self).__init__()\n\n        print(\"D_MODEL\", D_MODEL, \" N_LAYER\", N_LAYER_ENCODER, \" N_HEAD\", N_HEAD, \"DECODER ATTN\", ATTN_DECODER)\n\n        # --- params config --- #\n        self.n_token = n_token\n        self.d_model = D_MODEL\n        self.n_layer_encoder = N_LAYER_ENCODER  #\n        # self.n_layer_decoder = N_LAYER_DECODER\n        self.dropout = 0.1\n        self.n_head = N_HEAD  #\n        self.d_head = D_MODEL // N_HEAD\n        self.d_inner = 2048\n        self.loss_func = nn.CrossEntropyLoss(reduction='none')\n        # self.emb_sizes = [64, 32, 512, 128, 32]\n        self.emb_sizes = [64, 32, 64, 512, 128, 32, 64]\n\n        self.init_n_token = init_n_token  # genre, key, instrument\n        self.init_emb_sizes = [64, 64, 64]\n        self.time_encoding_size = 256\n        # --- modules config --- #\n        # embeddings\n        print('>>>>>:', self.n_token)\n\n        self.init_emb_genre = Embeddings(self.init_n_token[0], self.init_emb_sizes[0])\n        self.init_emb_key = Embeddings(self.init_n_token[1], self.init_emb_sizes[1])\n        self.init_emb_instrument = Embeddings(self.init_n_token[2], self.init_emb_sizes[2])\n        self.init_in_linear = nn.Linear(int(np.sum(self.init_emb_sizes)), self.d_model)\n\n        self.encoder_emb_barbeat = Embeddings(self.n_token[0], self.emb_sizes[0])\n        self.encoder_emb_type = Embeddings(self.n_token[1], self.emb_sizes[1])\n        self.encoder_emb_beat_density = Embeddings(self.n_token[2], self.emb_sizes[2])\n        self.encoder_emb_pitch = Embeddings(self.n_token[3], self.emb_sizes[3])\n        self.encoder_emb_duration = Embeddings(self.n_token[4], self.emb_sizes[4])\n        self.encoder_emb_instr = Embeddings(self.n_token[5], self.emb_sizes[5])\n        self.encoder_emb_onset_density = Embeddings(self.n_token[6], self.emb_sizes[6])\n        self.encoder_emb_time_encoding = Embeddings(self.n_token[7], self.time_encoding_size)\n        self.encoder_pos_emb = BeatPositionalEncoding(self.d_model, self.dropout)\n\n        # # linear\n        self.encoder_in_linear = nn.Linear(int(np.sum(self.emb_sizes)), self.d_model)\n        self.encoder_time_linear = nn.Linear(int(self.time_encoding_size), self.d_model)\n\n        self.transformer_encoder = TransformerEncoderBuilder.from_kwargs(\n            n_layers=self.n_layer_encoder,\n            n_heads=self.n_head,\n            query_dimensions=self.d_model // self.n_head,\n            value_dimensions=self.d_model // self.n_head,\n            feed_forward_dimensions=2048,\n            activation='gelu',\n            dropout=0.1,\n            attention_type=\"causal-linear\",\n        ).get()\n\n        # blend with type\n        self.project_concat_type = nn.Linear(self.d_model + 32, self.d_model)\n\n        # individual output\n        self.proj_barbeat = nn.Linear(self.d_model, self.n_token[0])\n        self.proj_type = nn.Linear(self.d_model, self.n_token[1])\n        self.proj_beat_density = nn.Linear(self.d_model, self.n_token[2])\n        self.proj_pitch = nn.Linear(self.d_model, self.n_token[3])\n        self.proj_duration = nn.Linear(self.d_model, self.n_token[4])\n        self.proj_instr = nn.Linear(self.d_model, self.n_token[5])\n        self.proj_onset_density = nn.Linear(self.d_model, self.n_token[6])\n\n    def compute_loss(self, predict, target, loss_mask):\n        loss = self.loss_func(predict, target)\n        loss = loss * loss_mask\n        loss = torch.sum(loss) / torch.sum(loss_mask)\n        return loss\n\n    def forward_init_token_vis(self, x, memory=None, is_training=True):\n        emb_genre = self.init_emb_genre(x[..., 0])\n        emb_key = self.init_emb_key(x[..., 1])\n        emb_instrument = self.init_emb_instrument(x[..., 2])\n        return emb_genre, emb_key, emb_instrument\n\n    def forward_init_token(self, x, memory=None, is_training=True):\n        emb_genre = self.init_emb_genre(x[..., 0])\n        emb_key = self.init_emb_key(x[..., 1])\n        emb_instrument = self.init_emb_instrument(x[..., 2])\n        embs = torch.cat(\n            [\n                emb_genre,\n                emb_key,\n                emb_instrument,\n            ], dim=-1)\n        encoder_emb_linear = self.init_in_linear(embs)\n        if is_training:\n            return encoder_emb_linear\n        else:\n            pos_emb = encoder_emb_linear.squeeze(0)\n            h, memory = self.transformer_encoder(pos_emb, memory=memory)\n            y_type = self.proj_type(h)\n            return h, y_type, memory\n\n    def forward_hidden(self, x, memory=None, is_training=True, init_token=None):\n        # linear transformer: b, s, f   x.shape=(bs, nf)\n\n        # embeddings\n        emb_barbeat = self.encoder_emb_barbeat(x[..., 0])\n        emb_type = self.encoder_emb_type(x[..., 1])\n        emb_beat_density = self.encoder_emb_beat_density(x[..., 2])\n        emb_pitch = self.encoder_emb_pitch(x[..., 3])\n        emb_duration = self.encoder_emb_duration(x[..., 4])\n        emb_instr = self.encoder_emb_instr(x[..., 5])\n        emb_onset_density = self.encoder_emb_onset_density(x[..., 6])\n        emb_time_encoding = self.encoder_emb_time_encoding(x[..., 7])\n\n        embs = torch.cat(\n            [\n                emb_barbeat,\n                emb_type,\n                emb_beat_density,\n                emb_pitch,\n                emb_duration,\n                emb_instr,\n                emb_onset_density\n            ], dim=-1)\n\n        encoder_emb_linear = self.encoder_in_linear(embs)\n        # import ipdb;ipdb.set_trace()\n        encoder_emb_time_linear = self.encoder_time_linear(emb_time_encoding)\n        encoder_emb_linear = encoder_emb_linear + encoder_emb_time_linear\n        encoder_pos_emb = self.encoder_pos_emb(encoder_emb_linear, x[:, :, 8])\n\n        if is_training:\n            assert init_token is not None\n            init_emb_linear = self.forward_init_token(init_token)\n            encoder_pos_emb = torch.cat([init_emb_linear, encoder_pos_emb], dim=1)\n        else:\n            assert init_token is not None\n            init_emb_linear = self.forward_init_token(init_token)\n            encoder_pos_emb = torch.cat([init_emb_linear, encoder_pos_emb], dim=1)\n        # transformer\n        if is_training:\n            attn_mask = TriangularCausalMask(encoder_pos_emb.size(1), device=x.device)\n            encoder_hidden = self.transformer_encoder(encoder_pos_emb, attn_mask)\n            # print(\"forward decoder done\")\n            y_type = self.proj_type(encoder_hidden[:, 7:, :])\n            return encoder_hidden, y_type\n\n        else:\n            encoder_mask = TriangularCausalMask(encoder_pos_emb.size(1), device=x.device)\n            h = self.transformer_encoder(encoder_pos_emb, encoder_mask)  # y: s x d_model\n            h = h[:, -1:, :]\n            h = h.squeeze(0)\n            y_type = self.proj_type(h)\n\n            return h, y_type\n\n    def forward_output(self, h, y):\n        # for training\n        tf_skip_type = self.encoder_emb_type(y[..., 1])\n        h = h[:, 7:, :]\n        # project other\n        y_concat_type = torch.cat([h, tf_skip_type], dim=-1)\n        y_ = self.project_concat_type(y_concat_type)\n\n        y_barbeat = self.proj_barbeat(y_)\n        y_beat_density = self.proj_beat_density(y_)\n        y_pitch = self.proj_pitch(y_)\n        y_duration = self.proj_duration(y_)\n        y_instr = self.proj_instr(y_)\n        y_onset_density = self.proj_onset_density(y_)\n        # import ipdb;ipdb.set_trace()\n\n        return y_barbeat, y_pitch, y_duration, y_instr, y_onset_density, y_beat_density\n\n    def forward_output_sampling(self, h, y_type, recurrent=True):\n        '''\n        for inference\n        '''\n        y_type_logit = y_type[0, :]  # dont know wtf\n        cur_word_type = sampling(y_type_logit, p=0.90)\n\n        type_word_t = torch.from_numpy(\n            np.array([cur_word_type])).long().unsqueeze(0)\n\n        if torch.cuda.is_available():\n            type_word_t = type_word_t.cuda()\n\n        tf_skip_type = self.encoder_emb_type(type_word_t).squeeze(0)\n\n        # concat\n        y_concat_type = torch.cat([h, tf_skip_type], dim=-1)\n        y_ = self.project_concat_type(y_concat_type)\n\n        # project other\n        y_barbeat = self.proj_barbeat(y_)\n\n        y_pitch = self.proj_pitch(y_)\n        y_duration = self.proj_duration(y_)\n        y_instr = self.proj_instr(y_)\n        y_onset_density = self.proj_onset_density(y_)\n        y_beat_density = self.proj_beat_density(y_)\n\n        # sampling gen_cond\n        cur_word_barbeat = sampling(y_barbeat, t=1.2)\n        cur_word_pitch = sampling(y_pitch, p=0.9)\n        cur_word_duration = sampling(y_duration, t=2, p=0.9)\n        cur_word_instr = sampling(y_instr, p=0.90)\n        cur_word_onset_density = sampling(y_onset_density, p=0.90)\n        cur_word_beat_density = sampling(y_beat_density, p=0.90)\n\n        # collect\n        next_arr = np.array([\n            cur_word_barbeat,\n            cur_word_type,\n            cur_word_beat_density,\n            cur_word_pitch,\n            cur_word_duration,\n            cur_word_instr,\n            cur_word_onset_density,\n        ])\n        return next_arr\n\n    def inference_from_scratch(self, **kwargs):\n        vlog = kwargs['vlog']\n        C = kwargs['C']\n\n        def get_p_beat(cur_bar, cur_beat, n_beat):\n            all_beat = cur_bar * 16 + cur_beat - 1\n            p_beat = round(all_beat / n_beat * 100) + 1\n            return p_beat\n\n        dictionary = {'bar': 17}\n        strength_track_list = [1, 2, 3]\n\n        pre_init = np.array([\n            [5, 0, 0],\n            [0, 0, 0],\n            [0, 0, 1],\n            [0, 0, 2],\n            [0, 0, 3],\n            [0, 0, 4],\n            [0, 0, 5],\n        ])\n        init = np.array([\n            [17, 1, vlog[0][1], 0, 0, 0, 0, 1, 0],  # bar\n        ])\n\n        with torch.no_grad():\n            final_res = []\n            h = None\n\n            init_t = torch.from_numpy(init).long()\n            pre_init = torch.from_numpy(pre_init).long().unsqueeze(0)\n            if torch.cuda.is_available():\n                pre_init = pre_init.cuda()\n                init_t = init_t.cuda()\n\n            print('------ initiate ------')\n            for step in range(init.shape[0]):\n                input_ = init_t[step, :].unsqueeze(0).unsqueeze(0)\n                print(input_)\n                final_res.append(init[step, :][None, ...])\n                h, y_type = self.forward_hidden(input_, is_training=False, init_token=pre_init)\n\n            print('------- condition -------')\n            assert vlog is not None\n            n_beat = vlog[0][4]\n            len_vlog = len(vlog)\n            cur_vlog = 1\n            cur_track = 0\n            idx = 0\n            acc_beat_num = vlog[0][1]\n            beat_num = {}\n            acc_note_num = 0\n            note_num = 0\n            err_note_number_list = []\n            err_beat_number_list = []\n            p_beat = 1\n            cur_bar = 0\n            while (True):\n                # sample others\n                print(idx, end=\"\\r\")\n                idx += 1\n                next_arr = self.forward_output_sampling(h, y_type)\n                if next_arr[1] == 1:\n                    replace = False\n                if next_arr[1] == 2 and next_arr[5] == 0:\n                    next_arr[5] = 1\n                    print(\"warning note with instrument 0 detected, replaced by drum###################\")\n                if cur_vlog >= len_vlog:\n                    print(\"exceed vlog len\")\n                    break\n                vlog_i = vlog[cur_vlog]\n                if vlog_i[0] == dictionary['bar'] and next_arr[0] == dictionary['bar']:\n                    err_beat_number = np.abs(len(beat_num.keys()) - acc_beat_num)\n                    err_beat_number_list.append(err_beat_number)\n                    flag = (np.random.rand() < C)\n                    print(\"replace beat density-----\", vlog_i, next_arr)\n                    if flag:\n                        next_arr = np.array([17, 1, vlog_i[1], 0, 0, 0, 0])\n                        print(\"replace beat density-----\", next_arr)\n                        beat_num = {}\n                        acc_beat_num = vlog_i[1]\n                        replace = True\n                        cur_vlog += 1\n                    else:\n                        print(\"replace denied----\")\n                        cur_vlog += 1\n                elif vlog_i[0] < dictionary['bar'] and next_arr[0] >= vlog_i[0]:\n                    err_note_number = np.abs(acc_note_num - note_num)\n                    err_note_number_list.append(err_note_number)\n                    print(\"replace onset density----\", vlog_i, next_arr)\n                    if cur_track == 0:\n                        cur_density = next_arr[2]\n                        flag = (np.random.rand() < C)\n                        if next_arr[0] == dictionary['bar']:\n                            cur_density = 1\n\n                    next_arr = np.array(\n                        [vlog_i[0], 1, cur_density, 0, 0, strength_track_list[cur_track], vlog_i[2] + 0])\n                    replace = True\n                    acc_note_num = vlog_i[2] + 0\n                    note_num = 0\n                    cur_track += 1\n                    if cur_track >= len(strength_track_list):\n                        cur_track = 0\n                        cur_vlog += 1\n\n                if next_arr[1] == 1:\n                    beat_num[next_arr[0]] = 1\n                elif next_arr[1] == 2 and replace == True:\n                    note_num += 1\n\n                if next_arr[0] == dictionary['bar']:\n                    cur_bar += 1\n                if next_arr[1] == 1:\n                    if next_arr[0] == 17:\n                        cur_beat = 1\n                    else:\n                        cur_beat = next_arr[0]\n                    p_beat = get_p_beat(cur_bar, cur_beat, n_beat)\n                if p_beat >= 102:\n                    print(\"exceed max p_beat----\")\n                    break\n                next_arr = np.concatenate([next_arr, [p_beat], [cur_bar * 16 + cur_beat - 1]])\n                final_res.append(next_arr[None, ...])\n                print(next_arr)\n                # forward\n                input_cur = torch.from_numpy(next_arr).long().unsqueeze(0).unsqueeze(0)\n                if torch.cuda.is_available():\n                    input_cur = input_cur.cuda()\n                input_ = torch.cat((input_, input_cur), dim=1)\n                if replace:\n                    h, y_type = self.forward_hidden(input_, is_training=False, init_token=pre_init)\n                else:\n                    h, y_type = self.forward_hidden(input_, is_training=False, init_token=pre_init)\n                if next_arr[1] == 0:\n                    print(\"EOS predicted\")\n                    break\n\n        print('\\n--------[Done]--------')\n        final_res = np.concatenate(final_res)\n        print(final_res.shape)\n        return final_res, err_note_number_list, err_beat_number_list\n\n\n    def train_forward(self, **kwargs):\n        x = kwargs['x']\n        target = kwargs['target']\n        loss_mask = kwargs['loss_mask']\n        init_token = kwargs['init_token']\n        h, y_type = self.forward_hidden(x, memory=None, is_training=True, init_token=init_token)\n        y_barbeat, y_pitch, y_duration, y_instr, y_onset_density, y_beat_density = self.forward_output(h, target)\n\n        # reshape (b, s, f) -> (b, f, s)\n        y_barbeat = y_barbeat[:, ...].permute(0, 2, 1)\n        y_type = y_type[:, ...].permute(0, 2, 1)\n        y_pitch = y_pitch[:, ...].permute(0, 2, 1)\n        y_duration = y_duration[:, ...].permute(0, 2, 1)\n        y_instr = y_instr[:, ...].permute(0, 2, 1)\n        y_onset_density = y_onset_density[:, ...].permute(0, 2, 1)\n        y_beat_density = y_beat_density[:, ...].permute(0, 2, 1)\n\n        # loss\n        loss_barbeat = self.compute_loss(\n            y_barbeat, target[..., 0], loss_mask)\n        loss_type = self.compute_loss(\n            y_type, target[..., 1], loss_mask)\n        loss_beat_density = self.compute_loss(\n            y_beat_density, target[..., 2], loss_mask)\n        loss_pitch = self.compute_loss(\n            y_pitch, target[..., 3], loss_mask)\n        loss_duration = self.compute_loss(\n            y_duration, target[..., 4], loss_mask)\n        loss_instr = self.compute_loss(\n            y_instr, target[..., 5], loss_mask)\n        loss_onset_density = self.compute_loss(\n            y_onset_density, target[..., 6], loss_mask)\n\n        return loss_barbeat, loss_type, loss_pitch, loss_duration, loss_instr, loss_onset_density, loss_beat_density\n\n    def forward(self, **kwargs):\n        if kwargs['is_train']:\n            return self.train_forward(**kwargs)\n        return self.inference_from_scratch(**kwargs)"
  },
  {
    "path": "src/numpy2midi_mix.py",
    "content": "import muspy\nimport numpy as np\n\nfrom midi2numpy_mix import Note, DECODER_DIMENSION, RESOLUTION\nfrom dictionary_mix import preset_event2word\n\nINSTRUMENT_PROGRAM = {\n    'Drums'  : 114,\n    'Piano'  : 0,  # Acoustic Grand Piano\n    'Guitar' : 24,  # Acoustic Guitar (nylon)\n    'Bass'   : 33,  # Electric Bass (finger)\n    'Strings': 41  # Viola\n}\n\n\ndef test_numpy2midi(idx: int) -> muspy.Music:\n    npz = np.load('lpd_5_ccdepr_mix_v4_10000.npz', allow_pickle=True)\n    decoder = npz['x'][idx]\n    name = npz['metadata'][idx]['id']\n    return numpy2midi(name, decoder)\n\n\ndef numpy2midi(name, decoder: np.ndarray) -> muspy.Music:\n    muspy_tracks = []\n    # Decoder\n    n_bars = -1\n    beat = 0\n    track_notes = {instr_type: [] for instr_type in INSTRUMENT_PROGRAM.keys()}\n    for word in decoder:\n        w_type = word[DECODER_DIMENSION['type']]\n        if w_type == preset_event2word['type']['M']:\n            if word[DECODER_DIMENSION['beat']] == preset_event2word['beat']['Bar']:\n                n_bars += 1\n            elif word[DECODER_DIMENSION['beat']] > 0 and word[DECODER_DIMENSION['beat']] < 17:\n                beat = word[DECODER_DIMENSION['beat']] - 1\n        elif w_type == preset_event2word['type']['Note']:\n            note = Note()\n            muspy_note = note.from_decoder_array(np_array=word, bar=n_bars, beat=beat)\n            track_notes[note.instr_type].append(muspy_note)\n        else:\n            assert w_type == preset_event2word['type']['EOS']\n            break\n    for instr_type, muspy_notes in track_notes.items():\n        muspy_tracks.append(muspy.Track(\n            program=INSTRUMENT_PROGRAM[instr_type],\n            is_drum=(instr_type == 'Drums'),\n            name=instr_type,\n            notes=muspy_notes\n        ))\n\n    muspy_music = muspy.Music(resolution=RESOLUTION // 4, tracks=muspy_tracks)\n\n    muspy.write_midi(name + \".mid\", muspy_music)\n\n    return muspy_music\n\n\nif __name__ == '__main__':\n    test_numpy2midi(idx=66)\n"
  },
  {
    "path": "src/pianoroll2midi.py",
    "content": "\"\"\"Author: Shangzhe Di (shangzhe.di@gmail.com)\n\nConvert the pianoroll files (.npz) in the lpd-5/LPD-5-cleansed (https://salu133445.github.io/lakh-pianoroll-dataset/dataset) to midi files.\n\nThe pianoroll files are organized as:\nlpd_5_cleansed\n├── A\n│   ├── A\n│   │   ├── A\n│   │   │   ├── TRAAAGR128F425B14B\n│   │   │   │   └── b97c529ab9ef783a849b896816001748.npz\n│   │   │   └── TRAAAZF12903CCCF6B\n│   │   │       └── 05f21994c71a5f881e64f45c8d706165.npz\n│   │   ├── B\n│   │   │   └── TRAABXH128F42955D6\n│   │   │       └── 04266ac849c1d3814dc03bbf61511b33.npz\n...\n\nThe converted midi files will be organized as:\nlpd_5_cleansed_midi/\n├── TRDNFHP128F9324C47.mid\n├── TRHIZHZ128F4295EFA.mid\n├── TRRRAJP128E0793859.mid\n├── TRRREEC128F9336C97.mid\n├── TRRREEO128F933C62F.mid\n├── TRRRERM128F429B7A0.mid\n├── TRRRGET128F426655D.mid\n...\n\n\"\"\"\n\nimport pypianoroll\nimport argparse\nimport os\nimport os.path as osp\nfrom tqdm import tqdm\n\n\ndef process_dataset(in_dir, out_dir):\n    if not os.path.exists(out_dir):\n        os.makedirs(out_dir)\n\n    in_filename_list, out_filename_list = [], []\n    for main_dir, sub_dir, filename_list in os.walk(in_dir):\n        for filename in filename_list:\n            if '.npz' not in filename:\n                continue\n            in_filename_list.append(osp.join(main_dir, filename))\n            track_name = main_dir.split(\"/\")[-1]\n            out_filename_list.append(osp.join(out_dir, track_name + '.mid'))\n\n    for i, in_filename in enumerate(tqdm(in_filename_list)):\n        convert_midi(in_filename, out_filename_list[i])\n\n\ndef convert_midi(in_filename, out_filename):\n    pianoroll = pypianoroll.load(in_filename)\n    pypianoroll.write(out_filename, pianoroll)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--in_dir\", help='the directory of the LPD dataset', default='./lpd_5_cleansed/')\n    parser.add_argument(\"--out_dir\", help='the directory of the output midi files', default='./lpd_5_cleansed_midi/')\n    args = parser.parse_args()\n    process_dataset(args.in_dir, args.out_dir)\n"
  },
  {
    "path": "src/train.py",
    "content": "import sys\nimport datetime\nimport argparse\nimport os\nimport time\n\nimport numpy as np\nimport torch\nfrom torch import optim\nfrom torch.nn.utils import clip_grad_norm_\n\nsys.path.append(\".\")\n\nimport utils\nfrom utils import log, Saver, network_paras\nfrom model import CMT\n\n\n\ndef train_dp():\n    parser = argparse.ArgumentParser(description=\"Args for training CMT\")\n    parser.add_argument('-n', '--name', default=\"debug\",\n                        help=\"Name of the experiment, also the log file and checkpoint directory. If 'debug', checkpoints won't be saved\")\n    parser.add_argument('-l', '--lr', default=0.0001, help=\"Initial learning rate\")\n    parser.add_argument('-b', '--batch_size', default=6, help=\"Batch size\")\n    parser.add_argument('-p', '--path', help=\"If set, load model from the given path\")\n    parser.add_argument('-e', '--epochs', default=200, help=\"Num of epochs\")\n    parser.add_argument('-t', '--train_data', default='../dataset/lpd_5_prcem_mix_v8_10000.npz',\n                        help=\"Path of the training data (.npz file)\")\n    parser.add_argument('-g', '--gpus', type=int, nargs='+', help=\"Ids of gpu\")\n    args = parser.parse_args()\n\n    if args.gpus is None:\n        os.environ['CUDA_VISIBLE_DEVICES'] = \",\".join([str(g) for g in list(range(torch.cuda.device_count()))])\n    else:\n        os.environ['CUDA_VISIBLE_DEVICES'] = \",\".join([str(g) for g in args.gpus])\n\n    path_train_data = args.train_data\n\n    init_lr = float(args.lr)\n\n    batch_size = int(args.batch_size)\n\n    DEBUG = args.name == \"debug\"\n\n    params = {\n        \"DECAY_EPOCH\": [],\n        \"DECAY_RATIO\": 0.1,\n    }\n\n    log(\"name:\", args.name)\n    log(\"args\", args)\n\n    if DEBUG:\n        log(\"DEBUG MODE checkpoints will not be saved\")\n    else:\n        utils.flog = open(\"../logs/\" + args.name + \".log\", \"w\")\n\n    # hyper params\n    n_epoch = args.epochs\n    max_grad_norm = 3\n\n    # config\n    train_data = np.load(path_train_data, allow_pickle=True)\n    train_x = train_data['x'][:, :, [1, 0, 2, 3, 4, 5, 6, 9, 7]]\n    train_y = train_data['y'][:, :, [1, 0, 2, 3, 4, 5, 6, 9, 7]]\n    train_mask = train_data['decoder_mask'][:, :9999]\n\n    metadata = train_data['metadata']\n    for i, m in enumerate(metadata):\n        total = m[\"de_len\"] - 1\n        train_x[i, :total, 7] = train_x[i, :total, 7] + 1\n\n    init_token = np.tile(np.array([\n            [5, 0, 0],\n            [0, 0, 0],\n            [0, 0, 1],\n            [0, 0, 2],\n            [0, 0, 3],\n            [0, 0, 4],\n            [0, 0, 5],\n        ]), (train_x.shape[0], 1, 1))\n\n    num_batch = len(train_x) // batch_size\n\n    # create saver\n    saver_agent = Saver(exp_dir=\"../exp/\" + args.name, debug=DEBUG)\n\n    decoder_n_class = np.max(train_x, axis=(0, 1)) + 1\n    init_n_class = [7, 1, 6]\n\n    #    decoder_n_class = [18, 3, 18, 129, 18, 6, 20, 102, 5025]\n    #    init_n_class = [7, 1, 6]\n\n    # log\n    log('num of encoder classes:', decoder_n_class, init_n_class)\n\n    # init\n\n    net = torch.nn.DataParallel(CMT(decoder_n_class, init_n_class))\n\n    if torch.cuda.is_available():\n        net.cuda()\n\n    DEVICE_COUNT = torch.cuda.device_count()\n    log(\"DEVICE COUNT:\", DEVICE_COUNT)\n    log(\"VISIBLE: \" + os.environ[\"CUDA_VISIBLE_DEVICES\"])\n\n    net.train()\n    n_parameters = network_paras(net)\n    log('n_parameters: {:,}'.format(n_parameters))\n    saver_agent.add_summary_msg(\n        ' > params amount: {:,d}'.format(n_parameters))\n\n    if args.path is not None:\n        print('[*] load model from:', args.path)\n        net.load_state_dict(torch.load(args.path))\n\n    # optimizers\n    optimizer = optim.Adam(net.parameters(), lr=init_lr)\n\n    log('    train_data:', path_train_data.split(\"/\")[-2])\n    log('    batch_size:', batch_size)\n    log('    num_batch:', num_batch)\n    log('    train_x:', train_x.shape)\n    log('    train_y:', train_y.shape)\n    log('    train_mask:', train_mask.shape)\n    log('    lr_init:', init_lr)\n    for k, v in params.items():\n        log(f'    {k}: {v}')\n\n    # run\n    start_time = time.time()\n    for epoch in range(n_epoch):\n        acc_loss = 0\n        acc_losses = np.zeros(7)\n\n        if epoch in params['DECAY_EPOCH']:\n            log('LR decay by ratio', params['DECAY_RATIO'])\n            for p in optimizer.param_groups:\n                p['lr'] *= params['DECAY_RATIO']\n\n        for bidx in range(num_batch):  # num_batch\n            saver_agent.global_step_increment()\n\n            # index\n            bidx_st = batch_size * bidx\n            bidx_ed = batch_size * (bidx + 1)\n\n            # unpack batch data\n            batch_x = train_x[bidx_st:bidx_ed]\n            batch_y = train_y[bidx_st:bidx_ed]\n            batch_mask = train_mask[bidx_st:bidx_ed]\n            batch_init = init_token[bidx_st:bidx_ed]\n\n            # to tensor\n            batch_x = torch.from_numpy(batch_x).long()\n            batch_y = torch.from_numpy(batch_y).long()\n            batch_mask = torch.from_numpy(batch_mask).float()\n            batch_init = torch.from_numpy(batch_init).long()\n\n            if torch.cuda.is_available():\n                batch_x = batch_x.cuda()\n                batch_y = batch_y.cuda()\n                batch_mask = batch_mask.cuda()\n                batch_init = batch_init.cuda()\n\n            # run\n            losses = net(is_train=True, x=batch_x, target=batch_y, loss_mask=batch_mask, init_token=batch_init)\n            losses = [l.sum() for l in losses]\n            loss = (losses[0] + losses[1] + losses[2] + losses[3] + losses[4] + losses[5] + losses[6]) / 7\n\n            # Update\n            net.zero_grad()\n            loss.backward()\n            if max_grad_norm is not None:\n                clip_grad_norm_(net.parameters(), max_grad_norm)\n            optimizer.step()\n\n            # print\n            sys.stdout.write(\n                '{}/{} | Loss: {:.3f} | barbeat {:.3f}, type {:.3f}, pitch {:.3f}, duration {:.3f}, instr {:.3f}, strength {:.3f}, density {:.3f}\\r'.format(\n                    bidx, num_batch, float(loss), losses[0], losses[1], losses[2], losses[3], losses[4], losses[5],\n                    losses[6]))\n            sys.stdout.flush()\n\n            # acc\n            acc_losses += np.array([l.item() for l in losses])\n            acc_loss += loss.item()\n\n            # log\n            saver_agent.add_summary('batch loss', loss.item())\n\n        # epoch loss\n        runtime = time.time() - start_time\n        epoch_loss = acc_loss / num_batch\n        acc_losses = acc_losses / num_batch\n        log('-' * 80)\n        log(time.ctime() + ' epoch: {}/{} | Loss: {:.3f} | time: {}'.format(\n            epoch, n_epoch, epoch_loss, str(datetime.timedelta(seconds=runtime))))\n        each_loss_str = 'barbeat {:.3f}, type {:.3f}, pitch {:.3f}, duration {:.3f}, instr {:.3f}, strength {:.3f}, density {:.3f}\\r'.format(\n            acc_losses[0], acc_losses[1], acc_losses[2], acc_losses[3], acc_losses[4], acc_losses[5], acc_losses[6])\n        log('each loss > ' + each_loss_str)\n\n        saver_agent.add_summary('epoch loss', epoch_loss)\n        saver_agent.add_summary('epoch each loss', each_loss_str)\n\n        # save model, with policy\n        loss = epoch_loss\n        if 0.2 < loss:\n            fn = int(loss * 10) * 10\n            saver_agent.save_model(net, name='loss_' + str(fn))\n        elif 0.001 < loss <= 0.20:\n            fn = int(loss * 100)\n            saver_agent.save_model(net, name='loss_' + str(fn))\n        elif loss <= 0.001:\n            log('Finished')\n            return\n\n\n#        else:\n#            saver_agent.save_model(net, name='loss_high')\n\n\nif __name__ == '__main__':\n    train_dp()\n"
  },
  {
    "path": "src/utils.py",
    "content": "import math\nimport numpy as np\nimport torch\nimport torch.nn as nn\n\nimport os\nimport time\nimport collections\nimport matplotlib.pyplot as plt\nimport logging\n\nflog = None\n\n\n################################################################################\n# Sampling\n################################################################################\n# -- temperature -- #\ndef softmax_with_temperature(logits, temperature):\n    probs = np.exp(logits / temperature) / np.sum(np.exp(logits / temperature))\n    return probs\n\n\ndef weighted_sampling(probs):\n    probs /= sum(probs)\n    sorted_probs = np.sort(probs)[::-1]\n    sorted_index = np.argsort(probs)[::-1]\n    word = np.random.choice(sorted_index, size=1, p=sorted_probs)[0]\n    return word\n\n\n# -- nucleus -- #\ndef nucleus(probs, p):\n    probs /= (sum(probs) + 1e-5)\n    sorted_probs = np.sort(probs)[::-1]\n    sorted_index = np.argsort(probs)[::-1]\n    cusum_sorted_probs = np.cumsum(sorted_probs)\n    after_threshold = cusum_sorted_probs > p\n    if sum(after_threshold) > 0:\n        last_index = np.where(after_threshold)[0][0] + 1\n        candi_index = sorted_index[:last_index]\n    else:\n        candi_index = sorted_index[:]\n    candi_probs = [probs[i] for i in candi_index]\n    candi_probs /= sum(candi_probs)\n    word = np.random.choice(candi_index, size=1, p=candi_probs)[0]\n    return word\n\n\ndef sampling(logit, p=None, t=1.0):\n    logit = logit.squeeze().cpu().numpy()\n    probs = softmax_with_temperature(logits=logit, temperature=t)\n\n    if p is not None:\n        cur_word = nucleus(probs, p=p)\n    else:\n        cur_word = weighted_sampling(probs)\n    return cur_word\n\n\n################################################################################\n# Model\n################################################################################\n\n\ndef network_paras(model):\n    # compute only trainable params\n    model_parameters = filter(lambda p: p.requires_grad, model.parameters())\n    params = sum([np.prod(p.size()) for p in model_parameters])\n    return params\n\n\nclass Embeddings(nn.Module):\n    def __init__(self, n_token, d_model):\n        super(Embeddings, self).__init__()\n        self.lut = nn.Embedding(n_token, d_model)\n        self.d_model = d_model\n\n    def forward(self, x):\n        return self.lut(x) * math.sqrt(self.d_model)\n\n\nclass PositionalEncoding(nn.Module):\n    def __init__(self, d_model, dropout=0.1, max_len=20000):\n        super(PositionalEncoding, self).__init__()\n        self.dropout = nn.Dropout(p=dropout)\n\n        pe = torch.zeros(max_len, d_model)\n        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)\n        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n        pe[:, 0::2] = torch.sin(position * div_term)\n        pe[:, 1::2] = torch.cos(position * div_term)\n        pe = pe.unsqueeze(0)\n        self.register_buffer('pe', pe)\n\n    def forward(self, x):\n        # print(x.shape, self.pe[:, :x.size(1), :].shape)\n        x = x + self.pe[:, :x.size(1), :]\n        return self.dropout(x)\n\n\nclass BeatPositionalEncoding(nn.Module):\n    def __init__(self, d_model, dropout=0.1, max_len=20000):\n        super(BeatPositionalEncoding, self).__init__()\n        self.dropout = nn.Dropout(p=dropout)\n\n        pe = torch.zeros(max_len, d_model)\n        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)\n        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n        pe[:, 0::2] = torch.sin(position * div_term)\n        pe[:, 1::2] = torch.cos(position * div_term)\n        pe = pe.unsqueeze(0)\n        self.register_buffer('pe', pe)\n\n    def forward(self, x, index):\n        x = x + self.pe[:, index, :]\n        return self.dropout(x)[0]\n\n\nclass Saver(object):\n    def __init__(\n            self,\n            exp_dir,\n            mode='w',\n            debug=False):\n\n        self.exp_dir = exp_dir\n        self.init_time = time.time()\n        self.global_step = 0\n        self.debug = debug\n\n        # makedirs\n        os.makedirs(exp_dir, exist_ok=True)\n\n        # logging config\n        path_logger = os.path.join(exp_dir, 'log.txt')\n        logging.basicConfig(\n            level=logging.DEBUG,\n            format='%(message)s',\n            filename=path_logger,\n            filemode=mode)\n        self.logger = logging.getLogger('training monitor')\n\n    def add_summary_msg(self, msg):\n        if self.debug:\n            return\n        self.logger.debug(msg)\n\n    def add_summary(\n            self,\n            key,\n            val,\n            step=None,\n            cur_time=None):\n        if self.debug:\n            return\n        if cur_time is None:\n            cur_time = time.time() - self.init_time\n        if step is None:\n            step = self.global_step\n\n        # write msg (key, val, step, time)\n        if isinstance(val, float):\n            msg_str = '{:10s} | {:.10f} | {:10d} | {}'.format(\n                key,\n                val,\n                step,\n                cur_time\n            )\n        else:\n            msg_str = '{:10s} | {} | {:10d} | {}'.format(\n                key,\n                val,\n                step,\n                cur_time\n            )\n\n        self.logger.debug(msg_str)\n\n    def save_model(\n            self,\n            model,\n            optimizer=None,\n            outdir=None,\n            name='model'):\n        if self.debug:\n            return\n        if outdir is None:\n            outdir = self.exp_dir\n        print(' [*] saving model to {}, name: {}'.format(outdir, name))\n        # torch.save(model, os.path.join(outdir, name+'.pt'))\n        torch.save(model.state_dict(), os.path.join(outdir, name + '_params.pt'))\n\n        if optimizer is not None:\n            torch.save(optimizer.state_dict(), os.path.join(outdir, name + '_opt.pt'))\n\n    def load_model(\n            self,\n            path_exp,\n            device='cpu',\n            name='model.pt'):\n\n        path_pt = os.path.join(path_exp, name)\n        print(' [*] restoring model from', path_pt)\n        model = torch.load(path_pt, map_location=torch.device(device))\n        return model\n\n    def global_step_increment(self):\n        self.global_step += 1\n\n\ndef make_loss_report(\n        path_log,\n        path_figure='loss.png',\n        dpi=100):\n    # load logfile\n    monitor_vals = collections.defaultdict(list)\n    with open(path_log, 'r') as f:\n        for line in f:\n            try:\n                line = line.strip()\n                key, val, step, acc_time = line.split(' | ')\n                monitor_vals[key].append((float(val), int(step), acc_time))\n            except:\n                continue\n\n    # collect\n    step_train = [item[1] for item in monitor_vals['train loss']]\n    vals_train = [item[0] for item in monitor_vals['train loss']]\n\n    step_valid = [item[1] for item in monitor_vals['valid loss']]\n    vals_valid = [item[0] for item in monitor_vals['valid loss']]\n\n    x_min = step_valid[np.argmin(vals_valid)]\n    y_min = min(vals_valid)\n\n    # plot\n    fig = plt.figure(dpi=dpi)\n    plt.title('training process')\n    plt.plot(step_train, vals_train, label='train')\n    plt.plot(step_valid, vals_valid, label='valid')\n    plt.yscale('log')\n    plt.plot([x_min], [y_min], 'ro')\n    plt.legend(loc='upper right')\n    plt.tight_layout()\n    plt.savefig(path_figure)\n\n\ndef log(*args, **kwargs):\n    print(*args, **kwargs)\n    if flog is not None:\n        print(*args, file=flog, flush=True)"
  },
  {
    "path": "src/video2npz/dictionary_mix.py",
    "content": "preset_event2word = {\n    \"tempo\"     : {\n        0          : 0,\n        \"CONTI\"    : 1,\n        \"Tempo_0\"  : 2,\n        \"Tempo_1\"  : 3,\n        \"Tempo_2\"  : 4,\n        \"Tempo_3\"  : 5,\n        \"Tempo_4\"  : 6,\n        \"Tempo_5\"  : 7,\n        \"Tempo_6\"  : 8,\n        \"Tempo_7\"  : 9,\n        \"Tempo_8\"  : 10,\n        \"Tempo_9\"  : 11,\n        \"Tempo_10\" : 12,\n        \"Tempo_11\" : 13,\n        \"Tempo_12\" : 14,\n        \"Tempo_13\" : 15,\n        \"Tempo_14\" : 16,\n        \"Tempo_15\" : 17,\n        \"Tempo_16\" : 18,\n        \"Tempo_17\" : 19,\n        \"Tempo_18\" : 20,\n        \"Tempo_19\" : 21,\n        \"Tempo_20\" : 22,\n        \"Tempo_21\" : 23,\n        \"Tempo_22\" : 24,\n        \"Tempo_23\" : 25,\n        \"Tempo_24\" : 26,\n        \"Tempo_25\" : 27,\n        \"Tempo_26\" : 28,\n        \"Tempo_27\" : 29,\n        \"Tempo_28\" : 30,\n        \"Tempo_29\" : 31,\n        \"Tempo_30\" : 32,\n        \"Tempo_31\" : 33,\n        \"Tempo_32\" : 34,\n        \"Tempo_33\" : 35,\n        \"Tempo_34\" : 36,\n        \"Tempo_35\" : 37,\n        \"Tempo_36\" : 38,\n        \"Tempo_37\" : 39,\n        \"Tempo_38\" : 40,\n        \"Tempo_39\" : 41,\n        \"Tempo_40\" : 42,\n        \"Tempo_41\" : 43,\n        \"Tempo_42\" : 44,\n        \"Tempo_43\" : 45,\n        \"Tempo_44\" : 46,\n        \"Tempo_45\" : 47,\n        \"Tempo_46\" : 48,\n        \"Tempo_47\" : 49,\n        \"Tempo_48\" : 50,\n        \"Tempo_49\" : 51,\n        \"Tempo_50\" : 52,\n        \"Tempo_51\" : 53,\n        \"Tempo_52\" : 54,\n        \"Tempo_53\" : 55,\n        \"Tempo_54\" : 56,\n        \"Tempo_55\" : 57,\n        \"Tempo_56\" : 58,\n        \"Tempo_57\" : 59,\n        \"Tempo_58\" : 60,\n        \"Tempo_59\" : 61,\n        \"Tempo_60\" : 62,\n        \"Tempo_61\" : 63,\n        \"Tempo_62\" : 64,\n        \"Tempo_63\" : 65,\n        \"Tempo_64\" : 66,\n        \"Tempo_65\" : 67,\n        \"Tempo_66\" : 68,\n        \"Tempo_67\" : 69,\n        \"Tempo_68\" : 70,\n        \"Tempo_69\" : 71,\n        \"Tempo_70\" : 72,\n        \"Tempo_71\" : 73,\n        \"Tempo_72\" : 74,\n        \"Tempo_73\" : 75,\n        \"Tempo_74\" : 76,\n        \"Tempo_75\" : 77,\n        \"Tempo_76\" : 78,\n        \"Tempo_77\" : 79,\n        \"Tempo_78\" : 80,\n        \"Tempo_79\" : 81,\n        \"Tempo_80\" : 82,\n        \"Tempo_81\" : 83,\n        \"Tempo_82\" : 84,\n        \"Tempo_83\" : 85,\n        \"Tempo_84\" : 86,\n        \"Tempo_85\" : 87,\n        \"Tempo_86\" : 88,\n        \"Tempo_87\" : 89,\n        \"Tempo_88\" : 90,\n        \"Tempo_89\" : 91,\n        \"Tempo_90\" : 92,\n        \"Tempo_91\" : 93,\n        \"Tempo_92\" : 94,\n        \"Tempo_93\" : 95,\n        \"Tempo_94\" : 96,\n        \"Tempo_95\" : 97,\n        \"Tempo_96\" : 98,\n        \"Tempo_97\" : 99,\n        \"Tempo_98\" : 100,\n        \"Tempo_99\" : 101,\n        \"Tempo_100\": 102,\n        \"Tempo_101\": 103,\n        \"Tempo_102\": 104,\n        \"Tempo_103\": 105,\n        \"Tempo_104\": 106,\n        \"Tempo_105\": 107,\n        \"Tempo_106\": 108,\n        \"Tempo_107\": 109,\n        \"Tempo_108\": 110,\n        \"Tempo_109\": 111,\n        \"Tempo_110\": 112,\n        \"Tempo_111\": 113,\n        \"Tempo_112\": 114,\n        \"Tempo_113\": 115,\n        \"Tempo_114\": 116,\n        \"Tempo_115\": 117,\n        \"Tempo_116\": 118,\n        \"Tempo_117\": 119,\n        \"Tempo_118\": 120,\n        \"Tempo_119\": 121,\n        \"Tempo_120\": 122,\n        \"Tempo_121\": 123,\n        \"Tempo_122\": 124,\n        \"Tempo_123\": 125,\n        \"Tempo_124\": 126,\n        \"Tempo_125\": 127,\n        \"Tempo_126\": 128,\n        \"Tempo_127\": 129,\n        \"Tempo_128\": 130,\n        \"Tempo_129\": 131,\n        \"Tempo_130\": 132,\n        \"Tempo_131\": 133,\n        \"Tempo_132\": 134,\n        \"Tempo_133\": 135,\n        \"Tempo_134\": 136,\n        \"Tempo_135\": 137,\n        \"Tempo_136\": 138,\n        \"Tempo_137\": 139,\n        \"Tempo_138\": 140,\n        \"Tempo_139\": 141,\n        \"Tempo_140\": 142,\n        \"Tempo_141\": 143,\n        \"Tempo_142\": 144,\n        \"Tempo_143\": 145,\n        \"Tempo_144\": 146,\n        \"Tempo_145\": 147,\n        \"Tempo_146\": 148,\n        \"Tempo_147\": 149,\n        \"Tempo_148\": 150,\n        \"Tempo_149\": 151,\n        \"Tempo_150\": 152,\n        \"Tempo_151\": 153,\n        \"Tempo_152\": 154,\n        \"Tempo_153\": 155,\n        \"Tempo_154\": 156,\n        \"Tempo_155\": 157,\n        \"Tempo_156\": 158,\n        \"Tempo_157\": 159,\n        \"Tempo_158\": 160,\n        \"Tempo_159\": 161,\n        \"Tempo_160\": 162,\n        \"Tempo_161\": 163,\n        \"Tempo_162\": 164,\n        \"Tempo_163\": 165,\n        \"Tempo_164\": 166,\n        \"Tempo_165\": 167,\n        \"Tempo_166\": 168,\n        \"Tempo_167\": 169,\n        \"Tempo_168\": 170,\n        \"Tempo_169\": 171,\n        \"Tempo_170\": 172,\n        \"Tempo_171\": 173,\n        \"Tempo_172\": 174,\n        \"Tempo_173\": 175,\n        \"Tempo_174\": 176,\n        \"Tempo_175\": 177,\n        \"Tempo_176\": 178,\n        \"Tempo_177\": 179,\n        \"Tempo_178\": 180,\n        \"Tempo_179\": 181,\n        \"Tempo_180\": 182,\n        \"Tempo_181\": 183,\n        \"Tempo_182\": 184,\n        \"Tempo_183\": 185,\n        \"Tempo_184\": 186,\n        \"Tempo_185\": 187,\n        \"Tempo_186\": 188,\n        \"Tempo_187\": 189,\n        \"Tempo_188\": 190,\n        \"Tempo_189\": 191,\n        \"Tempo_190\": 192,\n        \"Tempo_191\": 193,\n        \"Tempo_192\": 194,\n        \"Tempo_193\": 195,\n        \"Tempo_194\": 196,\n        \"Tempo_195\": 197,\n        \"Tempo_196\": 198,\n        \"Tempo_197\": 199,\n        \"Tempo_198\": 200,\n        \"Tempo_199\": 201,\n        \"Tempo_200\": 202,\n        \"Tempo_201\": 203,\n        \"Tempo_202\": 204,\n        \"Tempo_203\": 205,\n        \"Tempo_204\": 206,\n        \"Tempo_205\": 207,\n        \"Tempo_206\": 208,\n        \"Tempo_207\": 209,\n        \"Tempo_208\": 210,\n        \"Tempo_209\": 211,\n        \"Tempo_210\": 212,\n        \"Tempo_211\": 213,\n        \"Tempo_212\": 214,\n        \"Tempo_213\": 215,\n        \"Tempo_214\": 216,\n        \"Tempo_215\": 217,\n        \"Tempo_216\": 218,\n        \"Tempo_217\": 219,\n        \"Tempo_218\": 220,\n        \"Tempo_219\": 221,\n        \"Tempo_220\": 222,\n        \"Tempo_221\": 223,\n        \"Tempo_222\": 224,\n        \"Tempo_223\": 225,\n        \"Tempo_224\": 226,\n        \"Tempo_225\": 227,\n        \"Tempo_226\": 228,\n        \"Tempo_227\": 229,\n        \"Tempo_228\": 230,\n        \"Tempo_229\": 231,\n        \"Tempo_230\": 232,\n        \"Tempo_231\": 233,\n        \"Tempo_232\": 234,\n        \"Tempo_233\": 235,\n        \"Tempo_234\": 236,\n        \"Tempo_235\": 237,\n        \"Tempo_236\": 238,\n        \"Tempo_237\": 239,\n        \"Tempo_238\": 240,\n        \"Tempo_239\": 241,\n        \"Tempo_240\": 242,\n        \"Tempo_241\": 243,\n        \"Tempo_242\": 244,\n        \"Tempo_243\": 245,\n        \"Tempo_244\": 246,\n        \"Tempo_245\": 247,\n        \"Tempo_246\": 248,\n        \"Tempo_247\": 249,\n        \"Tempo_248\": 250,\n        \"Tempo_249\": 251,\n        \"Tempo_250\": 252,\n        \"Tempo_251\": 253,\n        \"Tempo_252\": 254,\n        \"Tempo_253\": 255,\n        \"Tempo_254\": 256,\n        \"Tempo_255\": 257,\n        \"Tempo_256\": 258,\n        \"Tempo_257\": 259,\n        \"Tempo_258\": 260,\n        \"Tempo_259\": 261,\n        \"Tempo_260\": 262,\n        \"Tempo_261\": 263,\n        \"Tempo_262\": 264,\n        \"Tempo_263\": 265,\n        \"Tempo_264\": 266,\n        \"Tempo_265\": 267,\n        \"Tempo_266\": 268,\n        \"Tempo_267\": 269,\n        \"Tempo_268\": 270,\n        \"Tempo_269\": 271,\n        \"Tempo_270\": 272,\n        \"Tempo_271\": 273,\n        \"Tempo_272\": 274,\n        \"Tempo_273\": 275,\n        \"Tempo_274\": 276,\n        \"Tempo_275\": 277,\n        \"Tempo_276\": 278,\n        \"Tempo_277\": 279,\n        \"Tempo_278\": 280,\n        \"Tempo_279\": 281,\n        \"Tempo_280\": 282,\n        \"Tempo_281\": 283,\n        \"Tempo_282\": 284,\n        \"Tempo_283\": 285,\n        \"Tempo_284\": 286,\n        \"Tempo_285\": 287,\n        \"Tempo_286\": 288,\n        \"Tempo_287\": 289,\n        \"Tempo_288\": 290,\n        \"Tempo_289\": 291,\n        \"Tempo_290\": 292,\n        \"Tempo_291\": 293,\n        \"Tempo_292\": 294,\n        \"Tempo_293\": 295,\n        \"Tempo_294\": 296,\n        \"Tempo_295\": 297,\n        \"Tempo_296\": 298,\n        \"Tempo_297\": 299,\n        \"Tempo_298\": 300,\n        \"Tempo_299\": 301,\n        \"Tempo_300\": 302,\n        \"Tempo_301\": 303,\n        \"Tempo_302\": 304,\n        \"Tempo_303\": 305,\n        \"Tempo_304\": 306,\n        \"Tempo_305\": 307,\n        \"Tempo_306\": 308,\n        \"Tempo_307\": 309,\n        \"Tempo_308\": 310,\n        \"Tempo_309\": 311,\n        \"Tempo_310\": 312,\n        \"Tempo_311\": 313,\n        \"Tempo_312\": 314,\n        \"Tempo_313\": 315,\n        \"Tempo_314\": 316,\n        \"Tempo_315\": 317,\n        \"Tempo_316\": 318,\n        \"Tempo_317\": 319,\n        \"Tempo_318\": 320,\n        \"Tempo_319\": 321,\n        \"Tempo_320\": 322,\n        \"Tempo_321\": 323,\n        \"Tempo_322\": 324,\n        \"Tempo_323\": 325,\n        \"Tempo_324\": 326,\n        \"Tempo_325\": 327,\n        \"Tempo_326\": 328,\n        \"Tempo_327\": 329,\n        \"Tempo_328\": 330,\n        \"Tempo_329\": 331,\n        \"Tempo_330\": 332,\n        \"Tempo_331\": 333,\n        \"Tempo_332\": 334,\n        \"Tempo_333\": 335,\n        \"Tempo_334\": 336,\n        \"Tempo_335\": 337,\n        \"Tempo_336\": 338,\n        \"Tempo_337\": 339,\n        \"Tempo_338\": 340,\n        \"Tempo_339\": 341,\n        \"Tempo_340\": 342,\n        \"Tempo_341\": 343,\n        \"Tempo_342\": 344,\n        \"Tempo_343\": 345,\n        \"Tempo_344\": 346,\n        \"Tempo_345\": 347,\n        \"Tempo_346\": 348,\n        \"Tempo_347\": 349,\n        \"Tempo_348\": 350,\n        \"Tempo_349\": 351,\n        \"Tempo_350\": 352,\n        \"Tempo_351\": 353,\n        \"Tempo_352\": 354,\n        \"Tempo_353\": 355,\n        \"Tempo_354\": 356,\n        \"Tempo_355\": 357,\n        \"Tempo_356\": 358,\n        \"Tempo_357\": 359,\n        \"Tempo_358\": 360,\n        \"Tempo_359\": 361,\n        \"Tempo_360\": 362\n    },\n    \"chord\"     : {\n        0      : 0,\n        \"CONTI\": 1\n    },\n    \"beat\"      : {\n        0        : 0,\n        \"Beat_0\" : 1,\n        \"Beat_1\" : 2,\n        \"Beat_2\" : 3,\n        \"Beat_3\" : 4,\n        \"Beat_4\" : 5,\n        \"Beat_5\" : 6,\n        \"Beat_6\" : 7,\n        \"Beat_7\" : 8,\n        \"Beat_8\" : 9,\n        \"Beat_9\" : 10,\n        \"Beat_10\": 11,\n        \"Beat_11\": 12,\n        \"Beat_12\": 13,\n        \"Beat_13\": 14,\n        \"Beat_14\": 15,\n        \"Beat_15\": 16,\n        \"Bar\"    : 17,\n    },\n    \"type\"      : {\n        \"EOS\"   : 0,\n        \"M\"     : 1,\n        \"Note\"  : 2,\n        'Global': 3,\n    },\n    \"instr_type\": {\n        'None'   : 0,\n        'Drums'  : 1,\n        'Piano'  : 2,\n        'Guitar' : 3,\n        'Bass'   : 4,\n        'Strings': 5,\n    },\n    \"key/genre\" : {\n        \"None\"      : 0,\n        'C'         : 5,\n        'C#'        : 6,\n        'D'         : 7,\n        'D#'        : 8,\n        'E'         : 9,\n        'F'         : 10,\n        'F#'        : 11,\n        'G'         : 12,\n        'G#'        : 13,\n        'A'         : 14,\n        'A#'        : 15,\n        'B'         : 16,\n        'c'         : 17,\n        'c#'        : 18,\n        'd'         : 19,\n        'd#'        : 20,\n        'e'         : 21,\n        'f'         : 22,\n        'f#'        : 23,\n        'g'         : 24,\n        'g#'        : 25,\n        'a'         : 26,\n        'a#'        : 27,\n        'b'         : 28,\n\n        'classic'   : 29,\n        'country'   : 30,\n        'dance'     : 31,\n        'electronic': 32,\n        'pop'       : 33,\n        'rock'      : 34,\n\n        # 'happy': 29,\n        # 'sad': 30,\n\n        # 'Rock':         29,\n        # 'Rap':          30,\n        # 'Latin':        31,\n        # 'Jazz':         32,\n        # 'Electronic':   33,\n        # 'Punk':         34,\n        # 'Pop':          35,\n        # 'New Age':      36,\n        # 'Metal':        37,\n        # 'RnB':          38,\n        # 'Country':      39,\n        # 'Reggae':       40,\n        # 'Folk':         41,\n        # 'Blues':        42,\n        # 'World':        43\n    },\n    \"pitch\"     : {\n        0               : 0,\n        \"Note_Pitch_0\"  : 1,\n        \"Note_Pitch_1\"  : 2,\n        \"Note_Pitch_2\"  : 3,\n        \"Note_Pitch_3\"  : 4,\n        \"Note_Pitch_4\"  : 5,\n        \"Note_Pitch_5\"  : 6,\n        \"Note_Pitch_6\"  : 7,\n        \"Note_Pitch_7\"  : 8,\n        \"Note_Pitch_8\"  : 9,\n        \"Note_Pitch_9\"  : 10,\n        \"Note_Pitch_10\" : 11,\n        \"Note_Pitch_11\" : 12,\n        \"Note_Pitch_12\" : 13,\n        \"Note_Pitch_13\" : 14,\n        \"Note_Pitch_14\" : 15,\n        \"Note_Pitch_15\" : 16,\n        \"Note_Pitch_16\" : 17,\n        \"Note_Pitch_17\" : 18,\n        \"Note_Pitch_18\" : 19,\n        \"Note_Pitch_19\" : 20,\n        \"Note_Pitch_20\" : 21,\n        \"Note_Pitch_21\" : 22,\n        \"Note_Pitch_22\" : 23,\n        \"Note_Pitch_23\" : 24,\n        \"Note_Pitch_24\" : 25,\n        \"Note_Pitch_25\" : 26,\n        \"Note_Pitch_26\" : 27,\n        \"Note_Pitch_27\" : 28,\n        \"Note_Pitch_28\" : 29,\n        \"Note_Pitch_29\" : 30,\n        \"Note_Pitch_30\" : 31,\n        \"Note_Pitch_31\" : 32,\n        \"Note_Pitch_32\" : 33,\n        \"Note_Pitch_33\" : 34,\n        \"Note_Pitch_34\" : 35,\n        \"Note_Pitch_35\" : 36,\n        \"Note_Pitch_36\" : 37,\n        \"Note_Pitch_37\" : 38,\n        \"Note_Pitch_38\" : 39,\n        \"Note_Pitch_39\" : 40,\n        \"Note_Pitch_40\" : 41,\n        \"Note_Pitch_41\" : 42,\n        \"Note_Pitch_42\" : 43,\n        \"Note_Pitch_43\" : 44,\n        \"Note_Pitch_44\" : 45,\n        \"Note_Pitch_45\" : 46,\n        \"Note_Pitch_46\" : 47,\n        \"Note_Pitch_47\" : 48,\n        \"Note_Pitch_48\" : 49,\n        \"Note_Pitch_49\" : 50,\n        \"Note_Pitch_50\" : 51,\n        \"Note_Pitch_51\" : 52,\n        \"Note_Pitch_52\" : 53,\n        \"Note_Pitch_53\" : 54,\n        \"Note_Pitch_54\" : 55,\n        \"Note_Pitch_55\" : 56,\n        \"Note_Pitch_56\" : 57,\n        \"Note_Pitch_57\" : 58,\n        \"Note_Pitch_58\" : 59,\n        \"Note_Pitch_59\" : 60,\n        \"Note_Pitch_60\" : 61,\n        \"Note_Pitch_61\" : 62,\n        \"Note_Pitch_62\" : 63,\n        \"Note_Pitch_63\" : 64,\n        \"Note_Pitch_64\" : 65,\n        \"Note_Pitch_65\" : 66,\n        \"Note_Pitch_66\" : 67,\n        \"Note_Pitch_67\" : 68,\n        \"Note_Pitch_68\" : 69,\n        \"Note_Pitch_69\" : 70,\n        \"Note_Pitch_70\" : 71,\n        \"Note_Pitch_71\" : 72,\n        \"Note_Pitch_72\" : 73,\n        \"Note_Pitch_73\" : 74,\n        \"Note_Pitch_74\" : 75,\n        \"Note_Pitch_75\" : 76,\n        \"Note_Pitch_76\" : 77,\n        \"Note_Pitch_77\" : 78,\n        \"Note_Pitch_78\" : 79,\n        \"Note_Pitch_79\" : 80,\n        \"Note_Pitch_80\" : 81,\n        \"Note_Pitch_81\" : 82,\n        \"Note_Pitch_82\" : 83,\n        \"Note_Pitch_83\" : 84,\n        \"Note_Pitch_84\" : 85,\n        \"Note_Pitch_85\" : 86,\n        \"Note_Pitch_86\" : 87,\n        \"Note_Pitch_87\" : 88,\n        \"Note_Pitch_88\" : 89,\n        \"Note_Pitch_89\" : 90,\n        \"Note_Pitch_90\" : 91,\n        \"Note_Pitch_91\" : 92,\n        \"Note_Pitch_92\" : 93,\n        \"Note_Pitch_93\" : 94,\n        \"Note_Pitch_94\" : 95,\n        \"Note_Pitch_95\" : 96,\n        \"Note_Pitch_96\" : 97,\n        \"Note_Pitch_97\" : 98,\n        \"Note_Pitch_98\" : 99,\n        \"Note_Pitch_99\" : 100,\n        \"Note_Pitch_100\": 101,\n        \"Note_Pitch_101\": 102,\n        \"Note_Pitch_102\": 103,\n        \"Note_Pitch_103\": 104,\n        \"Note_Pitch_104\": 105,\n        \"Note_Pitch_105\": 106,\n        \"Note_Pitch_106\": 107,\n        \"Note_Pitch_107\": 108,\n        \"Note_Pitch_108\": 109,\n        \"Note_Pitch_109\": 110,\n        \"Note_Pitch_110\": 111,\n        \"Note_Pitch_111\": 112,\n        \"Note_Pitch_112\": 113,\n        \"Note_Pitch_113\": 114,\n        \"Note_Pitch_114\": 115,\n        \"Note_Pitch_115\": 116,\n        \"Note_Pitch_116\": 117,\n        \"Note_Pitch_117\": 118,\n        \"Note_Pitch_118\": 119,\n        \"Note_Pitch_119\": 120,\n        \"Note_Pitch_120\": 121,\n        \"Note_Pitch_121\": 122,\n        \"Note_Pitch_122\": 123,\n        \"Note_Pitch_123\": 124,\n        \"Note_Pitch_124\": 125,\n        \"Note_Pitch_125\": 126,\n        \"Note_Pitch_126\": 127,\n        \"Note_Pitch_127\": 128,\n    },\n    \"duration\"  : {\n        0                   : 0,\n        \"Note_Duration_0\"   : 1,\n        \"Note_Duration_120\" : 2,\n        \"Note_Duration_240\" : 3,\n        \"Note_Duration_360\" : 4,\n        \"Note_Duration_480\" : 5,\n        \"Note_Duration_600\" : 6,\n        \"Note_Duration_720\" : 7,\n        \"Note_Duration_840\" : 8,\n        \"Note_Duration_960\" : 9,\n        \"Note_Duration_1080\": 10,\n        \"Note_Duration_1200\": 11,\n        \"Note_Duration_1320\": 12,\n        \"Note_Duration_1440\": 13,\n        \"Note_Duration_1560\": 14,\n        \"Note_Duration_1680\": 15,\n        \"Note_Duration_1800\": 16,\n        \"Note_Duration_1920\": 17\n    },\n    \"velocity\"  : {\n        0                  : 0,\n        \"Note_Velocity_0\"  : 1,\n        \"Note_Velocity_1\"  : 2,\n        \"Note_Velocity_2\"  : 3,\n        \"Note_Velocity_3\"  : 4,\n        \"Note_Velocity_4\"  : 5,\n        \"Note_Velocity_5\"  : 6,\n        \"Note_Velocity_6\"  : 7,\n        \"Note_Velocity_7\"  : 8,\n        \"Note_Velocity_8\"  : 9,\n        \"Note_Velocity_9\"  : 10,\n        \"Note_Velocity_10\" : 11,\n        \"Note_Velocity_11\" : 12,\n        \"Note_Velocity_12\" : 13,\n        \"Note_Velocity_13\" : 14,\n        \"Note_Velocity_14\" : 15,\n        \"Note_Velocity_15\" : 16,\n        \"Note_Velocity_16\" : 17,\n        \"Note_Velocity_17\" : 18,\n        \"Note_Velocity_18\" : 19,\n        \"Note_Velocity_19\" : 20,\n        \"Note_Velocity_20\" : 21,\n        \"Note_Velocity_21\" : 22,\n        \"Note_Velocity_22\" : 23,\n        \"Note_Velocity_23\" : 24,\n        \"Note_Velocity_24\" : 25,\n        \"Note_Velocity_25\" : 26,\n        \"Note_Velocity_26\" : 27,\n        \"Note_Velocity_27\" : 28,\n        \"Note_Velocity_28\" : 29,\n        \"Note_Velocity_29\" : 30,\n        \"Note_Velocity_30\" : 31,\n        \"Note_Velocity_31\" : 32,\n        \"Note_Velocity_32\" : 33,\n        \"Note_Velocity_33\" : 34,\n        \"Note_Velocity_34\" : 35,\n        \"Note_Velocity_35\" : 36,\n        \"Note_Velocity_36\" : 37,\n        \"Note_Velocity_37\" : 38,\n        \"Note_Velocity_38\" : 39,\n        \"Note_Velocity_39\" : 40,\n        \"Note_Velocity_40\" : 41,\n        \"Note_Velocity_41\" : 42,\n        \"Note_Velocity_42\" : 43,\n        \"Note_Velocity_43\" : 44,\n        \"Note_Velocity_44\" : 45,\n        \"Note_Velocity_45\" : 46,\n        \"Note_Velocity_46\" : 47,\n        \"Note_Velocity_47\" : 48,\n        \"Note_Velocity_48\" : 49,\n        \"Note_Velocity_49\" : 50,\n        \"Note_Velocity_50\" : 51,\n        \"Note_Velocity_51\" : 52,\n        \"Note_Velocity_52\" : 53,\n        \"Note_Velocity_53\" : 54,\n        \"Note_Velocity_54\" : 55,\n        \"Note_Velocity_55\" : 56,\n        \"Note_Velocity_56\" : 57,\n        \"Note_Velocity_57\" : 58,\n        \"Note_Velocity_58\" : 59,\n        \"Note_Velocity_59\" : 60,\n        \"Note_Velocity_60\" : 61,\n        \"Note_Velocity_61\" : 62,\n        \"Note_Velocity_62\" : 63,\n        \"Note_Velocity_63\" : 64,\n        \"Note_Velocity_64\" : 65,\n        \"Note_Velocity_65\" : 66,\n        \"Note_Velocity_66\" : 67,\n        \"Note_Velocity_67\" : 68,\n        \"Note_Velocity_68\" : 69,\n        \"Note_Velocity_69\" : 70,\n        \"Note_Velocity_70\" : 71,\n        \"Note_Velocity_71\" : 72,\n        \"Note_Velocity_72\" : 73,\n        \"Note_Velocity_73\" : 74,\n        \"Note_Velocity_74\" : 75,\n        \"Note_Velocity_75\" : 76,\n        \"Note_Velocity_76\" : 77,\n        \"Note_Velocity_77\" : 78,\n        \"Note_Velocity_78\" : 79,\n        \"Note_Velocity_79\" : 80,\n        \"Note_Velocity_80\" : 81,\n        \"Note_Velocity_81\" : 82,\n        \"Note_Velocity_82\" : 83,\n        \"Note_Velocity_83\" : 84,\n        \"Note_Velocity_84\" : 85,\n        \"Note_Velocity_85\" : 86,\n        \"Note_Velocity_86\" : 87,\n        \"Note_Velocity_87\" : 88,\n        \"Note_Velocity_88\" : 89,\n        \"Note_Velocity_89\" : 90,\n        \"Note_Velocity_90\" : 91,\n        \"Note_Velocity_91\" : 92,\n        \"Note_Velocity_92\" : 93,\n        \"Note_Velocity_93\" : 94,\n        \"Note_Velocity_94\" : 95,\n        \"Note_Velocity_95\" : 96,\n        \"Note_Velocity_96\" : 97,\n        \"Note_Velocity_97\" : 98,\n        \"Note_Velocity_98\" : 99,\n        \"Note_Velocity_99\" : 100,\n        \"Note_Velocity_100\": 101,\n        \"Note_Velocity_101\": 102,\n        \"Note_Velocity_102\": 103,\n        \"Note_Velocity_103\": 104,\n        \"Note_Velocity_104\": 105,\n        \"Note_Velocity_105\": 106,\n        \"Note_Velocity_106\": 107,\n        \"Note_Velocity_107\": 108,\n        \"Note_Velocity_108\": 109,\n        \"Note_Velocity_109\": 110,\n        \"Note_Velocity_110\": 111,\n        \"Note_Velocity_111\": 112,\n        \"Note_Velocity_112\": 113,\n        \"Note_Velocity_113\": 114,\n        \"Note_Velocity_114\": 115,\n        \"Note_Velocity_115\": 116,\n        \"Note_Velocity_116\": 117,\n        \"Note_Velocity_117\": 118,\n        \"Note_Velocity_118\": 119,\n        \"Note_Velocity_119\": 120,\n        \"Note_Velocity_120\": 121,\n        \"Note_Velocity_121\": 122,\n        \"Note_Velocity_122\": 123,\n        \"Note_Velocity_123\": 124,\n        \"Note_Velocity_124\": 125,\n        \"Note_Velocity_125\": 126,\n        \"Note_Velocity_126\": 127,\n        \"Note_Velocity_127\": 128,\n        \"Note_Velocity_128\": 129,\n        \"Note_Velocity_129\": 130,\n        \"Note_Velocity_130\": 131,\n        \"Note_Velocity_131\": 132,\n        \"Note_Velocity_132\": 133,\n        \"Note_Velocity_133\": 134,\n        \"Note_Velocity_134\": 135,\n        \"Note_Velocity_135\": 136,\n        \"Note_Velocity_136\": 137,\n        \"Note_Velocity_137\": 138,\n        \"Note_Velocity_138\": 139,\n        \"Note_Velocity_139\": 140,\n        \"Note_Velocity_140\": 141,\n        \"Note_Velocity_141\": 142,\n        \"Note_Velocity_142\": 143,\n        \"Note_Velocity_143\": 144,\n        \"Note_Velocity_144\": 145,\n        \"Note_Velocity_145\": 146,\n        \"Note_Velocity_146\": 147,\n        \"Note_Velocity_147\": 148,\n        \"Note_Velocity_148\": 149,\n        \"Note_Velocity_149\": 150,\n        \"Note_Velocity_150\": 151,\n        \"Note_Velocity_151\": 152,\n        \"Note_Velocity_152\": 153,\n        \"Note_Velocity_153\": 154,\n        \"Note_Velocity_154\": 155,\n        \"Note_Velocity_155\": 156,\n        \"Note_Velocity_156\": 157,\n        \"Note_Velocity_157\": 158,\n        \"Note_Velocity_158\": 159,\n        \"Note_Velocity_159\": 160,\n        \"Note_Velocity_160\": 161,\n        \"Note_Velocity_161\": 162,\n        \"Note_Velocity_162\": 163,\n        \"Note_Velocity_163\": 164,\n        \"Note_Velocity_164\": 165,\n        \"Note_Velocity_165\": 166,\n        \"Note_Velocity_166\": 167,\n        \"Note_Velocity_167\": 168,\n        \"Note_Velocity_168\": 169,\n        \"Note_Velocity_169\": 170,\n        \"Note_Velocity_170\": 171,\n        \"Note_Velocity_171\": 172,\n        \"Note_Velocity_172\": 173,\n        \"Note_Velocity_173\": 174,\n        \"Note_Velocity_174\": 175,\n        \"Note_Velocity_175\": 176,\n        \"Note_Velocity_176\": 177,\n        \"Note_Velocity_177\": 178,\n        \"Note_Velocity_178\": 179,\n        \"Note_Velocity_179\": 180,\n        \"Note_Velocity_180\": 181,\n        \"Note_Velocity_181\": 182,\n        \"Note_Velocity_182\": 183,\n        \"Note_Velocity_183\": 184,\n        \"Note_Velocity_184\": 185,\n        \"Note_Velocity_185\": 186,\n        \"Note_Velocity_186\": 187,\n        \"Note_Velocity_187\": 188,\n        \"Note_Velocity_188\": 189,\n        \"Note_Velocity_189\": 190,\n        \"Note_Velocity_190\": 191,\n        \"Note_Velocity_191\": 192,\n        \"Note_Velocity_192\": 193,\n        \"Note_Velocity_193\": 194,\n        \"Note_Velocity_194\": 195,\n        \"Note_Velocity_195\": 196,\n        \"Note_Velocity_196\": 197,\n        \"Note_Velocity_197\": 198,\n        \"Note_Velocity_198\": 199,\n        \"Note_Velocity_199\": 200,\n        \"Note_Velocity_200\": 201,\n        \"Note_Velocity_201\": 202,\n        \"Note_Velocity_202\": 203,\n        \"Note_Velocity_203\": 204,\n        \"Note_Velocity_204\": 205,\n        \"Note_Velocity_205\": 206,\n        \"Note_Velocity_206\": 207,\n        \"Note_Velocity_207\": 208,\n        \"Note_Velocity_208\": 209,\n        \"Note_Velocity_209\": 210,\n        \"Note_Velocity_210\": 211,\n        \"Note_Velocity_211\": 212,\n        \"Note_Velocity_212\": 213,\n        \"Note_Velocity_213\": 214,\n        \"Note_Velocity_214\": 215,\n        \"Note_Velocity_215\": 216,\n        \"Note_Velocity_216\": 217,\n        \"Note_Velocity_217\": 218,\n        \"Note_Velocity_218\": 219,\n        \"Note_Velocity_219\": 220,\n        \"Note_Velocity_220\": 221,\n        \"Note_Velocity_221\": 222,\n        \"Note_Velocity_222\": 223,\n        \"Note_Velocity_223\": 224,\n        \"Note_Velocity_224\": 225,\n        \"Note_Velocity_225\": 226,\n        \"Note_Velocity_226\": 227,\n        \"Note_Velocity_227\": 228,\n        \"Note_Velocity_228\": 229,\n        \"Note_Velocity_229\": 230,\n        \"Note_Velocity_230\": 231,\n        \"Note_Velocity_231\": 232,\n        \"Note_Velocity_232\": 233,\n        \"Note_Velocity_233\": 234,\n        \"Note_Velocity_234\": 235,\n        \"Note_Velocity_235\": 236,\n        \"Note_Velocity_236\": 237,\n        \"Note_Velocity_237\": 238,\n        \"Note_Velocity_238\": 239,\n        \"Note_Velocity_239\": 240,\n        \"Note_Velocity_240\": 241,\n        \"Note_Velocity_241\": 242,\n        \"Note_Velocity_242\": 243,\n        \"Note_Velocity_243\": 244,\n        \"Note_Velocity_244\": 245,\n        \"Note_Velocity_245\": 246,\n        \"Note_Velocity_246\": 247,\n        \"Note_Velocity_247\": 248,\n        \"Note_Velocity_248\": 249,\n        \"Note_Velocity_249\": 250,\n        \"Note_Velocity_250\": 251,\n        \"Note_Velocity_251\": 252,\n        \"Note_Velocity_252\": 253,\n        \"Note_Velocity_253\": 254,\n        \"Note_Velocity_254\": 255,\n        \"Note_Velocity_255\": 256,\n        \"Note_Velocity_256\": 257,\n        \"Note_Velocity_257\": 258,\n        \"Note_Velocity_258\": 259,\n        \"Note_Velocity_259\": 260,\n        \"Note_Velocity_260\": 261,\n        \"Note_Velocity_261\": 262,\n        \"Note_Velocity_262\": 263,\n        \"Note_Velocity_263\": 264,\n        \"Note_Velocity_264\": 265,\n        \"Note_Velocity_265\": 266,\n        \"Note_Velocity_266\": 267,\n        \"Note_Velocity_267\": 268,\n        \"Note_Velocity_268\": 269,\n        \"Note_Velocity_269\": 270,\n        \"Note_Velocity_270\": 271,\n        \"Note_Velocity_271\": 272,\n        \"Note_Velocity_272\": 273,\n        \"Note_Velocity_273\": 274,\n        \"Note_Velocity_274\": 275,\n        \"Note_Velocity_275\": 276,\n        \"Note_Velocity_276\": 277,\n        \"Note_Velocity_277\": 278,\n        \"Note_Velocity_278\": 279,\n        \"Note_Velocity_279\": 280,\n        \"Note_Velocity_280\": 281,\n        \"Note_Velocity_281\": 282,\n        \"Note_Velocity_282\": 283,\n        \"Note_Velocity_283\": 284,\n        \"Note_Velocity_284\": 285,\n        \"Note_Velocity_285\": 286,\n        \"Note_Velocity_286\": 287,\n        \"Note_Velocity_287\": 288,\n        \"Note_Velocity_288\": 289,\n        \"Note_Velocity_289\": 290,\n        \"Note_Velocity_290\": 291,\n        \"Note_Velocity_291\": 292,\n        \"Note_Velocity_292\": 293,\n        \"Note_Velocity_293\": 294,\n        \"Note_Velocity_294\": 295,\n        \"Note_Velocity_295\": 296,\n        \"Note_Velocity_296\": 297,\n        \"Note_Velocity_297\": 298,\n        \"Note_Velocity_298\": 299,\n        \"Note_Velocity_299\": 300,\n        \"Note_Velocity_300\": 301,\n        \"Note_Velocity_301\": 302,\n        \"Note_Velocity_302\": 303,\n        \"Note_Velocity_303\": 304,\n        \"Note_Velocity_304\": 305,\n        \"Note_Velocity_305\": 306,\n        \"Note_Velocity_306\": 307,\n        \"Note_Velocity_307\": 308,\n        \"Note_Velocity_308\": 309,\n        \"Note_Velocity_309\": 310,\n        \"Note_Velocity_310\": 311,\n        \"Note_Velocity_311\": 312,\n        \"Note_Velocity_312\": 313,\n        \"Note_Velocity_313\": 314,\n        \"Note_Velocity_314\": 315,\n        \"Note_Velocity_315\": 316,\n        \"Note_Velocity_316\": 317,\n        \"Note_Velocity_317\": 318,\n        \"Note_Velocity_318\": 319,\n        \"Note_Velocity_319\": 320,\n        \"Note_Velocity_320\": 321,\n        \"Note_Velocity_321\": 322,\n        \"Note_Velocity_322\": 323,\n        \"Note_Velocity_323\": 324,\n        \"Note_Velocity_324\": 325,\n        \"Note_Velocity_325\": 326,\n        \"Note_Velocity_326\": 327,\n        \"Note_Velocity_327\": 328,\n        \"Note_Velocity_328\": 329,\n        \"Note_Velocity_329\": 330,\n        \"Note_Velocity_330\": 331,\n        \"Note_Velocity_331\": 332,\n        \"Note_Velocity_332\": 333,\n        \"Note_Velocity_333\": 334,\n        \"Note_Velocity_334\": 335,\n        \"Note_Velocity_335\": 336,\n        \"Note_Velocity_336\": 337,\n        \"Note_Velocity_337\": 338,\n        \"Note_Velocity_338\": 339,\n        \"Note_Velocity_339\": 340,\n        \"Note_Velocity_340\": 341,\n        \"Note_Velocity_341\": 342,\n        \"Note_Velocity_342\": 343,\n        \"Note_Velocity_343\": 344,\n        \"Note_Velocity_344\": 345,\n        \"Note_Velocity_345\": 346,\n        \"Note_Velocity_346\": 347,\n        \"Note_Velocity_347\": 348,\n        \"Note_Velocity_348\": 349,\n        \"Note_Velocity_349\": 350,\n        \"Note_Velocity_350\": 351,\n        \"Note_Velocity_351\": 352,\n        \"Note_Velocity_352\": 353,\n        \"Note_Velocity_353\": 354,\n        \"Note_Velocity_354\": 355,\n        \"Note_Velocity_355\": 356,\n        \"Note_Velocity_356\": 357,\n        \"Note_Velocity_357\": 358,\n        \"Note_Velocity_358\": 359,\n        \"Note_Velocity_359\": 360,\n        \"Note_Velocity_360\": 361\n    },\n    \"boundary\"  : {\n        0         : 0,\n        \"None\"    : 1,\n        \"Boundary\": 2,\n    },\n    # 'density': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],\n    'variance'  : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],\n}\n\npreset_word2event = {\n    \"tempo\"     : {\n        0  : 0,\n        1  : \"CONTI\",\n        2  : \"Tempo_0\",\n        3  : \"Tempo_1\",\n        4  : \"Tempo_2\",\n        5  : \"Tempo_3\",\n        6  : \"Tempo_4\",\n        7  : \"Tempo_5\",\n        8  : \"Tempo_6\",\n        9  : \"Tempo_7\",\n        10 : \"Tempo_8\",\n        11 : \"Tempo_9\",\n        12 : \"Tempo_10\",\n        13 : \"Tempo_11\",\n        14 : \"Tempo_12\",\n        15 : \"Tempo_13\",\n        16 : \"Tempo_14\",\n        17 : \"Tempo_15\",\n        18 : \"Tempo_16\",\n        19 : \"Tempo_17\",\n        20 : \"Tempo_18\",\n        21 : \"Tempo_19\",\n        22 : \"Tempo_20\",\n        23 : \"Tempo_21\",\n        24 : \"Tempo_22\",\n        25 : \"Tempo_23\",\n        26 : \"Tempo_24\",\n        27 : \"Tempo_25\",\n        28 : \"Tempo_26\",\n        29 : \"Tempo_27\",\n        30 : \"Tempo_28\",\n        31 : \"Tempo_29\",\n        32 : \"Tempo_30\",\n        33 : \"Tempo_31\",\n        34 : \"Tempo_32\",\n        35 : \"Tempo_33\",\n        36 : \"Tempo_34\",\n        37 : \"Tempo_35\",\n        38 : \"Tempo_36\",\n        39 : \"Tempo_37\",\n        40 : \"Tempo_38\",\n        41 : \"Tempo_39\",\n        42 : \"Tempo_40\",\n        43 : \"Tempo_41\",\n        44 : \"Tempo_42\",\n        45 : \"Tempo_43\",\n        46 : \"Tempo_44\",\n        47 : \"Tempo_45\",\n        48 : \"Tempo_46\",\n        49 : \"Tempo_47\",\n        50 : \"Tempo_48\",\n        51 : \"Tempo_49\",\n        52 : \"Tempo_50\",\n        53 : \"Tempo_51\",\n        54 : \"Tempo_52\",\n        55 : \"Tempo_53\",\n        56 : \"Tempo_54\",\n        57 : \"Tempo_55\",\n        58 : \"Tempo_56\",\n        59 : \"Tempo_57\",\n        60 : \"Tempo_58\",\n        61 : \"Tempo_59\",\n        62 : \"Tempo_60\",\n        63 : \"Tempo_61\",\n        64 : \"Tempo_62\",\n        65 : \"Tempo_63\",\n        66 : \"Tempo_64\",\n        67 : \"Tempo_65\",\n        68 : \"Tempo_66\",\n        69 : \"Tempo_67\",\n        70 : \"Tempo_68\",\n        71 : \"Tempo_69\",\n        72 : \"Tempo_70\",\n        73 : \"Tempo_71\",\n        74 : \"Tempo_72\",\n        75 : \"Tempo_73\",\n        76 : \"Tempo_74\",\n        77 : \"Tempo_75\",\n        78 : \"Tempo_76\",\n        79 : \"Tempo_77\",\n        80 : \"Tempo_78\",\n        81 : \"Tempo_79\",\n        82 : \"Tempo_80\",\n        83 : \"Tempo_81\",\n        84 : \"Tempo_82\",\n        85 : \"Tempo_83\",\n        86 : \"Tempo_84\",\n        87 : \"Tempo_85\",\n        88 : \"Tempo_86\",\n        89 : \"Tempo_87\",\n        90 : \"Tempo_88\",\n        91 : \"Tempo_89\",\n        92 : \"Tempo_90\",\n        93 : \"Tempo_91\",\n        94 : \"Tempo_92\",\n        95 : \"Tempo_93\",\n        96 : \"Tempo_94\",\n        97 : \"Tempo_95\",\n        98 : \"Tempo_96\",\n        99 : \"Tempo_97\",\n        100: \"Tempo_98\",\n        101: \"Tempo_99\",\n        102: \"Tempo_100\",\n        103: \"Tempo_101\",\n        104: \"Tempo_102\",\n        105: \"Tempo_103\",\n        106: \"Tempo_104\",\n        107: \"Tempo_105\",\n        108: \"Tempo_106\",\n        109: \"Tempo_107\",\n        110: \"Tempo_108\",\n        111: \"Tempo_109\",\n        112: \"Tempo_110\",\n        113: \"Tempo_111\",\n        114: \"Tempo_112\",\n        115: \"Tempo_113\",\n        116: \"Tempo_114\",\n        117: \"Tempo_115\",\n        118: \"Tempo_116\",\n        119: \"Tempo_117\",\n        120: \"Tempo_118\",\n        121: \"Tempo_119\",\n        122: \"Tempo_120\",\n        123: \"Tempo_121\",\n        124: \"Tempo_122\",\n        125: \"Tempo_123\",\n        126: \"Tempo_124\",\n        127: \"Tempo_125\",\n        128: \"Tempo_126\",\n        129: \"Tempo_127\",\n        130: \"Tempo_128\",\n        131: \"Tempo_129\",\n        132: \"Tempo_130\",\n        133: \"Tempo_131\",\n        134: \"Tempo_132\",\n        135: \"Tempo_133\",\n        136: \"Tempo_134\",\n        137: \"Tempo_135\",\n        138: \"Tempo_136\",\n        139: \"Tempo_137\",\n        140: \"Tempo_138\",\n        141: \"Tempo_139\",\n        142: \"Tempo_140\",\n        143: \"Tempo_141\",\n        144: \"Tempo_142\",\n        145: \"Tempo_143\",\n        146: \"Tempo_144\",\n        147: \"Tempo_145\",\n        148: \"Tempo_146\",\n        149: \"Tempo_147\",\n        150: \"Tempo_148\",\n        151: \"Tempo_149\",\n        152: \"Tempo_150\",\n        153: \"Tempo_151\",\n        154: \"Tempo_152\",\n        155: \"Tempo_153\",\n        156: \"Tempo_154\",\n        157: \"Tempo_155\",\n        158: \"Tempo_156\",\n        159: \"Tempo_157\",\n        160: \"Tempo_158\",\n        161: \"Tempo_159\",\n        162: \"Tempo_160\",\n        163: \"Tempo_161\",\n        164: \"Tempo_162\",\n        165: \"Tempo_163\",\n        166: \"Tempo_164\",\n        167: \"Tempo_165\",\n        168: \"Tempo_166\",\n        169: \"Tempo_167\",\n        170: \"Tempo_168\",\n        171: \"Tempo_169\",\n        172: \"Tempo_170\",\n        173: \"Tempo_171\",\n        174: \"Tempo_172\",\n        175: \"Tempo_173\",\n        176: \"Tempo_174\",\n        177: \"Tempo_175\",\n        178: \"Tempo_176\",\n        179: \"Tempo_177\",\n        180: \"Tempo_178\",\n        181: \"Tempo_179\",\n        182: \"Tempo_180\",\n        183: \"Tempo_181\",\n        184: \"Tempo_182\",\n        185: \"Tempo_183\",\n        186: \"Tempo_184\",\n        187: \"Tempo_185\",\n        188: \"Tempo_186\",\n        189: \"Tempo_187\",\n        190: \"Tempo_188\",\n        191: \"Tempo_189\",\n        192: \"Tempo_190\",\n        193: \"Tempo_191\",\n        194: \"Tempo_192\",\n        195: \"Tempo_193\",\n        196: \"Tempo_194\",\n        197: \"Tempo_195\",\n        198: \"Tempo_196\",\n        199: \"Tempo_197\",\n        200: \"Tempo_198\",\n        201: \"Tempo_199\",\n        202: \"Tempo_200\",\n        203: \"Tempo_201\",\n        204: \"Tempo_202\",\n        205: \"Tempo_203\",\n        206: \"Tempo_204\",\n        207: \"Tempo_205\",\n        208: \"Tempo_206\",\n        209: \"Tempo_207\",\n        210: \"Tempo_208\",\n        211: \"Tempo_209\",\n        212: \"Tempo_210\",\n        213: \"Tempo_211\",\n        214: \"Tempo_212\",\n        215: \"Tempo_213\",\n        216: \"Tempo_214\",\n        217: \"Tempo_215\",\n        218: \"Tempo_216\",\n        219: \"Tempo_217\",\n        220: \"Tempo_218\",\n        221: \"Tempo_219\",\n        222: \"Tempo_220\",\n        223: \"Tempo_221\",\n        224: \"Tempo_222\",\n        225: \"Tempo_223\",\n        226: \"Tempo_224\",\n        227: \"Tempo_225\",\n        228: \"Tempo_226\",\n        229: \"Tempo_227\",\n        230: \"Tempo_228\",\n        231: \"Tempo_229\",\n        232: \"Tempo_230\",\n        233: \"Tempo_231\",\n        234: \"Tempo_232\",\n        235: \"Tempo_233\",\n        236: \"Tempo_234\",\n        237: \"Tempo_235\",\n        238: \"Tempo_236\",\n        239: \"Tempo_237\",\n        240: \"Tempo_238\",\n        241: \"Tempo_239\",\n        242: \"Tempo_240\",\n        243: \"Tempo_241\",\n        244: \"Tempo_242\",\n        245: \"Tempo_243\",\n        246: \"Tempo_244\",\n        247: \"Tempo_245\",\n        248: \"Tempo_246\",\n        249: \"Tempo_247\",\n        250: \"Tempo_248\",\n        251: \"Tempo_249\",\n        252: \"Tempo_250\",\n        253: \"Tempo_251\",\n        254: \"Tempo_252\",\n        255: \"Tempo_253\",\n        256: \"Tempo_254\",\n        257: \"Tempo_255\",\n        258: \"Tempo_256\",\n        259: \"Tempo_257\",\n        260: \"Tempo_258\",\n        261: \"Tempo_259\",\n        262: \"Tempo_260\",\n        263: \"Tempo_261\",\n        264: \"Tempo_262\",\n        265: \"Tempo_263\",\n        266: \"Tempo_264\",\n        267: \"Tempo_265\",\n        268: \"Tempo_266\",\n        269: \"Tempo_267\",\n        270: \"Tempo_268\",\n        271: \"Tempo_269\",\n        272: \"Tempo_270\",\n        273: \"Tempo_271\",\n        274: \"Tempo_272\",\n        275: \"Tempo_273\",\n        276: \"Tempo_274\",\n        277: \"Tempo_275\",\n        278: \"Tempo_276\",\n        279: \"Tempo_277\",\n        280: \"Tempo_278\",\n        281: \"Tempo_279\",\n        282: \"Tempo_280\",\n        283: \"Tempo_281\",\n        284: \"Tempo_282\",\n        285: \"Tempo_283\",\n        286: \"Tempo_284\",\n        287: \"Tempo_285\",\n        288: \"Tempo_286\",\n        289: \"Tempo_287\",\n        290: \"Tempo_288\",\n        291: \"Tempo_289\",\n        292: \"Tempo_290\",\n        293: \"Tempo_291\",\n        294: \"Tempo_292\",\n        295: \"Tempo_293\",\n        296: \"Tempo_294\",\n        297: \"Tempo_295\",\n        298: \"Tempo_296\",\n        299: \"Tempo_297\",\n        300: \"Tempo_298\",\n        301: \"Tempo_299\",\n        302: \"Tempo_300\",\n        303: \"Tempo_301\",\n        304: \"Tempo_302\",\n        305: \"Tempo_303\",\n        306: \"Tempo_304\",\n        307: \"Tempo_305\",\n        308: \"Tempo_306\",\n        309: \"Tempo_307\",\n        310: \"Tempo_308\",\n        311: \"Tempo_309\",\n        312: \"Tempo_310\",\n        313: \"Tempo_311\",\n        314: \"Tempo_312\",\n        315: \"Tempo_313\",\n        316: \"Tempo_314\",\n        317: \"Tempo_315\",\n        318: \"Tempo_316\",\n        319: \"Tempo_317\",\n        320: \"Tempo_318\",\n        321: \"Tempo_319\",\n        322: \"Tempo_320\",\n        323: \"Tempo_321\",\n        324: \"Tempo_322\",\n        325: \"Tempo_323\",\n        326: \"Tempo_324\",\n        327: \"Tempo_325\",\n        328: \"Tempo_326\",\n        329: \"Tempo_327\",\n        330: \"Tempo_328\",\n        331: \"Tempo_329\",\n        332: \"Tempo_330\",\n        333: \"Tempo_331\",\n        334: \"Tempo_332\",\n        335: \"Tempo_333\",\n        336: \"Tempo_334\",\n        337: \"Tempo_335\",\n        338: \"Tempo_336\",\n        339: \"Tempo_337\",\n        340: \"Tempo_338\",\n        341: \"Tempo_339\",\n        342: \"Tempo_340\",\n        343: \"Tempo_341\",\n        344: \"Tempo_342\",\n        345: \"Tempo_343\",\n        346: \"Tempo_344\",\n        347: \"Tempo_345\",\n        348: \"Tempo_346\",\n        349: \"Tempo_347\",\n        350: \"Tempo_348\",\n        351: \"Tempo_349\",\n        352: \"Tempo_350\",\n        353: \"Tempo_351\",\n        354: \"Tempo_352\",\n        355: \"Tempo_353\",\n        356: \"Tempo_354\",\n        357: \"Tempo_355\",\n        358: \"Tempo_356\",\n        359: \"Tempo_357\",\n        360: \"Tempo_358\",\n        361: \"Tempo_359\",\n        362: \"Tempo_360\"\n    },\n    \"chord\"     : {\n        0: \"0\",\n        1: \"CONTI\"\n    },\n    \"bar-beat\"  : {\n        0 : 0,\n        1 : \"Bar\",\n        2 : \"Beat_0\",\n        3 : \"Beat_1\",\n        4 : \"Beat_2\",\n        5 : \"Beat_3\",\n        6 : \"Beat_4\",\n        7 : \"Beat_5\",\n        8 : \"Beat_6\",\n        9 : \"Beat_7\",\n        10: \"Beat_8\",\n        11: \"Beat_9\",\n        12: \"Beat_10\",\n        13: \"Beat_11\",\n        14: \"Beat_12\",\n        15: \"Beat_13\",\n        16: \"Beat_14\",\n        17: \"Beat_15\"\n    },\n    \"type\"      : {\n        0: \"EOS\",\n        1: \"Metrical\",\n        2: \"Note\",\n        3: \"Seg\",\n    },\n    \"instr_type\": {\n        0: 'None',\n        1: 'Drums',\n        2: 'Piano',\n        3: 'Guitar',\n        4: 'Bass',\n        5: 'Strings',\n    },\n    \"pitch\"     : {\n        0  : 0,\n        1  : \"Note_Pitch_0\",\n        2  : \"Note_Pitch_1\",\n        3  : \"Note_Pitch_2\",\n        4  : \"Note_Pitch_3\",\n        5  : \"Note_Pitch_4\",\n        6  : \"Note_Pitch_5\",\n        7  : \"Note_Pitch_6\",\n        8  : \"Note_Pitch_7\",\n        9  : \"Note_Pitch_8\",\n        10 : \"Note_Pitch_9\",\n        11 : \"Note_Pitch_10\",\n        12 : \"Note_Pitch_11\",\n        13 : \"Note_Pitch_12\",\n        14 : \"Note_Pitch_13\",\n        15 : \"Note_Pitch_14\",\n        16 : \"Note_Pitch_15\",\n        17 : \"Note_Pitch_16\",\n        18 : \"Note_Pitch_17\",\n        19 : \"Note_Pitch_18\",\n        20 : \"Note_Pitch_19\",\n        21 : \"Note_Pitch_20\",\n        22 : \"Note_Pitch_21\",\n        23 : \"Note_Pitch_22\",\n        24 : \"Note_Pitch_23\",\n        25 : \"Note_Pitch_24\",\n        26 : \"Note_Pitch_25\",\n        27 : \"Note_Pitch_26\",\n        28 : \"Note_Pitch_27\",\n        29 : \"Note_Pitch_28\",\n        30 : \"Note_Pitch_29\",\n        31 : \"Note_Pitch_30\",\n        32 : \"Note_Pitch_31\",\n        33 : \"Note_Pitch_32\",\n        34 : \"Note_Pitch_33\",\n        35 : \"Note_Pitch_34\",\n        36 : \"Note_Pitch_35\",\n        37 : \"Note_Pitch_36\",\n        38 : \"Note_Pitch_37\",\n        39 : \"Note_Pitch_38\",\n        40 : \"Note_Pitch_39\",\n        41 : \"Note_Pitch_40\",\n        42 : \"Note_Pitch_41\",\n        43 : \"Note_Pitch_42\",\n        44 : \"Note_Pitch_43\",\n        45 : \"Note_Pitch_44\",\n        46 : \"Note_Pitch_45\",\n        47 : \"Note_Pitch_46\",\n        48 : \"Note_Pitch_47\",\n        49 : \"Note_Pitch_48\",\n        50 : \"Note_Pitch_49\",\n        51 : \"Note_Pitch_50\",\n        52 : \"Note_Pitch_51\",\n        53 : \"Note_Pitch_52\",\n        54 : \"Note_Pitch_53\",\n        55 : \"Note_Pitch_54\",\n        56 : \"Note_Pitch_55\",\n        57 : \"Note_Pitch_56\",\n        58 : \"Note_Pitch_57\",\n        59 : \"Note_Pitch_58\",\n        60 : \"Note_Pitch_59\",\n        61 : \"Note_Pitch_60\",\n        62 : \"Note_Pitch_61\",\n        63 : \"Note_Pitch_62\",\n        64 : \"Note_Pitch_63\",\n        65 : \"Note_Pitch_64\",\n        66 : \"Note_Pitch_65\",\n        67 : \"Note_Pitch_66\",\n        68 : \"Note_Pitch_67\",\n        69 : \"Note_Pitch_68\",\n        70 : \"Note_Pitch_69\",\n        71 : \"Note_Pitch_70\",\n        72 : \"Note_Pitch_71\",\n        73 : \"Note_Pitch_72\",\n        74 : \"Note_Pitch_73\",\n        75 : \"Note_Pitch_74\",\n        76 : \"Note_Pitch_75\",\n        77 : \"Note_Pitch_76\",\n        78 : \"Note_Pitch_77\",\n        79 : \"Note_Pitch_78\",\n        80 : \"Note_Pitch_79\",\n        81 : \"Note_Pitch_80\",\n        82 : \"Note_Pitch_81\",\n        83 : \"Note_Pitch_82\",\n        84 : \"Note_Pitch_83\",\n        85 : \"Note_Pitch_84\",\n        86 : \"Note_Pitch_85\",\n        87 : \"Note_Pitch_86\",\n        88 : \"Note_Pitch_87\",\n        89 : \"Note_Pitch_88\",\n        90 : \"Note_Pitch_89\",\n        91 : \"Note_Pitch_90\",\n        92 : \"Note_Pitch_91\",\n        93 : \"Note_Pitch_92\",\n        94 : \"Note_Pitch_93\",\n        95 : \"Note_Pitch_94\",\n        96 : \"Note_Pitch_95\",\n        97 : \"Note_Pitch_96\",\n        98 : \"Note_Pitch_97\",\n        99 : \"Note_Pitch_98\",\n        100: \"Note_Pitch_99\",\n        101: \"Note_Pitch_100\",\n        102: \"Note_Pitch_101\",\n        103: \"Note_Pitch_102\",\n        104: \"Note_Pitch_103\",\n        105: \"Note_Pitch_104\",\n        106: \"Note_Pitch_105\",\n        107: \"Note_Pitch_106\",\n        108: \"Note_Pitch_107\",\n        109: \"Note_Pitch_108\",\n        110: \"Note_Pitch_109\",\n        111: \"Note_Pitch_110\",\n        112: \"Note_Pitch_111\",\n        113: \"Note_Pitch_112\",\n        114: \"Note_Pitch_113\",\n        115: \"Note_Pitch_114\",\n        116: \"Note_Pitch_115\",\n        117: \"Note_Pitch_116\",\n        118: \"Note_Pitch_117\",\n        119: \"Note_Pitch_118\",\n        120: \"Note_Pitch_119\",\n        121: \"Note_Pitch_120\",\n        122: \"Note_Pitch_121\",\n        123: \"Note_Pitch_122\",\n        124: \"Note_Pitch_123\",\n        125: \"Note_Pitch_124\",\n        126: \"Note_Pitch_125\",\n        127: \"Note_Pitch_126\",\n        128: \"Note_Pitch_127\",\n        129: \"Note_Pitch_128\",\n    },\n    \"duration\"  : {\n        0 : 0,\n        1 : \"Note_Duration_0\",\n        2 : \"Note_Duration_120\",\n        3 : \"Note_Duration_240\",\n        4 : \"Note_Duration_360\",\n        5 : \"Note_Duration_480\",\n        6 : \"Note_Duration_600\",\n        7 : \"Note_Duration_720\",\n        8 : \"Note_Duration_840\",\n        9 : \"Note_Duration_960\",\n        10: \"Note_Duration_1080\",\n        11: \"Note_Duration_1200\",\n        12: \"Note_Duration_1320\",\n        13: \"Note_Duration_1440\",\n        14: \"Note_Duration_1560\",\n        15: \"Note_Duration_1680\",\n        16: \"Note_Duration_1800\",\n        17: \"Note_Duration_1920\"\n    },\n    \"velocity\"  : {\n        0  : 0,\n        1  : \"Note_Velocity_0\",\n        2  : \"Note_Velocity_1\",\n        3  : \"Note_Velocity_2\",\n        4  : \"Note_Velocity_3\",\n        5  : \"Note_Velocity_4\",\n        6  : \"Note_Velocity_5\",\n        7  : \"Note_Velocity_6\",\n        8  : \"Note_Velocity_7\",\n        9  : \"Note_Velocity_8\",\n        10 : \"Note_Velocity_9\",\n        11 : \"Note_Velocity_10\",\n        12 : \"Note_Velocity_11\",\n        13 : \"Note_Velocity_12\",\n        14 : \"Note_Velocity_13\",\n        15 : \"Note_Velocity_14\",\n        16 : \"Note_Velocity_15\",\n        17 : \"Note_Velocity_16\",\n        18 : \"Note_Velocity_17\",\n        19 : \"Note_Velocity_18\",\n        20 : \"Note_Velocity_19\",\n        21 : \"Note_Velocity_20\",\n        22 : \"Note_Velocity_21\",\n        23 : \"Note_Velocity_22\",\n        24 : \"Note_Velocity_23\",\n        25 : \"Note_Velocity_24\",\n        26 : \"Note_Velocity_25\",\n        27 : \"Note_Velocity_26\",\n        28 : \"Note_Velocity_27\",\n        29 : \"Note_Velocity_28\",\n        30 : \"Note_Velocity_29\",\n        31 : \"Note_Velocity_30\",\n        32 : \"Note_Velocity_31\",\n        33 : \"Note_Velocity_32\",\n        34 : \"Note_Velocity_33\",\n        35 : \"Note_Velocity_34\",\n        36 : \"Note_Velocity_35\",\n        37 : \"Note_Velocity_36\",\n        38 : \"Note_Velocity_37\",\n        39 : \"Note_Velocity_38\",\n        40 : \"Note_Velocity_39\",\n        41 : \"Note_Velocity_40\",\n        42 : \"Note_Velocity_41\",\n        43 : \"Note_Velocity_42\",\n        44 : \"Note_Velocity_43\",\n        45 : \"Note_Velocity_44\",\n        46 : \"Note_Velocity_45\",\n        47 : \"Note_Velocity_46\",\n        48 : \"Note_Velocity_47\",\n        49 : \"Note_Velocity_48\",\n        50 : \"Note_Velocity_49\",\n        51 : \"Note_Velocity_50\",\n        52 : \"Note_Velocity_51\",\n        53 : \"Note_Velocity_52\",\n        54 : \"Note_Velocity_53\",\n        55 : \"Note_Velocity_54\",\n        56 : \"Note_Velocity_55\",\n        57 : \"Note_Velocity_56\",\n        58 : \"Note_Velocity_57\",\n        59 : \"Note_Velocity_58\",\n        60 : \"Note_Velocity_59\",\n        61 : \"Note_Velocity_60\",\n        62 : \"Note_Velocity_61\",\n        63 : \"Note_Velocity_62\",\n        64 : \"Note_Velocity_63\",\n        65 : \"Note_Velocity_64\",\n        66 : \"Note_Velocity_65\",\n        67 : \"Note_Velocity_66\",\n        68 : \"Note_Velocity_67\",\n        69 : \"Note_Velocity_68\",\n        70 : \"Note_Velocity_69\",\n        71 : \"Note_Velocity_70\",\n        72 : \"Note_Velocity_71\",\n        73 : \"Note_Velocity_72\",\n        74 : \"Note_Velocity_73\",\n        75 : \"Note_Velocity_74\",\n        76 : \"Note_Velocity_75\",\n        77 : \"Note_Velocity_76\",\n        78 : \"Note_Velocity_77\",\n        79 : \"Note_Velocity_78\",\n        80 : \"Note_Velocity_79\",\n        81 : \"Note_Velocity_80\",\n        82 : \"Note_Velocity_81\",\n        83 : \"Note_Velocity_82\",\n        84 : \"Note_Velocity_83\",\n        85 : \"Note_Velocity_84\",\n        86 : \"Note_Velocity_85\",\n        87 : \"Note_Velocity_86\",\n        88 : \"Note_Velocity_87\",\n        89 : \"Note_Velocity_88\",\n        90 : \"Note_Velocity_89\",\n        91 : \"Note_Velocity_90\",\n        92 : \"Note_Velocity_91\",\n        93 : \"Note_Velocity_92\",\n        94 : \"Note_Velocity_93\",\n        95 : \"Note_Velocity_94\",\n        96 : \"Note_Velocity_95\",\n        97 : \"Note_Velocity_96\",\n        98 : \"Note_Velocity_97\",\n        99 : \"Note_Velocity_98\",\n        100: \"Note_Velocity_99\",\n        101: \"Note_Velocity_100\",\n        102: \"Note_Velocity_101\",\n        103: \"Note_Velocity_102\",\n        104: \"Note_Velocity_103\",\n        105: \"Note_Velocity_104\",\n        106: \"Note_Velocity_105\",\n        107: \"Note_Velocity_106\",\n        108: \"Note_Velocity_107\",\n        109: \"Note_Velocity_108\",\n        110: \"Note_Velocity_109\",\n        111: \"Note_Velocity_110\",\n        112: \"Note_Velocity_111\",\n        113: \"Note_Velocity_112\",\n        114: \"Note_Velocity_113\",\n        115: \"Note_Velocity_114\",\n        116: \"Note_Velocity_115\",\n        117: \"Note_Velocity_116\",\n        118: \"Note_Velocity_117\",\n        119: \"Note_Velocity_118\",\n        120: \"Note_Velocity_119\",\n        121: \"Note_Velocity_120\",\n        122: \"Note_Velocity_121\",\n        123: \"Note_Velocity_122\",\n        124: \"Note_Velocity_123\",\n        125: \"Note_Velocity_124\",\n        126: \"Note_Velocity_125\",\n        127: \"Note_Velocity_126\",\n        128: \"Note_Velocity_127\",\n        129: \"Note_Velocity_128\",\n        130: \"Note_Velocity_129\",\n        131: \"Note_Velocity_130\",\n        132: \"Note_Velocity_131\",\n        133: \"Note_Velocity_132\",\n        134: \"Note_Velocity_133\",\n        135: \"Note_Velocity_134\",\n        136: \"Note_Velocity_135\",\n        137: \"Note_Velocity_136\",\n        138: \"Note_Velocity_137\",\n        139: \"Note_Velocity_138\",\n        140: \"Note_Velocity_139\",\n        141: \"Note_Velocity_140\",\n        142: \"Note_Velocity_141\",\n        143: \"Note_Velocity_142\",\n        144: \"Note_Velocity_143\",\n        145: \"Note_Velocity_144\",\n        146: \"Note_Velocity_145\",\n        147: \"Note_Velocity_146\",\n        148: \"Note_Velocity_147\",\n        149: \"Note_Velocity_148\",\n        150: \"Note_Velocity_149\",\n        151: \"Note_Velocity_150\",\n        152: \"Note_Velocity_151\",\n        153: \"Note_Velocity_152\",\n        154: \"Note_Velocity_153\",\n        155: \"Note_Velocity_154\",\n        156: \"Note_Velocity_155\",\n        157: \"Note_Velocity_156\",\n        158: \"Note_Velocity_157\",\n        159: \"Note_Velocity_158\",\n        160: \"Note_Velocity_159\",\n        161: \"Note_Velocity_160\",\n        162: \"Note_Velocity_161\",\n        163: \"Note_Velocity_162\",\n        164: \"Note_Velocity_163\",\n        165: \"Note_Velocity_164\",\n        166: \"Note_Velocity_165\",\n        167: \"Note_Velocity_166\",\n        168: \"Note_Velocity_167\",\n        169: \"Note_Velocity_168\",\n        170: \"Note_Velocity_169\",\n        171: \"Note_Velocity_170\",\n        172: \"Note_Velocity_171\",\n        173: \"Note_Velocity_172\",\n        174: \"Note_Velocity_173\",\n        175: \"Note_Velocity_174\",\n        176: \"Note_Velocity_175\",\n        177: \"Note_Velocity_176\",\n        178: \"Note_Velocity_177\",\n        179: \"Note_Velocity_178\",\n        180: \"Note_Velocity_179\",\n        181: \"Note_Velocity_180\",\n        182: \"Note_Velocity_181\",\n        183: \"Note_Velocity_182\",\n        184: \"Note_Velocity_183\",\n        185: \"Note_Velocity_184\",\n        186: \"Note_Velocity_185\",\n        187: \"Note_Velocity_186\",\n        188: \"Note_Velocity_187\",\n        189: \"Note_Velocity_188\",\n        190: \"Note_Velocity_189\",\n        191: \"Note_Velocity_190\",\n        192: \"Note_Velocity_191\",\n        193: \"Note_Velocity_192\",\n        194: \"Note_Velocity_193\",\n        195: \"Note_Velocity_194\",\n        196: \"Note_Velocity_195\",\n        197: \"Note_Velocity_196\",\n        198: \"Note_Velocity_197\",\n        199: \"Note_Velocity_198\",\n        200: \"Note_Velocity_199\",\n        201: \"Note_Velocity_200\",\n        202: \"Note_Velocity_201\",\n        203: \"Note_Velocity_202\",\n        204: \"Note_Velocity_203\",\n        205: \"Note_Velocity_204\",\n        206: \"Note_Velocity_205\",\n        207: \"Note_Velocity_206\",\n        208: \"Note_Velocity_207\",\n        209: \"Note_Velocity_208\",\n        210: \"Note_Velocity_209\",\n        211: \"Note_Velocity_210\",\n        212: \"Note_Velocity_211\",\n        213: \"Note_Velocity_212\",\n        214: \"Note_Velocity_213\",\n        215: \"Note_Velocity_214\",\n        216: \"Note_Velocity_215\",\n        217: \"Note_Velocity_216\",\n        218: \"Note_Velocity_217\",\n        219: \"Note_Velocity_218\",\n        220: \"Note_Velocity_219\",\n        221: \"Note_Velocity_220\",\n        222: \"Note_Velocity_221\",\n        223: \"Note_Velocity_222\",\n        224: \"Note_Velocity_223\",\n        225: \"Note_Velocity_224\",\n        226: \"Note_Velocity_225\",\n        227: \"Note_Velocity_226\",\n        228: \"Note_Velocity_227\",\n        229: \"Note_Velocity_228\",\n        230: \"Note_Velocity_229\",\n        231: \"Note_Velocity_230\",\n        232: \"Note_Velocity_231\",\n        233: \"Note_Velocity_232\",\n        234: \"Note_Velocity_233\",\n        235: \"Note_Velocity_234\",\n        236: \"Note_Velocity_235\",\n        237: \"Note_Velocity_236\",\n        238: \"Note_Velocity_237\",\n        239: \"Note_Velocity_238\",\n        240: \"Note_Velocity_239\",\n        241: \"Note_Velocity_240\",\n        242: \"Note_Velocity_241\",\n        243: \"Note_Velocity_242\",\n        244: \"Note_Velocity_243\",\n        245: \"Note_Velocity_244\",\n        246: \"Note_Velocity_245\",\n        247: \"Note_Velocity_246\",\n        248: \"Note_Velocity_247\",\n        249: \"Note_Velocity_248\",\n        250: \"Note_Velocity_249\",\n        251: \"Note_Velocity_250\",\n        252: \"Note_Velocity_251\",\n        253: \"Note_Velocity_252\",\n        254: \"Note_Velocity_253\",\n        255: \"Note_Velocity_254\",\n        256: \"Note_Velocity_255\",\n        257: \"Note_Velocity_256\",\n        258: \"Note_Velocity_257\",\n        259: \"Note_Velocity_258\",\n        260: \"Note_Velocity_259\",\n        261: \"Note_Velocity_260\",\n        262: \"Note_Velocity_261\",\n        263: \"Note_Velocity_262\",\n        264: \"Note_Velocity_263\",\n        265: \"Note_Velocity_264\",\n        266: \"Note_Velocity_265\",\n        267: \"Note_Velocity_266\",\n        268: \"Note_Velocity_267\",\n        269: \"Note_Velocity_268\",\n        270: \"Note_Velocity_269\",\n        271: \"Note_Velocity_270\",\n        272: \"Note_Velocity_271\",\n        273: \"Note_Velocity_272\",\n        274: \"Note_Velocity_273\",\n        275: \"Note_Velocity_274\",\n        276: \"Note_Velocity_275\",\n        277: \"Note_Velocity_276\",\n        278: \"Note_Velocity_277\",\n        279: \"Note_Velocity_278\",\n        280: \"Note_Velocity_279\",\n        281: \"Note_Velocity_280\",\n        282: \"Note_Velocity_281\",\n        283: \"Note_Velocity_282\",\n        284: \"Note_Velocity_283\",\n        285: \"Note_Velocity_284\",\n        286: \"Note_Velocity_285\",\n        287: \"Note_Velocity_286\",\n        288: \"Note_Velocity_287\",\n        289: \"Note_Velocity_288\",\n        290: \"Note_Velocity_289\",\n        291: \"Note_Velocity_290\",\n        292: \"Note_Velocity_291\",\n        293: \"Note_Velocity_292\",\n        294: \"Note_Velocity_293\",\n        295: \"Note_Velocity_294\",\n        296: \"Note_Velocity_295\",\n        297: \"Note_Velocity_296\",\n        298: \"Note_Velocity_297\",\n        299: \"Note_Velocity_298\",\n        300: \"Note_Velocity_299\",\n        301: \"Note_Velocity_300\",\n        302: \"Note_Velocity_301\",\n        303: \"Note_Velocity_302\",\n        304: \"Note_Velocity_303\",\n        305: \"Note_Velocity_304\",\n        306: \"Note_Velocity_305\",\n        307: \"Note_Velocity_306\",\n        308: \"Note_Velocity_307\",\n        309: \"Note_Velocity_308\",\n        310: \"Note_Velocity_309\",\n        311: \"Note_Velocity_310\",\n        312: \"Note_Velocity_311\",\n        313: \"Note_Velocity_312\",\n        314: \"Note_Velocity_313\",\n        315: \"Note_Velocity_314\",\n        316: \"Note_Velocity_315\",\n        317: \"Note_Velocity_316\",\n        318: \"Note_Velocity_317\",\n        319: \"Note_Velocity_318\",\n        320: \"Note_Velocity_319\",\n        321: \"Note_Velocity_320\",\n        322: \"Note_Velocity_321\",\n        323: \"Note_Velocity_322\",\n        324: \"Note_Velocity_323\",\n        325: \"Note_Velocity_324\",\n        326: \"Note_Velocity_325\",\n        327: \"Note_Velocity_326\",\n        328: \"Note_Velocity_327\",\n        329: \"Note_Velocity_328\",\n        330: \"Note_Velocity_329\",\n        331: \"Note_Velocity_330\",\n        332: \"Note_Velocity_331\",\n        333: \"Note_Velocity_332\",\n        334: \"Note_Velocity_333\",\n        335: \"Note_Velocity_334\",\n        336: \"Note_Velocity_335\",\n        337: \"Note_Velocity_336\",\n        338: \"Note_Velocity_337\",\n        339: \"Note_Velocity_338\",\n        340: \"Note_Velocity_339\",\n        341: \"Note_Velocity_340\",\n        342: \"Note_Velocity_341\",\n        343: \"Note_Velocity_342\",\n        344: \"Note_Velocity_343\",\n        345: \"Note_Velocity_344\",\n        346: \"Note_Velocity_345\",\n        347: \"Note_Velocity_346\",\n        348: \"Note_Velocity_347\",\n        349: \"Note_Velocity_348\",\n        350: \"Note_Velocity_349\",\n        351: \"Note_Velocity_350\",\n        352: \"Note_Velocity_351\",\n        353: \"Note_Velocity_352\",\n        354: \"Note_Velocity_353\",\n        355: \"Note_Velocity_354\",\n        356: \"Note_Velocity_355\",\n        357: \"Note_Velocity_356\",\n        358: \"Note_Velocity_357\",\n        359: \"Note_Velocity_358\",\n        360: \"Note_Velocity_359\",\n        361: \"Note_Velocity_360\"\n    },\n    \"boundary\"  : {\n        0: 0,\n        1: \"None\",\n        2: \"Boundary\",\n    },\n    \"key\"       : {\n        0 : 0,\n        1 : \"None\",\n        2 : 'C',\n        3 : 'C#',\n        4 : 'D',\n        5 : 'D#',\n        6 : 'E',\n        7 : 'F',\n        8 : 'F#',\n        9 : 'G',\n        10: 'G#',\n        11: 'A',\n        12: 'A#',\n        13: 'B',\n        14: 'c',\n        15: 'c#',\n        16: 'd',\n        17: 'd#',\n        18: 'e',\n        19: 'f',\n        20: 'f#',\n        21: 'g',\n        22: 'g#',\n        23: 'a',\n        24: 'a#',\n        25: 'b',\n    }\n}"
  },
  {
    "path": "src/video2npz/metadata2numpy_mix.py",
    "content": "#/usr/bin/env python\n# -*- coding: UTF-8 -*-\nimport json\nimport os\nimport math\nimport argparse\n\nimport numpy as np\n\nfrom dictionary_mix import preset_event2word\nfrom stat_mix import vbeat_weight_percentile, fmpb_percentile\n\nRESOLUTION = 16\nDIMENSION = {\n    'beat'    : 0,\n    'density' : 1,\n    'strength': 2,\n    'i_beat'  : 3,\n    'n_beat'  : 4,\n    'p_beat'  : 5,\n}\nN_DIMENSION = len(DIMENSION)\n\n\ndef _cal_density(flow_magnitude):\n    for i, percentile in enumerate(fmpb_percentile):\n        if flow_magnitude < percentile:\n            return i\n    return len(fmpb_percentile)\n\n\ndef _cal_strength(weight):\n    for i, percentile in enumerate(vbeat_weight_percentile):\n        if weight < percentile:\n            return i\n    return len(vbeat_weight_percentile)\n\n\ndef _get_beat_token(beat, strength, i_beat, n_beat):\n    l = [[0] * N_DIMENSION]\n    l[0][DIMENSION['beat']] = preset_event2word['beat']['Beat_%d' % beat]\n    l[0][DIMENSION['strength']] = strength\n    l[0][DIMENSION['i_beat']] = i_beat\n    l[0][DIMENSION['n_beat']] = n_beat\n    l[0][DIMENSION['p_beat']] = round(float(i_beat) / n_beat * 100) + 1\n    return l\n\n\ndef _get_bar_token(density, i_beat, n_beat):\n    l = [[0] * N_DIMENSION]\n    l[0][DIMENSION['beat']] = preset_event2word['beat']['Bar']\n    l[0][DIMENSION['density']] = density + 1\n    l[0][DIMENSION['i_beat']] = i_beat\n    l[0][DIMENSION['n_beat']] = n_beat\n    l[0][DIMENSION['p_beat']] = round(float(i_beat) / n_beat * 100) + 1\n    return l\n\n\ndef metadata2numpy(metadata):\n    vbeats = metadata['vbeats']\n    fmpb = metadata['flow_magnitude_per_bar']\n    n_beat = int(math.ceil(float(metadata['duration']) / 60 * float(metadata['tempo']) * 4))\n\n    n_bars = 0  # 已添加 bar token 个数\n    l = []\n    for vbeat in vbeats:\n        # add bar token\n        while int(vbeat['bar']) >= n_bars:\n            i_beat = n_bars * RESOLUTION\n            l += _get_bar_token(density=_cal_density(fmpb[n_bars]), i_beat=i_beat, n_beat=n_beat)\n            n_bars += 1\n        # add beat token\n        i_beat = int(vbeat['bar']) * RESOLUTION + int(vbeat['tick'])\n        l += _get_beat_token(beat=int(vbeat['tick']), strength=_cal_strength(vbeat['weight']), i_beat=i_beat,\n                             n_beat=n_beat)\n    # add empty bars\n    while n_bars < len(fmpb):\n        i_beat = n_bars * RESOLUTION\n        l += _get_bar_token(density=_cal_density(fmpb[n_bars]), i_beat=i_beat, n_beat=n_beat)\n        n_bars += 1\n\n    return np.asarray(l, dtype=int)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--out_dir', default=\"../../inference/\")\n    parser.add_argument('--video', default=\"final_640.mp4\")\n    parser.add_argument('--metadata', default=\"metadata.json\")\n    args = parser.parse_args()\n\n    video_name = os.path.basename(args.video)\n\n    with open(args.metadata) as f:\n        metadata = json.load(f)\n\n    target_path = os.path.join(args.out_dir, video_name.replace('.mp4', '.npz'))\n\n    print('processing to save to %s' % target_path)\n    input_numpy = metadata2numpy(metadata)\n    np.savez(target_path, input=input_numpy)\n    print(\"saved to \" + str(target_path))"
  },
  {
    "path": "src/video2npz/optical_flow.py",
    "content": "#encoding=utf-8\nimport cv2\nimport argparse\nimport os\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport skvideo.io\nfrom tqdm import tqdm\n\n\ndef makedirs(dirs):\n    for dir in dirs:\n        if not os.path.exists(dir):\n            os.makedirs(dir)\n\n\nvideo_dir = '../../videos/'\nflow_dir = 'flow/'\nfig_dir = 'fig/'\nmakedirs([video_dir, flow_dir, fig_dir, 'optical_flow/'])\n\nTIME_PER_BAR = 2  # 暂定2s一小节\n\n# 文字参数\nORG = (50, 50)\nFONT = cv2.FONT_HERSHEY_SIMPLEX\nFONT_SCALE = 1\nCOLOR = (0, 0, 255)\nTHICKNESS = 2\n\n\ndef dense_optical_flow(method, video_path, params=[], to_gray=False):\n    #\tprint(video_path)\n    assert os.path.exists(video_path)\n    metadata = skvideo.io.ffprobe(video_path)\n    print(\"video loaded successfully\")\n    frame, time = metadata['video']['@avg_frame_rate'].split('/')\n    fps = round(float(frame) / float(time))\n    if os.path.exists(os.path.join(flow_dir, os.path.basename(video_path).split('.')[0] + '.npz')):\n        flow_magnitude_list = list(\n            np.load(os.path.join(flow_dir, os.path.basename(video_path).split('.')[0] + '.npz'))['flow'])\n    else:\n        # Read the video and first frame\n        video = skvideo.io.vread(video_path)[:]\n        n_frames = len(video)  # 总帧数\n        old_frame = video[0]\n\n        # crate HSV & make Value a constant\n        hsv = np.zeros_like(old_frame)\n        hsv[..., 1] = 255\n\n        # Preprocessing for exact method\n        if to_gray:\n            old_frame = cv2.cvtColor(old_frame, cv2.COLOR_RGB2GRAY)\n\n        flow_magnitude_list = []\n        for i in tqdm(range(1, n_frames)):\n            # Read the next frame\n            new_frame = video[i]\n\n            # Preprocessing for exact method\n            if to_gray:\n                new_frame = cv2.cvtColor(new_frame, cv2.COLOR_RGB2GRAY)\n\n            # Calculate Optical Flow\n            flow = method(old_frame, new_frame, None, *params)\n            flow_magnitude = np.mean(np.abs(flow))\n            flow_magnitude_list.append(flow_magnitude)\n\n            # Update the previous frame\n            old_frame = new_frame\n\n    frame_per_bar = TIME_PER_BAR * fps\n    flow_magnitude_per_bar = []\n    temp = np.zeros((len(flow_magnitude_list)))\n    for i in np.arange(0, len(flow_magnitude_list), frame_per_bar):\n        mean_flow = np.mean(flow_magnitude_list[int(i): min(int(i + frame_per_bar), len(flow_magnitude_list))])\n        flow_magnitude_per_bar.append(mean_flow)\n        temp[int(i): min(int(i + frame_per_bar), len(flow_magnitude_list))] = mean_flow\n\n    np.savez(os.path.join(flow_dir, os.path.basename(video_path).split('.')[0] + '.npz'),\n             flow=np.asarray(flow_magnitude_list))\n\n    # 绘制flow强度折线图\n    x = np.arange(0, len(flow_magnitude_list))\n    plt.figure(figsize=(10, 4))\n    plt.plot(x, temp, 'b.')\n    plt.title('Optical Flow Magnitude')\n    plt.savefig(os.path.join(fig_dir, os.path.basename(video_path).split('.')[0] + '.jpg'))\n\n    # return optical_flow, flow_magnitude_list\n    return flow_magnitude_per_bar, flow_magnitude_list\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--method\", choices=[\"farneback\", \"lucaskanade_dense\", \"rlof\"], default=\"farneback\")\n    parser.add_argument(\"--video\", default=\"../../videos/final_640.mp4\")\n    args = parser.parse_args()\n\n    flow = []\n\n    video_path = args.video\n    print(\"video_path\", video_path)\n    if args.method == 'lucaskanade_dense':\n        method = cv2.optflow.calcOpticalFlowSparseToDense\n        optical_flow, flow_magnitude_list = dense_optical_flow(method, video_path, to_gray=True)\n    elif args.method == 'farneback':\n        method = cv2.calcOpticalFlowFarneback\n        params = [0.5, 3, 15, 3, 5, 1.2, 0]  # default Farneback's algorithm parameters\n        optical_flow, flow_magnitude_list = dense_optical_flow(method, video_path, params, to_gray=True)\n    elif args.method == \"rlof\":\n        method = cv2.optflow.calcOpticalFlowDenseRLOF\n        optical_flow, flow_magnitude_list = dense_optical_flow(method, video_path)\n\n    flow += optical_flow\n\n    flow = np.asarray(flow)\n    for percentile in range(10, 101, 10):\n        print('percentile %d: %.4f' % (percentile, np.percentile(flow, percentile)))\n    np.savez('optical_flow/flow.npz', flow=flow)"
  },
  {
    "path": "src/video2npz/resize_video.py",
    "content": "import os\n\n\ndef resize_video(video_name, in_dir='video', out_dir='video_360p', max_height=360):\n    command = 'ffmpeg -i %s -strict -2 -vf scale=-1:%d %s -v quiet' % (\n        os.path.join(in_dir, video_name),\n        max_height,\n        os.path.join(out_dir, video_name)\n    )\n    print(command)\n    os.system(command)\n    return os.path.join(out_dir, video_name)"
  },
  {
    "path": "src/video2npz/resize_videos.sh",
    "content": "mkdir video_360p\nfiles=$(ls video)\nfor filename in $files\ndo\n    echo $filename\n    ffmpeg -i video/$filename -strict -2 -vf scale=-1:360 video_360p/$filename -v quiet\ndone\n"
  },
  {
    "path": "src/video2npz/stat_mix.py",
    "content": "def _cal_density(flow_magnitude):\n    for i, percentile in enumerate(fmpb_percentile):\n        if flow_magnitude < percentile:\n            return i\n    return len(fmpb_percentile)\n\n\ndef _cal_strength(weight):\n    for i, percentile in enumerate(vbeat_weight_percentile):\n        if weight < percentile:\n            return i\n    return len(vbeat_weight_percentile)\n\n\n# calculated based on a set of videos\n\nvbeat_weight_percentile = [0, 0.22890276357193542, 0.4838207191278801, 0.7870981363596372, 0.891160136856027,\n                           0.9645568135300789, 0.991241869205911, 0.9978208223154553, 0.9996656159745393,\n                           0.9998905521344276]\nfmpb_percentile = [0.008169269189238548, 0.020344337448477745, 0.02979462407529354, 0.041041795164346695,\n                   0.07087484002113342, 0.10512548685073853, 0.14267262816429138, 0.19095642864704132,\n                   0.5155120491981506, 0.7514784336090088, 0.9989343285560608, 1.2067525386810303, 1.6322582960128784,\n                   2.031705141067505, 2.467430591583252, 2.8104422092437744]"
  },
  {
    "path": "src/video2npz/video2metadata.py",
    "content": "#/usr/bin/env python\n# -*- coding: UTF-8 -*-\nimport matplotlib\n\nmatplotlib.use('Agg')\nimport visbeat3 as vb\nimport os\nimport os.path as osp\nimport cv2\nimport json\nimport argparse\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.pyplot import MultipleLocator\n\n\ndef makedirs(d):\n    if not osp.exists(d):\n        os.makedirs(d)\n\n\ndef frange(start, stop, step=1.0):\n    while start < stop:\n        yield start\n        start += step\n\n\ndef process_all_videos(args):\n    out_json = {}\n    for i, video_name in enumerate(os.listdir(args.video_dir)):\n        if '.mp4' not in video_name:\n            continue\n        print('%d/%d: %s' % (i, len(os.listdir(args.video_dir)), video_name))\n        metadata = process_video(video_name, args)\n        out_json[video_name] = metadata\n\n    json_str = json.dumps(out_json, indent=4)\n    with open(osp.join(args.video_dir, 'metadata.json'), 'w') as f:\n        f.write(json_str)\n\n\ndef process_video(video_path, args):\n    figsize = (32, 4)\n    dpi = 200\n    xrange = (0, 95)\n    x_major_locator = MultipleLocator(2)\n\n    vb.Video.getVisualTempo = vb.Video_CV.getVisualTempo\n\n    video = os.path.basename(video_path)\n    vlog = vb.PullVideo(name=video, source_location=osp.join(video_path), max_height=360)\n    vbeats = vlog.getVisualBeatSequences(search_window=None)[0]\n\n    tempo, beats = vlog.getVisualTempo()\n    print(\"Tempo is\", tempo)\n    vbeats_list = []\n    for vbeat in vbeats:\n        i_beat = round(vbeat.start / 60 * tempo * 4)\n        vbeat_dict = {\n            'start_time': vbeat.start,\n            'bar'       : int(i_beat // 16),\n            'tick'      : int(i_beat % 16),\n            'weight'    : vbeat.weight\n        }\n        if vbeat_dict['tick'] % args.resolution == 0:  # only select vbeat that lands on the xth tick\n            vbeats_list.append(vbeat_dict)\n    print('%d / %d vbeats selected' % (len(vbeats_list), len(vbeats)))\n\n    npz = np.load(\"flow/\" + video.replace('.mp4', '.npz'), allow_pickle=True)\n    print(npz.keys())\n    flow_magnitude_list = npz['flow']\n    fps = round(vlog.n_frames() / float(vlog.getDuration()))\n    fpb = int(round(fps * 4 * 60 / tempo))  # frame per bar\n\n    fmpb = []  # flow magnitude per bar\n    temp = np.zeros((len(flow_magnitude_list)))\n    for i in range(0, len(flow_magnitude_list), fpb):\n        mean_flow = np.mean(flow_magnitude_list[i: min(i + fpb, len(flow_magnitude_list))])\n        fmpb.append(float(mean_flow))\n        temp[i: min(i + fpb, len(flow_magnitude_list))] = mean_flow\n\n    if args.visualize:\n        makedirs('image')\n\n        height = vlog.getFrame(0).shape[0]\n        thumbnails = [vlog.getFrameFromTime(t)[:, :int(height * 2.5 / 10), :] for t in list(frange(25, 35, 1))]\n        thumbnails = np.concatenate(thumbnails, axis=1)\n        cv2.cvtColor(thumbnails, cv2.COLOR_RGB2BGR)\n        cv2.imwrite(osp.join('image', video + '_thumbnails_1' + '.png'), thumbnails)\n\n        plt.rcParams.update({'font.size': 14})\n        plt.figure(figsize=figsize, dpi=dpi)\n        plt.subplots_adjust(bottom=0.15)\n\n        x2_time = [float(item) / fps for item in list(range(len(flow_magnitude_list)))]\n        plt.plot(x2_time[::3], flow_magnitude_list[::3], '-', color='#fff056', alpha=0.75, label=\"Per Frame\")\n        for i, fm in enumerate(fmpb):\n            x_frame = [i * fpb, (i + 1) * fpb - 1]\n            x_time = [x / fps for x in x_frame]\n            y_fm = [fm, fm]\n            if i == 0:\n                plt.plot(x_time, y_fm, 'r-', label='Per Bar', lw=3)\n            else:\n                plt.plot(x_time, y_fm, 'r-', lw=3)\n        if xrange is not None:\n            plt.xlim(xrange)\n        ax = plt.gca()\n        ax.xaxis.set_major_locator(x_major_locator)\n        plt.xlabel('Time (s)')\n        plt.ylabel('Optical Flow Magnitude')\n        plt.legend(loc=\"upper left\")\n        plt.savefig(osp.join('image', video + '_flow' + '.eps'), format='eps', transparent=True)\n        plt.savefig(osp.join('image', video + '_flow' + '.png'), format='png', transparent=True)\n\n        vlog.printVisualBeatSequences(figsize=figsize, save_path=osp.join('image', video + '_visbeat' + '.eps'),\n                                      xrange=xrange, x_major_locator=x_major_locator)\n\n    return {\n        'duration'              : vlog.getDuration(),\n        'tempo'                 : tempo,\n        'vbeats'                : vbeats_list,\n        'flow_magnitude_per_bar': fmpb,\n    }\n\n\nif __name__ == '__main__':\n    # vb.SetAssetsDir('.' + os.sep + 'VisBeatAssets' + os.sep)\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--video', type=str, default='../../videos/final_640.mp4')\n    parser.add_argument('--visualize', action='store_true', default=True)\n    parser.add_argument('--resolution', type=int, default=1)\n    args = parser.parse_args()\n\n    metadata = process_video(args.video, args)\n    with open(\"metadata.json\", \"w\") as f:\n        json.dump(metadata, f)\n    print(\"saved to metadata.json\")"
  },
  {
    "path": "src/video2npz/video2npz.sh",
    "content": "# extract flow magnitude into optical_flow/flow.npz\npython optical_flow.py --video $1\n\n# convert video into metadata.json with flow magnitude\npython video2metadata.py --video $1\n\n# convert metadata into .npz under `inference/`\npython metadata2numpy_mix.py --video $1\n"
  },
  {
    "path": "src/video2npz/visbeat3/LICENSE",
    "content": "SOFTWARE LICENSE AGREEMENT For Stanford Docket S18-164, \"Visual Rhythm and Beat:\nAutomatic Synchronization of visual beats to motion or dance\"\n\n1.\tBy downloading the software in this directory, you (\"RECIPIENT\") are\nexplicitly agreeing to this license agreement with THE BOARD OF TRUSTEES OF THE\nLELAND STANFORD JUNIOR UNIVERSITY (\"STANFORD\").  Stanford has an assignment to\n\"Visual Rhythm and Beat: Automatic Synchronization of visual beats to motion or\ndance\" (\"Software\") which was developed in the laboratory of Professor Maneesh\nAgrawala.\n\n2.\tBy accepting, receiving, and using Software, including any accompanying\ninformation, materials or manuals, you are agreeing to be bound by the terms of\nthis Agreement.  If you do not agree to the terms of this Agreement, do not\ndownload the Software from this directory, and destroy any copies you may have\nalready downloaded.\n\n3.\tSTANFORD grants a royalty-free, nonexclusive, and nontransferable license to\nuse the Software furnished hereunder, upon the terms and conditions set out\nbelow.\n\n4.\tRECIPIENT acknowledges that the Software is a research tool still in the\ndevelopment stage and that it is being supplied as is, without any accompanying\nservices, support or improvements from STANFORD.  STANFORD makes no\nrepresentations and extends no warranties of any kind, either express or implied\nother than set out in this agreement.\n\n5.\tRECIPIENT agrees to use the Software solely for internal, non-commercial\npurposes and shall not distribute or transfer it to another location or to any\nother person without prior written permission from STANFORD.\n\n6.\tRECIPIENT acknowledges that any programs created based on the Software will\nbe considered a derivative of Software and cannot be used commercially without a\ncommercial license from Stanford.\n\n7.\tRECIPIENT may make modifications to the Software and integrate Software into\nRECIPIENT's own software.\n\n8.\tRECIPIENT may not further distribute Software without express written\npermission of STANFORD. If permission to transfer the Software is given,\nRECIPIENT warrants that RECIPIENT will not remove or export any part of the\nSoftware from the United States except in full compliance with all United States\nexport regulations and other applicable laws.\n\n9.\tRECIPIENT will use the Software in compliance with all applicable laws,\npolicies and regulations including, but not limited to, any approvals, informed\nconsent and patient confidentiality principles.\n\n10.\tRECIPIENT will indemnify, hold harmless, and defend STANFORD against any\nclaim of any kind arising out of or related to the exercise of any rights\ngranted under this Agreement or the breach of this Agreement by RECIPIENT.\n\n11.\tTitle and copyright to the Software and any derivatives and any associated\ndocumentation shall at all times remain with STANFORD, and RECIPIENT agrees to\npreserve same.\n\n12.\tIf RECIPIENT plans to publish any peer reviewed papers, abstracts, or\nsimilar publications, RECIPIENT agrees to acknowledge Software and its creators\nin a manner consistent with academic (industry) practice.\n\n13.\tRECIPIENT agrees to maintain the visbeat logo that appears on all outputs\nfrom the software.\n\n14.\tIf RECIPIENT wishes to terminate this license, RECIPIENT shall destroy all\ncopies of Software.\n"
  },
  {
    "path": "src/video2npz/visbeat3/MANIFEST.in",
    "content": "# Include the README\ninclude *.md\n\n# Include the license file\ninclude LICENSE\ninclude LICENSE.pdf\n\n# Include the data files\nrecursive-include visbeat3/assets *\ngraft visbeat3/assets\nglobal-include *\n"
  },
  {
    "path": "src/video2npz/visbeat3/README.md",
    "content": "# visbeat3\n\nThis is a migration of [visbeat](http://abedavis.com/visualbeat/) from Python2 to Python3. All credits belong to the original author.\n\nNote: This repo is under development, for any issue, please PR directly!\n\n## Install\n\n```\npip3 install visbeat3\n```\n\nor\n\n```\npip3 install -e git+https://github.com/haofanwang/visbeat3.git#egg=visbeat3\n```\n\n## Usage\n\n```\nimport visbeat3 as vb\n```\n\n## Reference\n```\n@inproceedings{davis2018visual,\n  title={Visual rhythm and beat},\n  author={Davis, Abe and Agrawala, Maneesh},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition Workshops},\n  pages={2532--2535},\n  year={2018}\n}\n```\n"
  },
  {
    "path": "src/video2npz/visbeat3/VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Backups/VideoSource.json",
    "content": "{\n    \"a_info\": {\n        \"AObjectType\": \"VideoSource\",\n        \"base_path\": null,\n        \"directory_path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238\",\n        \"file_base_name\": \"VideoSource\",\n        \"file_ext\": \".json\",\n        \"file_name\": \"VideoSource.json\",\n        \"file_path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/VideoSource.json\",\n        \"source_type\": \"file\"\n    },\n    \"directories\": {\n        \"backup\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Backups/\",\n        \"data\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/\",\n        \"features\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Features/\",\n        \"temp\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/TEMP/\",\n        \"versions\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/\",\n        \"warps\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Warps/\"\n    },\n    \"source_location\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions//Source/Full/wzk_vlog_beat_enhance1_track1238.mp4\",\n    \"versions_info\": {\n        \"Original\": {\n            \"360\": {\n                \"duration\": 38.07140473807141,\n                \"end_time\": 38.07140473807141,\n                \"meta_data\": {\n                    \"audio_codec\": \"aac\",\n                    \"codec\": \"h264\",\n                    \"duration\": 38.11,\n                    \"ffmpeg_version\": \"4.2.2 built with Apple clang version 11.0.0 (clang-1100.0.33.8)\",\n                    \"fps\": 29.97,\n                    \"nframes\": Infinity,\n                    \"pix_fmt\": \"yuv420p\",\n                    \"plugin\": \"ffmpeg\",\n                    \"rotate\": 0,\n                    \"size\": [\n                        204,\n                        360\n                    ],\n                    \"source_size\": [\n                        204,\n                        360\n                    ]\n                },\n                \"name\": \"wzk_vlog_beat_enhance1_track1238_360\",\n                \"num_frames_total\": 1141,\n                \"path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Original/maxheight_360/wzk_vlog_beat_enhance1_track1238.mp4\",\n                \"sampling_rate\": 29.97,\n                \"start_time\": 0\n            },\n            \"Full\": {\n                \"duration\": 34.83483483483484,\n                \"end_time\": 34.83483483483484,\n                \"meta_data\": {\n                    \"audio_codec\": \"aac\",\n                    \"codec\": \"h264\",\n                    \"duration\": 38.08,\n                    \"ffmpeg_version\": \"4.2.2 built with Apple clang version 11.0.0 (clang-1100.0.33.8)\",\n                    \"fps\": 29.97,\n                    \"nframes\": Infinity,\n                    \"pix_fmt\": \"yuv420p(tv\",\n                    \"plugin\": \"ffmpeg\",\n                    \"rotate\": 0,\n                    \"size\": [\n                        544,\n                        960\n                    ],\n                    \"source_size\": [\n                        544,\n                        960\n                    ]\n                },\n                \"name\": \"wzk_vlog_beat_enhance1_track1238_Full\",\n                \"num_frames_total\": 1044,\n                \"path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Source/Full/wzk_vlog_beat_enhance1_track1238.mp4\",\n                \"sampling_rate\": 29.97,\n                \"start_time\": 0\n            }\n        }\n    },\n    \"video_file_name\": \"wzk_vlog_beat_enhance1_track1238.mp4\"\n}"
  },
  {
    "path": "src/video2npz/visbeat3/VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/VideoSource.json",
    "content": "{\n    \"a_info\": {\n        \"AObjectType\": \"VideoSource\",\n        \"base_path\": null,\n        \"directory_path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238\",\n        \"file_base_name\": \"VideoSource\",\n        \"file_ext\": \".json\",\n        \"file_name\": \"VideoSource.json\",\n        \"file_path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/VideoSource.json\",\n        \"source_type\": \"file\"\n    },\n    \"directories\": {\n        \"backup\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Backups/\",\n        \"data\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/\",\n        \"features\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Features/\",\n        \"temp\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/TEMP/\",\n        \"versions\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/\",\n        \"warps\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Warps/\"\n    },\n    \"source_location\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions//Source/Full/wzk_vlog_beat_enhance1_track1238.mp4\",\n    \"versions_info\": {\n        \"Original\": {\n            \"360\": {\n                \"duration\": 38.07140473807141,\n                \"end_time\": 38.07140473807141,\n                \"meta_data\": {\n                    \"audio_codec\": \"aac\",\n                    \"codec\": \"h264\",\n                    \"duration\": 38.11,\n                    \"ffmpeg_version\": \"4.2.2 built with Apple clang version 11.0.0 (clang-1100.0.33.8)\",\n                    \"fps\": 29.97,\n                    \"nframes\": Infinity,\n                    \"pix_fmt\": \"yuv420p\",\n                    \"plugin\": \"ffmpeg\",\n                    \"rotate\": 0,\n                    \"size\": [\n                        204,\n                        360\n                    ],\n                    \"source_size\": [\n                        204,\n                        360\n                    ]\n                },\n                \"name\": \"wzk_vlog_beat_enhance1_track1238_360\",\n                \"num_frames_total\": 1141,\n                \"path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Original/maxheight_360/wzk_vlog_beat_enhance1_track1238.mp4\",\n                \"sampling_rate\": 29.97,\n                \"start_time\": 0\n            },\n            \"Full\": {\n                \"duration\": 34.83483483483484,\n                \"end_time\": 34.83483483483484,\n                \"meta_data\": {\n                    \"audio_codec\": \"aac\",\n                    \"codec\": \"h264\",\n                    \"duration\": 38.08,\n                    \"ffmpeg_version\": \"4.2.2 built with Apple clang version 11.0.0 (clang-1100.0.33.8)\",\n                    \"fps\": 29.97,\n                    \"nframes\": Infinity,\n                    \"pix_fmt\": \"yuv420p(tv\",\n                    \"plugin\": \"ffmpeg\",\n                    \"rotate\": 0,\n                    \"size\": [\n                        544,\n                        960\n                    ],\n                    \"source_size\": [\n                        544,\n                        960\n                    ]\n                },\n                \"name\": \"wzk_vlog_beat_enhance1_track1238_Full\",\n                \"num_frames_total\": 1044,\n                \"path\": \"./VisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Source/Full/wzk_vlog_beat_enhance1_track1238.mp4\",\n                \"sampling_rate\": 29.97,\n                \"start_time\": 0\n            }\n        }\n    },\n    \"video_file_name\": \"wzk_vlog_beat_enhance1_track1238.mp4\"\n}"
  },
  {
    "path": "src/video2npz/visbeat3/bin/dancefer",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport matplotlib\nmatplotlib.use('PS')\nimport visbeat3\n\nsource_url = 'https://www.youtube.com/watch?v={}'.format(sys.argv[0]);\ntarget_url = 'https://www.youtube.com/watch?v={}'.format(sys.argv[1]);\n\noutput_path = sys.argv[2];\n\nresult = visbeat3.AutoDancefer(source=source_url, target = target_url,\n                              output_path = output_path,\n                              synch_video_beat = 0,\n                              synch_audio_beat = 0,\n                              beat_offset = 64,\n                              nbeats = 128);\nresult.play();\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/ADefines.py",
    "content": "# AD_DEBUG = 1;\n\nAD_DEBUG = 0;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AFileManager.py",
    "content": "from .AObject import *\n#import shutil\nfrom distutils.dir_util import copy_tree\n\nclass AFileManager(AObject):\n    \"\"\"AFileManager (class): Manages assets. This should really be replaced with a database of some sort...\n        Attributes:\n            todo\n    \"\"\"\n\n    @staticmethod\n    def AOBJECT_TYPE():\n        return 'AFileManager';\n\n    def getJSONPath(self):\n        return self.getPath();\n\n    def __init__(self, path=None, clear_temp=None):\n        \"\"\"If you provide a directory, it will look for a existing AFileManager.json in that directory, or create one if it does not already exist.\n            If you provide a json, it will use that json, unless the json doesn't exist, in which case it will complain...\n        \"\"\"\n        AObject.__init__(self, path=path);\n        # self.initializeBlank();\n        self.initWithPath(path=path, clear_temp=clear_temp);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.directories = {};\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n    def initWithPath(self, path=None, clear_temp=None):\n        oldpath = None\n        newpath = path;\n        if(path):\n            if(os.path.isfile(path)):\n                self.loadFromJSON(self.getJSONPath()); #assume path property is already set to 'path'\n                oldpath = self.getPath(); #whatever was in the json, having overwritten path property\n            elif(os.path.isdir(path)):\n                json_file_path = path+os.sep+self.getJSONName();\n                self.setPath(json_file_path);\n                if(os.path.isfile(self.getJSONPath())):\n                    self.loadFromJSON(json_file_path);\n                    oldpath = self.getPath();\n                    newpath = json_file_path;\n                    # self.setPath(file_path=json_file_path);\n                else:\n                    newpath=self.getJSONPath()\n                    self.writeToJSON(json_path=newpath);#no json file found, so we create one\n            else:\n                assert False, \"Given AFileManager path is neither an existing directory or file! path: {} (AFileManager.py)\".format(path)\n\n            self.setPath(file_path=newpath);\n\n            if(oldpath):\n                oldir = get_dir_from_path(pathstring(oldpath));\n                newdir = get_dir_from_path(pathstring(newpath));\n                if(oldir != newdir):\n                    AWARN(\"FILEMANAGER FOUND FILE MOVED FROM:\\n{}\\nTO:\\n{}\\nUPDATING DIRECTORIES...\".format(oldir,\n                                                                                                            newdir));\n                    for d in self.directories:\n                        dpth = self.directories[d];\n                        if(dpth.startswith(oldir)):\n                            dpthst = dpth.lstrip(oldir);\n                            self.directories[d]=os.path.join(newdir,dpthst);\n                            AWARN(\"{} updated to {}\".format(dpth, self.directories[d]));\n\n\n            self.setDir('data', pathstring(self.getDirectoryPath()+os.sep+\"Data\"+os.sep));\n            self.setDir('backup', pathstring(self.getDir('data')+\"Backups\"+os.sep));\n            self.setDir('temp', pathstring(self.getDir('data')+\"TEMP\"+os.sep));\n            temp_dir = self.getDir('temp');\n            if(os.path.isdir(temp_dir) and (clear_temp)):\n                for the_file in os.listdir(temp_dir):\n                    file_path = os.path.join(temp_dir, the_file);\n                    try:\n                        if os.path.isfile(file_path):\n                            os.remove(file_path);\n                            #os.unlink(file_path);\n                            #elif os.path.isdir(file_path): shutil.rmtree(file_path)\n                    except Exception as e:\n                        print(e)\n            make_sure_path_exists(temp_dir);\n            #Video.VIDEO_TEMP_DIR = temp_dir;\n\n    def setDir(self, name, path):\n        # AWARN(\"setting {} to {}\".format(name, path))\n        # assert(name is not 'log')\n        self.directories[name]=path;\n        make_sure_path_exists(path);\n        return path;\n\n    def addDir(self, name):\n        assert(name not in self.directories), \"tried to add {} dir to AFileManager, but this dir is already set\"\n        return self.setDir(name, pathstring(self.getDirectoryPath()+os.sep+name+os.sep));\n\n    def getDir(self, name):\n        # printDictionary(self.directories)\n        return self.directories.get(name);\n\n\n    def emptyDir(self, name):\n        dpth = self.getDir(name);\n        if(dpth is not None and os.path.isdir(dpth)):\n            shutil.rmtree(dpth);\n            make_sure_path_exists(dpth);\n\n    def deleteDir(self, name):\n        dpth = self.getDir(name);\n        if (dpth is not None and os.path.isdir(dpth)):\n            shutil.rmtree(dpth);\n            d = dict(self.directories);\n            del d[name];\n            self.directories=d;\n\n\n    def toDictionary(self):\n        d = AObject.toDictionary(self);\n        d['directories']=self.directories;\n        #serialize class specific members\n        return d;\n\n    def copyPathToDir(self, path_to_copy, dest_dir):\n        dest_path = self.getDir(dest_dir);\n        if(dest_path):\n            if(os.path.isdir(path_to_copy)):\n                copy_tree(src=path_to_copy, dst=dest_path);\n            elif(os.path.isfile(path_to_copy)):\n                shutil.copy2(path_to_copy, dest_path)\n        return;\n\n    def copyDirToPath(self, dir_to_copy, dest_path):\n        src_path = self.getDir(dir_to_copy);\n        if(src_path):\n            if(os.path.isdir(dest_path)):\n                copy_tree(src=src_path, dst=dest_path);\n        return;\n\n    @staticmethod\n    def copyRandomFractionOfFilesInSourceDir(source_dir, dest_dir, fraction=1.0, ext=None):\n        \"\"\"\n        Copies a random fraction of files in source directory... Wrote this for splitting training/test data in ML applications.\n        :param source_dir:\n        :param dest_dir:\n        :param fraction:\n        :param ext:\n        :return:\n        \"\"\"\n        directories = []\n        subdirnames = []\n        filepaths = [];\n        for filename in os.listdir(source_dir):\n            path = os.path.join(source_dir, filename)\n            if os.path.isdir(path):\n                directories.append(path)\n                subdirnames.append(filename)\n            else:\n                # namepart, extpart = os.path.splitext(filename);\n                if((ext is None) or filename.lower().endswith(ext)):\n                    filepaths.append(path);\n\n        n_to_copy = int(len(filepaths)*fraction);\n        random_seed = 0;\n        random.seed(random_seed);\n        random.shuffle(filepaths);\n        copy_sources = filepaths[:n_to_copy];\n        for src, dst in zip(copy_sources, [dest_dir]*len(copy_sources)):\n            #print(\"src: {}\\ndst: {}\".format(src, dst));\n            shutil.copy2(src, dst);\n\n        for d in range(len(directories)):\n            subdest = pathstring(os.path.join(dest_dir,subdirnames[d])+os.sep);\n            make_sure_dir_exists(subdest);\n            AFileManager.copyRandomFractionOfFilesInSourceDir(source_dir=directories[d], dest_dir=subdest, fraction=fraction, ext=ext);\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        self.directories = d['directories'];\n\n    def save(self):\n        if(os.path.isfile(self.getJSONPath())):\n            os.rename(self.getJSONPath(), self.getDir('backup')+os.sep+self.AOBJECT_TYPE()+\".json\");\n        self.writeToJSON(self.getJSONPath());\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AFuncDict.py",
    "content": "from .AParamDict import *\nimport pickle as pickle\nimport os\nclass AFuncDict(AParamDict):\n    \"\"\"AFuncDict (class): Extends AParamDict so that functions can be assigned to features and called whenever\n        computing those features is necessary.\n        Attributes:\n            data: name -> value, params\n            feature funcs: name -> function for evaluating\n    \"\"\"\n\n    def __init__(self, owner=None, name=None, path=None):\n        AParamDict.__init__(self, owner=owner, name=name, path=path);\n        self.functions = {};\n\n    def getEntry(self, name=None, params=None, force_recompute=False):\n        d = self.data.get(name);\n        if((d is not None) and (not force_recompute)):\n            return d;\n        else:\n            f = self.getFunction(name=name);\n            if(f is not None):\n                if(params is not None):\n                    if(not params.get('force_recompute')):\n                        params.update(dict(force_recompute=force_recompute));\n                    self.setValue(name=name, value=f(self=self.owner, **params), params=params, modified=True);\n                else:\n                    self.setValue(name=name, value=f(self=self.owner, force_recompute=force_recompute), params=params, modified=True);\n            return self.data.get(name);\n        return None;\n\n    def getValue(self, name=None, params=None, force_recompute=False):\n        d = self.getEntry(name=name, params=params, force_recompute=force_recompute);\n        if(d is not None):\n            return d.get('value');\n        else:\n            return None;\n\n    def getParams(self, name=None):\n        d = self.data.get(name);\n        if(d is not None):\n            return d.get('params');\n        else:\n            return None;\n\n    def getFunction(self, name=None):\n        return self.functions.get(name);\n\n    def setValue(self, name, value=None, params=None, modified=True):\n        self.data[name]['value']=value;\n        self.data[name]['params']=params;\n        self.setEntryModified(name=name, is_modified=modified)\n        #self.data[name]['modified']=modified;\n\n    def setFunction(self, name, function=None):\n        self.functions[name]=function;\n\n    def saveEntry(self, name, path, force=False):\n        \"\"\"Save one entry to one file.\"\"\"\n        if(self.data.get(name) is None):\n            return None;\n        if(self.isEntryModified(name=name) or force or (not os.path.isfile(path))):\n            #pickleToPath\n            f = open(path, 'wb');\n            pickle.dump(self.getEntry(name=name), f, protocol=2);\n            f.close();\n            self.setEntryModified(name=name, is_modified=False);\n            #assert(False), \"should not be saving in this test\";\n        return True;\n\n    def setEntryModified(self, name, is_modified=True):\n        self.data[name]['modified']=is_modified;\n        if(is_modified):\n            self.setModified(is_modified=True);\n\n    def isEntryModified(self, name):\n        entry = self.data.get(name);\n        if(entry is not None):\n            m=entry.get('modified');\n            if(m is not None):\n                return m;\n            else:\n                return True;\n        else:\n            assert(False), \"checking mod bit on entry that does not exist\"\n\n    def isModified(self):\n        return self.modified;\n\n    def setModified(self, is_modified):\n        self.modified=is_modified;\n\n    def save(self, path, force=False):\n        \"\"\"save all entries to one file.\"\"\"\n        if(force or self.isModified()):\n            f = open(path, 'wb');\n            pickle.dump(self.data, f, protocol=2);\n            f.close();\n            self.setModified(is_modified=False);\n            #assert(False), \"should not be saving in this test\";\n        return True;\n\n    def loadEntry(self, name, path):\n        \"\"\"load one entry from one file.\"\"\"\n        f=open(path, 'rb');\n        self.setEntry(name=name, d=pickle.load(f));\n        f.close();\n        self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def load(self, path):\n        \"\"\"Load a set of entries all from one file.\"\"\"\n        f=open(path, 'rb');\n        newd = pickle.load(f);\n        self.data.update(newd);\n        f.close();\n        return True;\n\n    def getKeyList(self):\n        return list(self.data.keys());\n\n    def getFunctionList(self):\n        return list(self.functions.keys());\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AImports.py",
    "content": "#AImports\nfrom . import ADefines as defines\nimport os\nimport os.path\nimport errno\nimport json\nimport pickle as pickle\nimport glob\nimport subprocess\nfrom operator import truediv\nimport shutil\nimport time\nfrom time import gmtime, strftime, localtime\nimport random\nfrom . import fileui\n\n\n\ntry:\n    from termcolor import colored\n    def AWARN(message):\n        if (defines.AD_DEBUG):\n            print((colored(message, 'red')))\n    def AINFORM(message):\n        if(defines.AD_DEBUG):\n            print((colored(message, 'blue')))\nexcept ImportError:\n    if (defines.AD_DEBUG):\n        print(\"You do not have termcolor installed (pip install termcolor). AWARN will just show as plain print statements when defines.AD_DEBUG==True...\")\n    def AWARN(message):\n        if (defines.AD_DEBUG):\n            print(message);\n    def AINFORM(message):\n        if (defines.AD_DEBUG):\n            print(message);\n\ndef local_time_string():\n    return strftime(\"%Y-%m-%d_%H:%M:%S\", localtime());\n\ndef get_temp_file_path(final_file_path=\"TEMP\", temp_dir_path = None):\n    pparts = os.path.split(final_file_path);\n    destfolder = pparts[0]+os.sep;\n    tempdir = temp_dir_path;\n    if(tempdir is None):\n        tempdir='.';\n    destfolder=pathstring(tempdir+os.sep);\n    tempname = 'TEMP_'+pparts[1];\n    temptry = 0;\n    while(os.path.isfile(destfolder+tempname)):\n        temptry=temptry+1;\n        tempname = 'TEMP{}_'.format(temptry)+pparts[1];\n    return pathstring(destfolder+tempname);\n\n\ndef runningInNotebook():\n    try:\n        shell = get_ipython().__class__.__name__\n        if shell == 'ZMQInteractiveShell':\n            return True   # Jupyter notebook or qtconsole\n        elif shell == 'TerminalInteractiveShell':\n            return False  # Terminal running IPython\n        else:\n            return False  # Other type (?)\n    except NameError:\n        return False      # Probably standard Python interpreter\n\ndef getshellname():\n    try:\n        shell = get_ipython().__class__.__name__\n        return shell;\n    except NameError:\n        return False      # Probably standard Python interpreter\n\n\ndef runningInSpyder():\n    return 'SpyderKernel' in str(get_ipython().kernel.__class__);\n\ndef pickleToPath(d, path):\n    # assert(False)\n    print(\"pickling\")\n    f = open(path, 'wb');\n    pickle.dump(d, f, protocol=2);\n    f.close();\n    return True;\n\ndef unpickleFromPath(path):\n    f=open(path, 'rb');\n    d=pickle.load(f);\n    f.close();\n    return d;\n\ndef make_sure_path_exists(path):\n    try:\n        os.makedirs(path)\n    except OSError as exception:\n        if exception.errno != errno.EEXIST:\n            raise\n\ndef make_sure_dir_exists(path):\n    pparts = os.path.split(path);\n    destfolder = pparts[0]+os.sep;\n    try:\n        os.makedirs(destfolder)\n    except OSError as exception:\n        if exception.errno != errno.EEXIST:\n            raise\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\ndef pathstring(path):\n    return path.replace(os.sep+os.sep, os.sep);\n\ndef is_interactive():\n    import __main__ as main\n    return not hasattr(main, '__file__')\n\ndef printOb(obj):\n    for attr in dir(obj):\n        print(\"#### Obj.%s = %s\\n\" % (attr, getattr(obj, attr)))\n\ndef pathstring(path):\n    return path.replace(os.sep+os.sep, os.sep);\n\ndef get_prepended_name_file_path(original_file_path, string_to_prepend):\n    pparts = os.path.split(original_file_path);\n    destfolder = pparts[0]+os.sep;\n    pname = string_to_prepend+pparts[1];\n    return pathstring(destfolder+pname);\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\ndef change_extension(input_path, new_ext):\n    nameparts = os.path.splitext(input_path);\n    return nameparts[0]+new_ext;\n\ndef printDictionary(obj):\n    if type(obj) == dict:\n        for k, v in list(obj.items()):\n            if hasattr(v, '__iter__'):\n                print(k)\n                printDictionary(v)\n            else:\n                print('%s : %s' % (k, v))\n    elif type(obj) == list:\n        for v in obj:\n            if hasattr(v, '__iter__'):\n                printDictionary(v)\n            else:\n                print(v)\n    else:\n        print(obj)\n\ndef spotgt_shift_bit_length(x):\n    #smallest power of two greater than\n    return 1<<(x-1).bit_length()\n\ndef get_file_name_from_path(pth):\n    return os.path.split(pth)[1];\n\ndef get_dir_from_path(pth):\n    return (os.path.split(pth)[0]+os.sep);\n\ndef get_file_names_from_paths(pths):\n    r = [];\n    for p in pths:\n        r.append(get_file_name_from_path(p));\n    return r;\n\ndef writeDictionaryToJSON(d, json_path=None):\n    if(json_path):\n        with open(json_path, 'w') as outfile:\n            json.dump(d, outfile, sort_keys = True, indent = 4, ensure_ascii=False);\n\n\ndef vtt_to_srt(fileContents):\n    replacement = re.sub(r'([\\d]+)\\.([\\d]+)', r'\\1,\\2', fileContents)\n    replacement = re.sub(r'WEBVTT\\n\\n', '', replacement)\n    replacement = re.sub(r'^\\d+\\n', '', replacement)\n    replacement = re.sub(r'\\n\\d+\\n', '\\n', replacement)\n    return replacement\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AObject.py",
    "content": "#AO#labels#AObject\nimport os\nimport json\n\nfrom .AParamDict import *\nfrom . import fileui\n\nclass AObject(object):\n    \"\"\"AObject (class): This is a paarent class used to implement any comon serialization or typing we might want to do later\n        Attributes:\n            labels: dictionary of meta_data\n            save, load, and clear funcs: these are hooks for functions that manage the object's data on disk.\n    \"\"\"\n\n    AOBJECT_BASE_PATH=None;\n\n    def __init__(self, path=None, **kwargs):\n        self.initializeBlank();\n        if(path):\n            self.setPath(file_path=path, **kwargs);\n\n\n    def initializeBlank(self):\n        self.a_info = {'AObjectType': self.AOBJECT_TYPE()};\n        # self.a_data = AParamDict(owner=self, name='a_data');\n        self.save_func = None;\n        self.load_func = None;\n        self.clear_func = None;\n\n    def setPath(self, file_path=None, **kwargs):\n        if(file_path):\n            self.a_info['file_path'] = pathstring(file_path);\n            pparts = os.path.split(self.a_info['file_path']);\n            self.a_info['file_name'] = pparts[1];\n            self.a_info['directory_path']=pparts[0];\n            filename = self.a_info.get('file_name');\n            if(filename):\n                nameparts = os.path.splitext(filename);\n                self.a_info['file_base_name'] = nameparts[0];\n                self.a_info['file_ext'] = nameparts[1];\n            self.a_info['base_path'] = kwargs.get('base_path');\n            if(self.a_info['base_path'] is None):\n                self.a_info['base_path'] = AObject.AOBJECT_BASE_PATH;\n\n    def getPath(self):\n        if('file_path' in self.a_info):\n            return self.a_info['file_path'];\n        else:\n            return None;\n\n    def _showFile(self):\n        if(fileui.Show is not None):\n            fileui.Show(self.getPath());\n\n    def _open(self):\n        if(fileui.Open is not None):\n            fileui.Open(self.getPath());\n\n    def getRelativePath(self, base_path=None):\n        base = base_path;\n        if(base is None):\n            base = self.a_info.get('base_path');\n        if(base is None):\n            AWARN(\"Base path not set!\");\n        return str(self.getPath());\n\n    def getFileName(self):\n        if('file_name' in self.a_info):\n            return self.a_info['file_name'];\n        else:\n            return None;\n\n    def getFileExtension(self):\n        if('file_ext' in self.a_info):\n            return self.a_info['file_ext'];\n        else:\n            return None;\n\n    def getDirectoryPath(self):\n        return self.a_info.get('directory_path')\n\n    def setInfo(self, label, value):\n        self.a_info[label]=value;\n\n    def getInfo(self, label):\n        return self.a_info.get(label);\n\n    def loadFromJSON(self, json_path=None):\n        if(json_path):\n            self.setPath(file_path=json_path);\n        if('file_path' in self.a_info):\n            json_text=open(self.a_info['file_path']).read();\n            d = json.loads(json_text);\n            self.initFromDictionary(d);\n\n    def writeToJSON(self, json_path=None):\n        #with open(jsonpath+self.name+'.json', 'w') as outfile:\n        if(not json_path):\n            json_path = self.a_info.get('file_path');\n        if(json_path):\n            with open(json_path, 'w') as outfile:\n                json.dump(self.toDictionary(), outfile, sort_keys = True, indent = 4, ensure_ascii=False);\n\n    def serializeInfo(self):\n        return self.a_info;\n\n    def save(self, features_to_save='all', overwrite=True, **kwargs):\n        if(self.save_func):\n            self.save_func(self, features_to_save=features_to_save, overwrite=overwrite, **kwargs);\n        else:\n            AWARN(\"SAVE FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.AOBJECT_TYPE()));\n\n    def load(self, features_to_load=None, **kwargs):\n        if(self.load_func):\n            self.load_func(self, features_to_load=features_to_load, **kwargs);\n        else:\n            AWARN(\"LOAD FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.AOBJECT_TYPE()));\n\n    ########### \"VIRTUAL\" FUNCTIONS #############\n    @staticmethod\n    def AOBJECT_TYPE():\n        return 'AObject';\n\n    def toDictionary(self):\n        d = {'a_info': self.serializeInfo()};\n        return d;\n\n    def initFromDictionary(self, d):\n        self.a_info = d.get('a_info');\n\n    # ##Example of how these functions should be written in a  subclass, here we call the subclass 'AssetManager'\n    # def AOBJECT_TYPE(self):\n    #     return 'AssetManager';\n    #\n    # def toDictionary(self):\n    #     d = AObject.toDictionary(self);\n    #     #serialize class specific members\n    #     return d;\n    #\n    # def initFromDictionary(self, d):\n    #     AObject.initFromDictionary(self, d);\n    #     #do class specific inits with d;\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AParamDict.py",
    "content": "from .AImports import *\nclass AParamDict(object):\n    \"\"\"AParamDict (class): Dictionary that stores values and the parameters used to compute those values. I use this\n        class for two things. The first is to store parameters for reproducability. The second is to only recompute\n        values when functions are called with different parameters (some of this latter functionality is tied up in\n        code that isn't part of the Lite release).\n\n        Attributes:\n            data: name -> value, params\n    \"\"\"\n\n    def __init__(self, owner=None, name=None, path=None):\n        self.name=name;\n        self.data = {};\n        self.owner=owner;\n        self.modified=False;\n\n    def getEntry(self, name=None, params=None, force_recompute=False):\n        d = self.data.get(name);\n        if((d is not None) and (not force_recompute)):\n            return d;\n        return None;\n\n    def setEntry(self, name, d):\n        assert(name!='all' and name!='each'),\"Entry named '{}' is reserved in AParamDict\".format(name);\n        self.data[name]=d;\n\n    def removeEntry(self, name, assert_if_absent=True, set_modified = True):\n        if(assert_if_absent):\n            assert(name in self.data),\"Tried to remove entry {} that was not already in {}\".format(name, self.__class__);\n        popentry = self.data.pop(name, None);\n        if(set_modified):\n            self.setModified(set_modified);\n        return popentry;\n\n\n    def hasEntry(self, name=None):\n        return (self.data.get(name) is not None);\n\n    def getValue(self, name=None, params=None, force_recompute=False):\n        d = self.getEntry(name=name, params=params, force_recompute=force_recompute);\n        if(d is not None):\n            return d.get('value');\n        else:\n            return None;\n\n    def getParams(self, name=None):\n        d = self.data.get(name);\n        if(d is not None):\n            return d.get('params');\n        else:\n            return None;\n\n    def setValue(self, name, value=None, params=None, modified=True):\n        self.data[name]['value']=value;\n        self.data[name]['params']=params;\n        self.setEntryModified(name=name, is_modified=modified)\n\n    def saveEntry(self, name, path, force=False):\n        \"\"\"Save one entry to one file.\"\"\"\n        if(self.hasEntry(name=name) is None):\n            return None;\n        if(self.isEntryModified(name=name) or force or (not os.path.isfile(path))):\n            f = open(path, 'wb');\n            pickle.dump(self.getEntry(name=name), f, protocol=2);\n            f.close();\n            self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def setEntryModified(self, name, is_modified=True):\n        self.data[name]['modified']=is_modified;\n        if(is_modified):\n            self.setModified(is_modified=True);\n\n    def isEntryModified(self, name):\n        m=self.data[name].get('modified');\n        if(m is not None):\n            return m;\n        else:\n            return True;\n\n    def isModified(self):\n        return self.modified;\n\n    def setModified(self, is_modified):\n        self.modified=is_modified;\n\n    def save(self, path, force=False):\n        \"\"\"save all entries to one file.\"\"\"\n        if(force or self.isModified()):\n            f = open(path, 'wb');\n            pickle.dump(self.data, f, protocol=2);\n            f.close();\n            self.setModified(is_modified=False);\n        return True;\n\n    def loadEntry(self, name, path):\n        \"\"\"load one entry from one file.\"\"\"\n        f=open(path, 'rb');\n        self.setEntry(name=name, d=pickle.load(f));\n        f.close();\n        self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def load(self, path):\n        \"\"\"Load a set of entries all from one file.\"\"\"\n        f=open(path, 'rb');\n        newd = pickle.load(f);\n        self.data.update(newd);\n        f.close();\n        return True;\n\n    def getKeyList(self):\n        return list(self.data.keys());"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Audio.py",
    "content": "from .EventList import *\nfrom .TimeSignal1D import *\nfrom scipy.io.wavfile import write\nimport librosa\nimport librosa.display\n\nfrom scipy import signal, fftpack\n\n\n\nclass Audio(TimeSignal1D):\n    \"\"\"Audio (class): A sound, and a bunch of convenience functions to go with it.\n        Attributes:\n            x: the sound signal\n            sampling_rate: the sampling rate\n    \"\"\"\n\n    FEATURE_FUNCS = TimeSignal1D.FEATURE_FUNCS.copy();\n\n    def __init__(self, path=None, sampling_rate=None, x=None, name=None):\n        #VBObject.__init__(self, path=path);\n        TimeSignal1D.__init__(self, path=path, sampling_rate=sampling_rate, x=x);\n        #self.initializeBlank();\n        if(name is not None):\n            self.name = name;\n        if(path):\n            self.loadFile();\n        if(self.name is None):\n            self.name = self.getInfo('file_name')\n\n\n    # <editor-fold desc=\"Property: 'name'\">\n    @property\n    def name(self):\n        return self.getName();\n    def getName(self):\n        return self._name;\n    @name.setter\n    def name(self, value):\n        self._setName(value);\n    def _setName(self, value):\n        self._name = value;\n    # </editor-fold>\n\n    def initializeBlank(self):\n        self.name = None;\n        TimeSignal1D.initializeBlank(self);\n        self.n_channels = 1;\n\n    def _getFrameRate(self):\n        return self.getOnsetSamplingRate();\n\n    def clone(self):\n        clone = Audio();\n        clone.setPath(self.getPath());\n        clone.x = self.x.copy();\n        clone.sampling_rate = self.sampling_rate;\n        clone.n_channels = self.n_channels;\n        stereo = self.getStereo();\n        if (stereo is not None):\n            clone.setInfo('stereo_signal', stereo);\n            clone.setInfo('stereo_sampling_rate', self.getInfo('stereo_sampling_rate'));\n        return clone;\n\n    def loadFile(self, file_path=None, sampling_rate=None, convert_to_mono=True):\n        if(file_path):\n            self.setPath(file_path=file_path);\n\n        if('file_path' in self.a_info):\n            self.x, self.sampling_rate = librosa.load(self.a_info['file_path'],sr=sampling_rate, mono=convert_to_mono);\n            if(len(self.x.shape)>1):\n                self.a_info['stereo_signal']=self.x;\n                self.setInfo('stereo_sampling_rate', self.sampling_rate);\n                self.x = np.mean(self.x, axis = 0)\n                print(\"averaged stereo channels\");\n\n    def getStereo(self):\n        return self.a_info.get('stereo_signal');\n\n    def getStereoSamplingRate(self):\n        return self.getInfo('stereo_sampling_rate');\n\n\n\n    def getStringForHTMLStreamingBase64(self):\n        encoded = self.getStereoEncodedBase64WAV();\n        return \"data:audio/wav;base64,{0}\".format(encoded.decode('ascii'));\n\n    def getStereoEncodedBase64WAV(self):\n        sig = self.getStereo();\n        sr = self.getStereoSamplingRate();\n        if (sig is None):\n            sig = self.getSignal();\n            sr = self.sampling_rate;\n        saudio = _make_wav(sig, sr);\n        encoded = base64.b64encode(saudio);\n        return encoded;\n\n    def getMonoEncodedBase64WAV(self):\n        sig = self.getSignal();\n        sr = self.sampling_rate;\n        saudio = _make_wav(sig, sr);\n        encoded = base64.b64encode(saudio);\n        return encoded;\n\n    def getLocalRhythmicSaliency(self, **kwargs):\n        return self.getOnsetEnvelope(**kwargs);\n\n\n    def play(self, autoplay = None):\n        \"\"\"\n         Play audio. Works in Jupyter. if notebook, audio will play normalized -- this is something html5 audio seems to do by default.\n        :param autoplay:\n        :return:\n        \"\"\"\n        if(ISNOTEBOOK):\n            # if(normalize):\n            audiodisp = vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=autoplay);\n            vb_get_ipython().display.display(audiodisp);\n            # vb_get_ipython().display.display(vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=False))\n            # else:\n            # audiodisp = vb_get_ipython().display.Audio(data=self.getMonoEncodedBase64WAV(), rate=self.sampling_rate,\n            #                                            autoplay=autoplay);\n            # vb_get_ipython().display.display(audiodisp);\n            # print(\"html render\")\n            # htmlstr = self.getStringForHTMLStreamingBase64()\n            # ahtml = HTML(data='''<audio alt=\"{}\" controls>\n            #             <source src=\"{}\" type=\"audio/wav\" />\n            #          </audio>'''.format(self.name, htmlstr));\n            # IPython.display.display(ahtml);\n\n        else:\n            p = pyaudio.PyAudio()\n            stream = p.open(format=pyaudio.paFloat32,\n                             channels=self.n_channels,\n                             rate=self.sampling_rate,\n                             output=True,\n                             output_device_index=1\n                             )\n            stream.write(self.getSignal())\n            stream.stop_stream();\n            stream.close()\n            p.terminate()\n\n    def playBeats(self, indices=None, beats=None):\n        beat_inds = indices;\n        if(beats is None):\n            beats = self.getBeatEvents();\n        if(beat_inds is None):\n            beat_inds = [0, len(beats)-1];\n        if(not isinstance(beat_inds, list)):\n            beat_inds=[beat_inds-1, beat_inds, beat_inds+1];\n        if(beat_inds[0]<0):\n            start_time = 0;\n        else:\n            start_time = beats[beat_inds[0]].start;\n        if(beat_inds[-1]>len(beats)):\n            end_time = self.getDuration();\n        else:\n            end_time = beats[beat_inds[-1]].start;\n        self.playSegment(time_range = [start_time, end_time]);\n\n    def AudioClipFromBeatRange(self, beat_range, beats=None):\n        if(beats is None):\n            beats = self.getBeatEvents();\n        if(beat_range is None):\n            beat_range = [0, len(beats)-1];\n        if(beat_range[1] is None):\n            beat_range[1]=len(beats)-1;\n\n        return self.AudioClip(start=beats[beat_range[0]].start, end=beats[beat_range[1]].start);\n\n\n\n\n    def playSegment(self, time_range, autoplay=None):\n        start_time = time_range[0];\n        end_time = time_range[1];\n        if(isinstance(start_time, Event)):\n            start_time = start_time.start;\n        if(isinstance(end_time, Event)):\n            end_time = end_time.start;\n        if(ISNOTEBOOK):\n            audiodisp = vb_get_ipython().display.Audio(data=self.getSignalSegment(time_range=[start_time, end_time]), rate=self.sampling_rate, autoplay=autoplay);\n            vb_get_ipython().display.display(audiodisp);\n            # vb_get_ipython().display.display(vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=False))\n        else:\n            p = pyaudio.PyAudio()\n            stream = p.open(format=pyaudio.paFloat32,\n                             channels=self.n_channels,\n                             rate=self.sampling_rate,\n                             output=True,\n                             output_device_index=1\n                             )\n            stream.write(self.getSignalSegment(time_range=[start_time, end_time]))\n            stream.stop_stream();\n            stream.close()\n            p.terminate()\n\n    def writeToFile(self, output_path=None, output_sampling_rate=None):\n        assert(output_path), \"must provide path to save audio.\"\n        data = self.getSignal();\n        scaled = np.int16(data/np.max(np.abs(data)) * 32767)\n        if(output_sampling_rate is None):\n            output_sampling_rate=44100\n        write(output_path, output_sampling_rate, scaled)\n\n    def setValueRange(self, value_range=None):\n        if(value_range is None):\n            value_range = [-1,1];\n        TimeSignal1D.setValueRange(self, value_range=value_range);\n\n    def resample(self, sampling_rate):\n        new_n_samples = sampling_rate*self.getDuration();\n        self.x = sp.signal.resample(self.x, int(new_n_samples));\n        self.sampling_rate = sampling_rate;\n\n    def GetResampled(self, sampling_rate):\n        new_a = self.clone();\n        new_a.resample(sampling_rate=sampling_rate);\n        return new_a;\n\n\n\n    def AlignedTo(self, B):\n        assert(False),'Abe needs to fix -- broke when messing with alignment code for video';\n\n        A = self.clone();\n        if(A.sampling_rate !=B.sampling_rate):\n            A.resample(B.sampling_rate);\n\n        a_signal = A.getSignal();\n        b_signal = B.getSignal();\n        a_duration = self.getDuration();\n\n        if(len(a_signal) < len(b_signal)):\n            siglen = spotgt_shift_bit_length(len(b_signal));\n        else:\n            siglen = spotgt_shift_bit_length(len(a_signal));\n\n        npada = siglen-len(a_signal);\n        if(npada>0):\n            a_signal = np.pad(a_signal, (0,npada), 'constant', constant_values=(0, 0));\n\n        npadb = siglen-len(b_signal);\n        if(npadb>0):\n            b_signal = np.pad(b_signal, (0,npadb), 'constant', constant_values=(0, 0));\n\n        Af = fftpack.fft(a_signal);\n        Bf = fftpack.fft(b_signal);\n        Ar = Af.conjugate();\n        Br = Bf.conjugate();\n        # Ar = -Af.conjugate();\n        # Br = -Bf.conjugate();\n\n        ashift = np.argmax(np.abs(fftpack.ifft(Ar * Bf)));\n        print(ashift);\n        print((np.argmax(np.abs(fftpack.ifft(Af * Br)))));\n\n        a_return = Audio();\n        a_return.n_channels = 1;\n        a_return.sampling_rate = B.sampling_rate;\n        a_return.x = np.roll(a_signal, ashift);\n\n        return a_return;\n\n    def getOffsetFrom(self, B):\n        return -self.getShiftAmountTo(B);\n\n    def getShiftAmountTo(self, B):\n        \"\"\"\n        Get amount to shift by in seconds (to shift this to alignment with B)\n        \"\"\"\n        a_signal = self.getSignal();\n        b_signal = B.getSignal();\n        a_duration = self.getDuration();\n        if(self.sampling_rate !=B.sampling_rate):\n            ansamps = a_duration*B.sampling_rate;\n            a_signal = sp.signal.resample(a_signal, int(ansamps));\n            # a_signal = librosa.resample(a_signal, self.sampling_rate, B.sampling_rate, res_type='kaiser_fast');\n        if(len(a_signal) < len(b_signal)):\n            siglen = spotgt_shift_bit_length(len(b_signal));\n        else:\n            siglen = spotgt_shift_bit_length(len(a_signal));\n        npada = siglen-len(a_signal);\n        if(npada>0):\n            a_signal = np.pad(a_signal, (0,npada), 'constant', constant_values=(0, 0));\n        npadb = siglen-len(b_signal);\n        if(npadb>0):\n            b_signal = np.pad(b_signal, (0,npadb), 'constant', constant_values=(0, 0));\n\n        # if(len(a_signal) < len(b_signal)):\n        #     npad = len(b_signal)-len(a_signal);\n        #     a_signal = np.pad(a_signal, (0,npad), 'constant', constant_values=(0, 0));\n        #     print('pad1');\n        #\n        # if (len(b_signal) < len(a_signal)):\n        #     npad = len(a_signal) - len(b_signal);\n        #     b_signal = np.pad(b_signal, (0, npad), 'constant', constant_values=(0, 0));\n        #     print('pad2');\n\n        # print('point0')\n\n        Af = fftpack.fft(a_signal);\n        Bf = fftpack.fft(b_signal);\n        Ar = Af.conjugate();\n        Br = Bf.conjugate();\n        # Ar = -Af.conjugate();\n        # Br = -Bf.conjugate();\n        ashiftab = np.argmax(np.abs(fftpack.ifft(Ar * Bf)));\n        durationsamples = self.getDuration()*B.sampling_rate;\n        # if(ashiftab>(durationsamples*0.5)):\n        #     ashiftab = ashiftab-durationsamples;\n        return truediv(ashiftab, B.sampling_rate);\n\n    def getBeatEventList(self, time_range = None):\n        beats = self.getBeats();\n        if(time_range is None):\n            return EventList.FromStartTimes(beats, type='beats');\n\n        start_beat = 0;\n        end_beat = len(beats) - 1;\n        if(time_range[0] is not None):\n            while((start_beat<len(beats)) and (beats[start_beat]<time_range[0])):\n                start_beat=start_beat+1;\n        if(time_range[1] is not None):\n            while(end_beat>0 and (beats[end_beat]>time_range[1])):\n                end_beat = end_beat-1;\n        if(end_beat>start_beat):\n            return EventList.FromStartTimes(beats[start_beat:end_beat], type='beats');\n        else:\n            return None;\n\n\n    def getBeatEvents(self, start_time=None, end_time=None):\n        beat_eventlist = self.getBeatEventList();\n        return beat_eventlist.events;\n\n    def AudioClip(self, start, end):\n        from . import AudioClip\n        clip = AudioClip.AudioClip(path=self.getPath(), start=start, end=end);\n        return clip;\n\n\n    def getWithSoundAdded(self, add_times, sound=None, mute_original=None, gain_original = None):\n        if(sound is None):\n            sound = Audio.PingSound(sampling_rate=self.sampling_rate);\n        if(sound.sampling_rate==self.sampling_rate):\n            s_toadd = sound.getSignal();\n        else:\n            new_n_samples = self.sampling_rate * sound.getDuration();\n            s_toadd = sp.signal.resample(sound.getSignal(), int(new_n_samples));\n\n        result = self.clone();\n        if(mute_original):\n            result.x = np.zeros(result.x.shape);\n        if(gain_original is not None):\n            result.x = result.x*gain_original;\n\n\n        sl = len(s_toadd);\n        for t in add_times:\n            if(t<self.getDuration()):\n                ti = int(t*self.sampling_rate);\n                te = min(len(result.x), ti+sl);\n                result.x[ti:te]=result.x[ti:te]+s_toadd[0:te-ti];\n        result.setValueRange();\n        # result.setMaxAbsValue(1.0);\n        return result;\n\n\n    def showSpectrogram(self, time_range = None, **kwargs):\n        if(hop_length is None):\n            hop_length=AUDIO_DEFAULT_HOP_LENGTH;\n\n        fig = plt.figure();\n\n        S = self.getSpectrogram(hop_length=hop_length, **kwargs);\n        hop_length = self.getFeatureParams('spectrogram').get('hop_length');\n        print((\"hop length: {}\".format(hop_length)));\n        # S = librosa.stft(self.getSignal(), hop_length=hop_length);\n\n        librosa.display.specshow(librosa.amplitude_to_db(S,ref = np.max),sr=self.sampling_rate, hop_length=hop_length, y_axis = 'linear', x_axis = 'time')\n        plt.title('Power Spectrogram')\n        plt.colorbar(format='%+2.0f dB')\n        plt.ylim([0,8000]);\n        plt.xlabel('Time (s)')\n        if (time_range is not None):\n            plt.xlim(time_range);\n        plt.tight_layout()\n        return fig;\n\n    def showMelSpectrogram(self, force_recompute=False, **kwargs):\n        mel_spec = self.getMelSpectrogram(force_recompute=force_recompute, **kwargs);\n        # Make a new figure\n        plt.figure();\n        plt.figure(figsize=(12,4))\n        # Display the spectrogram on a mel scale\n        # sample rate and hop length parameters are used to render the time axis\n        librosa.display.specshow(mel_spec, sr=self.sampling_rate, x_axis='time', y_axis='mel')\n        # Put a descriptive title on the plot\n        plt.title('Mel Power Spectrogram')\n        # draw a color bar\n        plt.colorbar(format='%+02.0f dB')\n        # Make the figure layout compact\n        plt.tight_layout()\n\n\n    @staticmethod\n    def Silence(n_seconds, sampling_rate, name=None):\n        x = np.zeros(int(np.ceil(n_seconds*sampling_rate)));\n        s = Audio(x=x, sampling_rate = sampling_rate, name = name);\n        if(s.name is None):\n            s.name = 'silence';\n        return s;\n\n\n    @staticmethod\n    def _getDampedSin(freq, n_seconds=None, sampling_rate=16000, damping=0.1, noise_floor=0.001):\n        \"\"\"\n\n        :param freq:\n        :param n_seconds: if None, will set length necessary to damp to noise floor, up to 10.0s.\n        :param sampling_rate:\n        :param damping: Every period the amplitude is multiplied by 0.5^damping\n        :param noise_floor:\n        :return:\n        \"\"\"\n        if(n_seconds is None):\n            if(damping>0.005):\n                nosc = truediv(math.log(noise_floor,0.5),damping);\n                n_seconds = truediv(nosc, freq);\n            else:\n                n_seconds = 10.0;\n\n        x = np.sin(np.linspace(0, n_seconds * freq * 2 * np.pi, np.round(n_seconds * sampling_rate)));\n        dmp = np.linspace(0, n_seconds * freq, np.round(n_seconds * sampling_rate))\n        dmp = np.power(0.5, dmp * damping);\n        return np.multiply(x, dmp);\n\n\n\n    @staticmethod\n    def PingSound(n_seconds=None, freqs=None, damping=None, sampling_rate = 16000):\n        if(freqs is None):\n            # freqs = [400,500,600, 700, 800, 900, 1000, 1100, 1200, 1300];\n            # freqs = np.arange(4, 25) * 100\n            freqs = np.arange(5, 25) * 75; # just kind of thought this sounded fine...\n        if(damping is None):\n            damping = [0.05]*len(freqs);\n        if(not isinstance(damping,list)):\n            damping = [damping]*len(freqs);\n        s = Audio._getDampedSin(freq=freqs[0], n_seconds = n_seconds, sampling_rate = sampling_rate, damping=damping[0]);\n        for h in range(1,len(freqs)):\n            new_s = Audio._getDampedSin(freq=freqs[h], n_seconds = n_seconds, sampling_rate = sampling_rate, damping=damping[h]);\n            if(len(new_s)>len(s)):\n                new_s[:len(s)]=new_s[:len(s)]+s;\n                s = new_s;\n            else:\n                s[:len(new_s)] = s[:len(new_s)]+new_s;\n        sa = Audio(x=s, sampling_rate=sampling_rate, name = 'ping');\n        # sa.setValueRange(value_range=[-1,1]);\n        sa.setMaxAbsValue(1.0);\n        return sa;\n\n\n    ##### --- FEATURES --- #####\n\n    def getBeats(self, use_full_signal=True, tightness = None, force_recompute=False):\n        \"\"\"\n\n        :param use_full_signal: If called from AudioClip class, this will determine whether the full signal is used or\n            just the clip. This is important because the tempo is a global property. More evidence for a constant tempo\n            is good, but if the tempo changes over the audio you probably don't want to use the full signal.\n        :param tightness: How tightly to the tempo are beats picked. Must be positive. 0 would not care about tempo.\n            100 is default. This is actually part of the penalty used in the dynamic programming objective from\n            Ellis 2007. In librosa: txwt = -tightness * (np.log(-window / period) ** 2)\n        :param force_recompute:\n        :return:\n        \"\"\"\n        if ((not self.hasFeature(name='beats')) or force_recompute):\n            beat_args = dict(sr = self.sampling_rate, units = 'time');\n\n            if (use_full_signal):\n                beat_args.update(dict(y = self.getFullSignal()));\n            else:\n                beat_args.update(dict(y=self.getSignal()))\n            if (tightness is not None):\n                beat_args.update(dict(tightness=tightness));\n\n            # print(beat_args)\n            tempo, beats = librosa.beat.beat_track(**beat_args);\n            self.setFeature(name='tempo', value=tempo);\n            self.setFeature(name='beats', value=beats);\n        return self.getFeature(name='beats');\n\n    def getBeatVector(self, vector_length=None, force_recompute=False):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        if ((not self.hasFeature(name='beatvector')) or force_recompute):\n            D = self.getDuration();\n            if (vector_length is None):\n                vector_length = int(math.ceil(D * 240));\n            rvec = np.zeros(vector_length);\n            beats = self.getFeature('beats');\n            step = truediv(D, vector_length);\n            for i in range(len(beats)):\n                b = beats[i];\n                id = int(truediv(b, step));\n                rvec[id] = 1;\n            self.setFeature(name='beatvector', value=rvec);\n        return self.getFeature(name='beatvector');\n\n    def getOnsets(self, use_full_signal=True, force_recompute=False, **kwargs):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        if ((not self.hasFeature(name='onsets')) or force_recompute):\n            if (use_full_signal):\n                onsets = librosa.onset.onset_detect(y=self.getFullSignal(), sr=self.sampling_rate, units='time',\n                                                    **kwargs);\n                self.setFeature(name='onsets', value=onsets);\n            else:\n                onsets = librosa.onset.onset_detect(y=self.getSignal(), sr=self.sampling_rate, units='time',\n                                                    **kwargs);\n                self.setFeature(name='onsets', value=onsets);\n        return self.getFeature(name='onsets');\n\n    def getOnsetSamplingRate(self):\n        return np.true_divide(self.sampling_rate, AUDIO_DEFAULT_HOP_LENGTH);\n\n    def pickOnsets(self, pre_max_time=0.03,\n                   post_max_time=0.0,\n                   pre_avg_time=0.1,\n                   post_avg_time=0.1,\n                   wait_time=0.03,\n                   delta=0.07,\n                   force_recompute=True, **kwargs):\n        \"\"\"\n\n        :param pre_max_time:\n        :param post_max_time:\n        :param pre_avg_time:\n        :param post_avg_time:\n        :param wait_time:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        # kwargs.setdefault('pre_max', 0.03 * sr // hop_length)  # 30ms\n        # kwargs.setdefault('post_max', 0.00 * sr // hop_length + 1)  # 0ms\n        # kwargs.setdefault('pre_avg', 0.10 * sr // hop_length)  # 100ms\n        # kwargs.setdefault('post_avg', 0.10 * sr // hop_length + 1)  # 100ms\n        # kwargs.setdefault('wait', 0.03 * sr // hop_length)  # 30ms\n        # kwargs.setdefault('delta', 0.07)\n\n        pick_params = dict(\n            pre_max_time=pre_max_time,\n            post_max_time=post_max_time,\n            pre_avg_time=pre_avg_time,\n            post_avg_time=post_avg_time,\n            wait_time=wait_time,\n            delta=delta,\n        )\n\n        tp_keys = list(pick_params.keys());\n        for p in tp_keys:\n            pick_params[p] = int(round(self.getOnsetSamplingRate() * pick_params[p]));\n\n        dparams = dict(\n            pre_max=pick_params['pre_max_time'],\n            post_max=pick_params['post_max_time'] + 1,\n            pre_avg=pick_params['pre_avg_time'],\n            post_avg=pick_params['post_avg_time'] + 1,\n            wait=pick_params['wait_time'],\n            delta=delta\n        )\n\n        return self.getOnsets(force_recompute=force_recompute, **dparams);\n\n    def getEvents(self):\n        return self.getBeatEvents();\n\n    def getEventList(self):\n        return EventList(self.getBeatEvents());\n\n    def getOnsetEvents(self):\n        onsets = self.getOnsets();\n        events = Event.FromStartTimes(onsets, type='onsets');\n        return events;\n\n    def getBeatEvents(self, start_time=None, end_time=None, **kwargs):\n        beats = self.getBeats(**kwargs);\n        start_beat = 0;\n        end_beat = len(beats) - 1;\n        if(start_time is not None):\n            while((start_beat<len(beats)) and (beats[start_beat]<start_time)):\n                start_beat=start_beat+1;\n        if(end_time is not None):\n            while(end_beat>0 and (beats[end_beat]>end_time)):\n                end_beat = end_beat-1;\n        if(end_beat>start_beat):\n            return Event.FromStartTimes(beats[start_beat:end_beat], type='beats');\n        else:\n            return None;\n\n    def getOnsetEnvelope(self, use_full_signal=True, force_recompute=False, centering=True, **kwargs):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        feature_name = 'onset_envelope';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            if(use_full_signal):\n                eval_sig = self.getFullSignal();\n            else:\n                eval_sig = self.getSignal();\n            onsets = librosa.onset.onset_strength(y=eval_sig, sr=self.sampling_rate, centering=centering, hop_length=AUDIO_DEFAULT_HOP_LENGTH, **kwargs);\n\n            self.setFeature(name=feature_name, value=onsets);\n        return self.getFeature(name=feature_name);\n\n\n    def getMelSpectrogram(self, n_mels = 128, force_recompute=False):\n        feature_name = 'melspectrogram';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            params = dict( sr = self.sampling_rate,\n                                n_mels = n_mels);\n            Spec = librosa.feature.melspectrogram(self.getSignal(), **params);\n            self.setFeature(name=feature_name, value=librosa.power_to_db(Spec, ref=np.max), params=params);\n        return self.getFeature(feature_name);\n\n    def getSpectrogram(self, hop_length=None, force_recompute=False, **kwargs):\n        feature_name = 'spectrogram';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            # params = dict( sr = self.sampling_rate);\n            # params.update(kwargs);\n            params = dict(kwargs);\n\n            if(hop_length is None):\n                hop_length = AUDIO_DEFAULT_HOP_LENGTH;\n            params['hop_length'] = hop_length;\n\n            center = kwargs.get('center');\n            if(center is None):\n                center = True;\n            params['center'] = center;\n            # print('recomputing {}'.format(hop_length))\n\n            S = np.abs(librosa.stft(self.getSignal(), **params));\n            self.setFeature(name=feature_name, value=S, params=params);\n        return self.getFeature(feature_name);\n\n    def getRMSE(self, force_recompute=False, hop_length=None, frame_length=None):\n        feature_name = 'rmse';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            if(frame_length is None):\n                frac_of_second = 0.05;\n                frame_length=max(1, int(self.sampling_rate*frac_of_second));\n            if(hop_length is None):\n                hop_length=int(math.floor(frame_length*0.5));\n            params = dict( hop_length = hop_length,\n                                center = True,\n                                frame_length = frame_length);\n            rmse = librosa.feature.rmse(y=self.getSignal(), **params);\n            self.setFeature(name=feature_name, value=np.ndarray.flatten(rmse), params=params);\n        return self.getFeature(feature_name);\n\n\n    def getBeatTimeBefore(self, t):\n        return self.getBeatBefore(t=t).start;\n\n    def getBeatBefore(self, t):\n        beats = self.getBeatEvents();\n        bi = self.getBeatIndexBefore(t=t);\n        return beats[bi].start;\n\n    def getBeatIndexBefore(self, t):\n        beats = self.getBeatEvents();\n        for i, b in enumerate(beats):\n            if(b.start>t):\n                return i-1;\n        return len(beats)-1;\n\n\n    def getTempogram(self, window_length=None, force_recompute=None, frame_rate=None, resample_rate = None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param window_length: in seconds\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'tempogram';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            if (window_length is None):\n                window_length = DEFAULT_TEMPOGRAM_WINDOW_SECONDS;\n            tpgparams = {};\n            tpgparams.update(kwargs);\n\n            sr = self.sampling_rate;\n            y=self.getSignal();\n            if(resample_rate is None):\n                resample_rate = 22050;\n            if(sr>resample_rate):\n                print((\"resampling {}Hz to {}Hz\".format(sr, resample_rate)));\n                y = librosa.core.resample(y, orig_sr=sr, target_sr=resample_rate);\n                sr = resample_rate;\n                print(\"resampled\")\n\n            if(frame_rate is None):\n                frame_rate = 30;\n            hop_length = int(round(truediv(sr,frame_rate)));\n            win_length = int(round(window_length * frame_rate));\n\n            tparams = dict(y=y,\n                           sr=sr,\n                           hop_length=hop_length,\n                           win_length=win_length,\n                           **kwargs);\n            tpgparams.update(dict(sr=sr,hop_length=hop_length, win_length=win_length));\n            result = librosa.feature.tempogram(**tparams);\n            ###########\n            tempo_bpms = librosa.tempo_frequencies(result.shape[0], hop_length=hop_length, sr=sr)\n            self.setFeature(name='tempogram_bpms', value=tempo_bpms);\n            self.setFeature(name=feature_name, value=result, params=tpgparams);\n            self.setInfo(label='tempogram_params',value=tpgparams);\n\n        return self.getFeature(feature_name);\n\n    def plotTempogram(self, window=None, time_range=None, **kwargs):\n        tempogram = self.getFeature('tempogram', force_recompute=True);\n        tparams = self.getInfo('tempogram_params')\n        toshow = tempogram;\n        if(window is not None):\n            wstart=int(round(window[0]*self.sampling_rate));\n            wend = int(round(window[1]*self.sampling_rate));\n            toshow = tempogram[:,wstart:wend];\n\n        mplt = librosa.display.specshow(toshow, sr=tparams['sr'], hop_length=tparams['hop_length'], x_axis = 'time', y_axis = 'tempo')\n        plt.legend(frameon=True, framealpha=0.75)\n        plt.set_cmap('coolwarm')\n        plt.colorbar(format='%+2.0f dB')\n        if (time_range is not None):\n            plt.xlim(time_range);\n        plt.xlabel('Time (s)')\n        plt.title('Audio Tempogram');\n        plt.tight_layout()\n        return mplt;\n\n    def plotOnsets(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = self.getOnsetEvents();\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotBeats(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = self.getBeatEvents();\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.title('Onset Envelope and Beats');\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotOnsetEnvelope(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = None;\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.title('Onset Envelope');\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotSignal(self, time_range=None, ylim=None, **kwargs):\n        signal = self.getSignal();\n        # Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        times = np.arange(len(signal));\n        times = times * truediv(1.0, self.sampling_rate);\n        mplt = plt.plot(times, signal);\n        if (time_range is not None):\n            plt.xlim(time_range[0], time_range[1])\n        if (ylim is not None):\n            plt.ylim(ylim);\n        plt.title('Time Signal');\n        return mplt;\n\n\n    FEATURE_FUNCS['melspectrogram'] = getMelSpectrogram;\n    FEATURE_FUNCS['spectrogram'] = getSpectrogram;\n    FEATURE_FUNCS['rmse'] = getRMSE;\n    FEATURE_FUNCS['beats'] = getBeats;\n    FEATURE_FUNCS['onsets'] = getOnsets;\n    FEATURE_FUNCS['beatvector'] = getBeatVector;\n    FEATURE_FUNCS['tempogram'] = getTempogram;\n    FEATURE_FUNCS['onset_envelope'] = getOnsetEnvelope;\n\n\ndef _make_wav(data, rate):\n    \"\"\" Transform a numpy array to a PCM bytestring \"\"\"\n    import struct\n    from io import BytesIO\n    import wave\n\n    try:\n        import numpy as np\n\n        data = np.array(data, dtype=float)\n        if len(data.shape) == 1:\n            nchan = 1\n        elif len(data.shape) == 2:\n            # In wave files,channels are interleaved. E.g.,\n            # \"L1R1L2R2...\" for stereo. See\n            # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx\n            # for channel ordering\n            nchan = data.shape[0]\n            data = data.T.ravel()\n        else:\n            raise ValueError('Array audio input must be a 1D or 2D array')\n        scaled = np.int16(data / np.max(np.abs(data)) * 32767).tolist()\n    except ImportError:\n        # check that it is a \"1D\" list\n        idata = iter(data)  # fails if not an iterable\n        try:\n            iter(next(idata))\n            raise TypeError('Only lists of mono audio are '\n                            'supported if numpy is not installed')\n        except TypeError:\n            # this means it's not a nested list, which is what we want\n            pass\n        maxabsvalue = float(max([abs(x) for x in data]))\n        scaled = [int(x / maxabsvalue * 32767) for x in data]\n        nchan = 1\n\n    fp = BytesIO()\n    waveobj = wave.open(fp, mode='wb')\n    waveobj.setnchannels(nchan)\n    waveobj.setframerate(rate)\n    waveobj.setsampwidth(2)\n    waveobj.setcomptype('NONE', 'NONE')\n    waveobj.writeframes(b''.join([struct.pack('<h', x) for x in scaled]))\n    val = fp.getvalue()\n    waveobj.close()\n\n    return val"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/AudioClip.py",
    "content": "from .Audio import *\n\nclass AudioClip(Audio):\n    \"\"\"AudioClip (class): A segment of a video, and a bunch of convenience functions to go with it.\n        Attributes:\n            start: The name of the video\n            end: The framerate of the video\n    \"\"\"\n\n    def VBOBJECT_TYPE(self):\n        return 'AudioClip';\n\n    def __init__(self, audio=None, start=None, end=None, path=None):\n        assert(not (audio and path)), \"provided both video object and path to VideoClip constructor.\"\n        # assert((start is not None) and (end is not None)), \"must provide start time and end time to AudioClip constructor\"\n        Audio.__init__(self, path=path);\n        #self.initializeBlank();#gets called by parent\n        if(start is None):\n            start = 0;\n        if(end is None):\n            if(audio is not None):\n                end = audio.getDuration();\n            else:\n                end = truediv(len(self.x), self.sampling_rate);\n\n        self.start = start;\n        self.end = end;\n\n\n        if(audio):\n            self.setPath(audio.getPath());\n            self.x = audio.x;\n            self.sampling_rate=audio.sampling_rate;\n            self.n_channels=audio.n_channels;\n            stereo = audio.getStereo();\n            if(stereo):\n                self.a_info['stereo_signal']=stereo;\n        if(self.sampling_rate):\n            self._pull_clip_potion();\n\n\n    def _pull_clip_potion(self):\n        startsample = math.floor(self.sampling_rate * self.start);\n        endsample = math.ceil(self.sampling_rate * self.end);\n        startinsample = max(startsample, 0);\n        endinsample = min(endsample, len(self.x));\n        self.clipped = self.x[int(startinsample):int(endinsample)];\n        if (startsample < 0):\n            self.clipped = np.concatenate((np.zeros(int(-startsample)), self.clipped));\n        if (endsample > len(self.x)):\n            self.clipped = np.concatenate((np.zeros(int(endsample - len(self.x))), self.clipped));\n\n\n    def resample(self, sampling_rate):\n        Audio.resample(self, sampling_rate);\n        self._pull_clip_potion();\n\n    def initializeBlank(self):\n        Audio.initializeBlank(self);\n        self.start = None;\n        self.end = None;\n        self.resampled = None;\n        self.clipped = None;\n\n    def getSignal(self, resample=False):\n        if(self.resampled):\n            return self.resampled;\n        if(resample):\n            assert(False), \"haven't implemented audio clip resampling yet.\";\n        return self.clipped\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Event.py",
    "content": "from .VisBeatImports import *\n\nclass Event(AObject):\n    \"\"\"Event (class): An event in time, either in video or audio\n        Attributes:\n            start: when the event starts\n    \"\"\"\n\n    DIRECTION_FORWARD = 1;\n    DIRECTION_BACKWARD = -1;\n    DIRECTION_BOTH = 0;\n    _EVENT_PHASE_BASE_RES = 8;\n\n    def AOBJECT_TYPE(self):\n        return 'Event';\n\n    def __str__(self):\n        return str(self.getAttributeDict());\n\n    def __init__(self, start=None, type=None, weight=None, index=None, is_active=1, unrolled_start = None, direction=0, **kwargs):\n        AObject.__init__(self, path=None);\n        self.start = start;\n        self.type=type;\n        self.weight=weight;\n        self.index = index;\n        self.unrolled_start = unrolled_start;\n        self.is_active = is_active;\n        self.direction = direction;\n        self.a_info.update(kwargs);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.start = None;\n        self.type = None;\n        self.weight = None;\n        self.index = None;\n        self.unrolled_start = None;\n        self.is_active = None;\n        self.direction = None;\n\n\n    def getAttributeDict(self):\n        d = dict();\n        d['start'] = self.start;\n        d['type'] = self.type;\n        d['weight'] = self.weight;\n        d['index'] = self.index;\n        d['unrolled_start'] = self.unrolled_start;\n        d['is_active'] = self.is_active;\n        d['direction'] = self.direction;\n        return d;\n\n    def toDictionary(self):\n        d=AObject.toDictionary(self);\n        d.update(self.getAttributeDict());\n        return d;\n\n\n    def initAttributesFromDictionary(self, d):\n        self.start = d['start'];\n        self.type = d.get('type');\n        self.weight = d.get('weight');\n        self.index = d['index'];\n        self.unrolled_start = d.get('unrolled_start');\n        self.is_active = d['is_active'];\n        if (d.get('direction') is None):\n            self.direction = 0;\n        else:\n            self.direction = d['direction'];\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        self.initAttributesFromDictionary(d);\n\n    def clone(self, start=None):\n        newe = Event();\n        newe.initFromDictionary(self.toDictionary());\n        if (start):\n            newe.start = start;\n        return newe;\n\n\n    def _getIsSelected(self):\n        return self.getInfo('is_selected');\n    def _setIsSelected(self, is_selected):\n        self.setInfo('is_selected', is_selected);\n\n    def _getPhase(self, phase_resolution=None):\n        if (self.getInfo('phase') is None):\n            return -1;\n        if (phase_resolution is None):\n            return self.getInfo('phase');\n        else:\n            return self.getInfo('phase') * (phase_resolution / Event._EVENT_PHASE_BASE_RES);\n\n    def _setPhase(self, phase, phase_resolution):\n        if (phase_resolution is None):\n            self.setInfo('phase', phase);\n        else:\n            self.setInfo('phase', phase * (Event._EVENT_PHASE_BASE_RES / phase_resolution));\n\n    def _getBoundaryType(self):\n        return self.getInfo('boundary_type');\n    def _setBoundaryType(self, boundary_type):\n        self.setInfo('boundary_type', boundary_type);\n\n    @classmethod\n    def _FromGUIDict(cls, gd, phase_resolution=None):\n        e = cls();\n        e.initAttributesFromDictionary(gd);\n        e._setPhase(gd['phase'], phase_resolution=phase_resolution);\n        e._setBoundaryType(gd.get('boundary_type'));\n        e._setIsSelected(gd.get('is_selected'));\n        return e;\n\n    @classmethod\n    def _FromGUIDicts(cls, gds, type=None):\n        events = [];\n        for gd in gds:\n            ne = cls._FromGUIDict(gd);\n            if (type is not None):\n                ne.type = type;\n            events.append(ne);\n        return events;\n\n    def _toGUIDict(self):\n        '''\n        note that is_active is switched to 0 or 1 for javascript/json\n        :return:\n        '''\n        d = self.getAttributeDict();\n        if(self.is_active):\n            d['is_active'] = 1;\n        else:\n            d['is_active'] = 0;\n        d['phase'] = self._getPhase();\n        d['boundary_type'] = self._getBoundaryType();\n        d['is_selected'] = self._getIsSelected();\n        return d;\n\n    @staticmethod\n    def _ToGUIDicts(events, active=None):\n        '''\n        convert to dicts for javascript GUI\n        :param events:\n        :param active: if not none, all of the is_active flags will be set to this\n        :return:\n        '''\n        startind = int(round(time.time() * 1000));\n        starts = [];\n        for e in range(len(events)):\n            de = events[e]._toGUIDict();\n            if (active is not None):\n                assert (active is 0 or active is 1), \"is_active must be 0 or 1\";\n                de['is_active'] = active;\n            if (de.get('index') is None):\n                de['index'] = startind + e;\n            starts.append(de);\n        return starts;\n\n\n    def getUnrolledStartTime(self):\n        if(self.unrolled_start is not None):\n            return self.unrolled_start;\n        else:\n            return self.start;\n\n\n    def getStartTime(self):\n        return self.start;\n\n\n\n    def getShifted(self, new_start_time):\n        return Event(self.start-new_start_time, type=self.type, weight=self.weight, index=self.index);\n\n\n\n\n    @staticmethod\n    def GetUnrolledList(event_list, assert_on_folds=None):\n        out_list = [];\n        event0 = event_list[0].clone();\n        event0.unrolled_start = event0.start;\n        event0.index = 0;\n        out_list.append(event0);\n        for e in range(1,len(event_list)):\n            newe = event_list[e].clone();\n            if(assert_on_folds):\n                assert(newe.start>=out_list[-1].start), 'FOLD (non-monotonic event list) DETECTED WHEN NOT ALLOWED!!!\\n see Event.GetUnrolledList'\n            newe.unrolled_start = out_list[-1].unrolled_start+np.fabs(newe.start-out_list[-1].start);\n            newe.index = e;\n            out_list.append(newe);\n        return out_list;\n\n    @staticmethod\n    def NewFromIndices(event_list, inds):\n        out_list = [];\n        for ei in inds:\n            out_list.append(event_list[ei].clone());\n        return out_list;\n\n    @staticmethod\n    def RollToNOld(events, n_out, momentum = 0.25):\n        inds = [0];\n        step = 1;\n        n_events = len(events);\n        for b in range(1,n_out):\n            lastind = inds[-1];\n            if ((n_out-b)<(n_events-lastind) or lastind==0):\n                inds.append(lastind+1);\n                step = 1;\n            elif(lastind==(len(events)-1)):\n                inds.append(len(events)-2);\n                step = -1;\n            else:\n                foreward_p = 0.5+momentum;\n                roll = np.random.rand();\n                if(roll<foreward_p):\n                    inds.append(lastind+step);\n                else:\n                    inds.append(lastind-step);\n                    step = -step;\n        print(inds);\n        return Event.GetUnrolledList(Event.NewFromIndices(events, inds));\n\n    @staticmethod\n    def UnfoldToN(events, n_out, momentum=0.25):\n        # This weird way of implementing is the result of stripping non-visbeat stuff out of the original code...\n        return Event.RollToN(events=events, n_out=n_out, momentum=momentum);\n\n\n\n    @staticmethod\n    def GetDirectedLinks(events):\n        links = [{}]\n        links[0]['prev_f']=None;\n        links[0]['prev_b'] = None;\n        lastf = None;\n        lastb = None;\n        if(events[0].direction<1):\n            lastb = 0;\n        if(events[0].direction>-1):\n            lastf = 0;\n\n        for ei in range(1,len(events)):\n            links.append({});\n            links[ei]['prev_f']=lastf;\n            links[ei]['prev_b']=lastb;\n\n            lastbu = lastb;\n            lastfu = lastf;\n            if(lastbu is None):\n                lastbu = 0;\n            if(lastfu is None):\n                lastfu = 0;\n\n\n            if(events[ei].direction<1):\n                for lb in range(lastbu,ei):\n                    links[lb]['next_b']=ei;\n                    # print(\"ei is {} and lastbu is {}, lastb is {}\".format(ei, lastbu, lastb));\n                lastb = ei;\n            if (events[ei].direction>-1):\n                for lf in range(lastfu, ei):\n                    links[lf]['next_f'] = ei;\n                    # print(\"ei is {} and lastfu is {}, lastf is {}\".format(ei, lastfu, lastf));\n                lastf = ei;\n\n        return links;\n\n\n    @staticmethod\n    def RollToN(events, n_out, start_index = 0, momentum=0.1):\n        links = Event.GetDirectedLinks(events);\n        inds = [start_index];\n        step = 1;\n        n_events = len(events);\n        for b in range(1, n_out):\n            lastind = inds[-1];\n            foreward_p = 0.5 + momentum;\n            roll = np.random.rand();\n\n            if (roll < foreward_p):\n                step = step;\n            else:\n                step = -step;\n\n            if(links[lastind].get('prev_b') is None):\n                step = 1;\n            if(links[lastind].get('next_f') is None):\n                step = -1;\n\n            if(step>0):\n                inds.append(links[lastind]['next_f']);\n            else:\n                inds.append(links[lastind]['prev_b']);\n        # print(inds);\n        return Event.GetUnrolledList(Event.NewFromIndices(events, inds));\n\n\n\n    @staticmethod\n    def Clone(event_list):\n        out_list = [];\n        for ei in event_list:\n            out_list.append(ei.clone());\n        return out_list;\n\n    @staticmethod\n    def SetDirections(event_list, direction):\n        for e in range(len(event_list)):\n            event_list[e].direction = direction;\n        return event_list;\n\n\n\n    @classmethod\n    def FromStartTimes(cls, starts, type=None):\n        events = [];\n        for s in starts:\n            events.append(cls(start=s, type=type));\n        return events;\n\n    @classmethod\n    def FromStartsAndWeights(cls, starts, weights, type=None):\n        events = [];\n        assert(len(starts)==len(weights)), 'Event.FromStartsAndWeights got {} starts and {} weights'.format(len(starts), len(weights));\n        for s in range(len(starts)):\n            events.append(cls(start=starts[s], weight=weights[s],type=type));\n        return events;\n\n    @staticmethod\n    def ToStartTimes(events):\n        starts = np.zeros(len(events));\n        for e in range(len(events)):\n            starts[e]=events[e].start;\n        return starts;\n\n    @staticmethod\n    def ToWeights(events):\n        weights = np.zeros(len(events));\n        for e in range(len(events)):\n            weights[e] = events[e].weight;\n        return weights;\n\n    #endpoint is false if events are already placed at beginning and end\n    @staticmethod\n    def RepeatToLength(events, n, endpoints=False):\n        if(n<len(events)):\n            return events[:n];\n        if(n==len(events)):\n            return events;\n\n        if(endpoints):\n            print(\"HAVE NOT IMPLEMENTED ENDPOINTS VERSION OF REPEAT\")\n\n        dup_index = 1;\n        while(len(events)<n):\n            interval = events[dup_index].start-events[dup_index-1].start;\n            last_time = events[-1].start;\n            newevent = events[dup_index].clone(start=last_time+interval);\n            events.append(newevent);\n            dup_index=dup_index+1;\n        return events;\n\n    @staticmethod\n    def Double(events):\n        doubled = [];\n        for e in range(1,len(events)):\n            halfstart = 0.5*(events[e].start+events[e-1].start);\n            doubled.append(events[e].clone(start=halfstart));\n            doubled.append(events[e]);\n        return doubled;\n\n    @staticmethod\n    def Half(events, offset=0):\n        if(offset is None):\n            offset=0;\n\n        halved = [];\n        for e in range(1,len(events)):\n            if((e%2)==offset):\n                halved.append(events[e]);\n        return halved;\n\n    @staticmethod\n    def SubdivideIntervals(events, extra_samples_per_interval=1):\n        newe = [];\n        samples = np.linspace(0,1,extra_samples_per_interval+2)[1:-1];\n        newe.append(events[0]);\n        for e in range(1, len(events)):\n            for s in samples:\n                newstart = events[e].start*s+events[e-1].start*(1.0-s);\n                newe.append(events[e].clone(start=newstart));\n            newe.append(events[e].clone())\n        return newe;\n\n    @staticmethod\n    def Third(events, offset=0):\n        if (offset is None):\n            offset = 0;\n        third = [];\n        for e in range(len(events)):\n            if (not ((e+offset) % 3)):\n                third.append(events[e]);\n        return third;\n\n    @staticmethod\n    def SubsampleEveryN(events, n, offset=0):\n        if (offset is None):\n            offset = 0;\n        newe = [];\n        for e in range(len(events)):\n            if (not ((e + offset) % n)):\n                newe.append(events[e]);\n        return newe;\n\n    # @staticmethod\n    # def FromSignalBeats(signal, sampling_rate, event_type=None, **kwargs):\n    #     # seg = [0,100]\n    #     # xvals = range(seg[1]-seg[0])\n    #     xvals = np.arange(len(signal));\n    #     xvals = xvals*truediv(1.0, sampling_rate);\n    #\n    #     vis_tempo, beatinds = librosa.beat.beat_track(y=None, sr=sampling_rate, onset_envelope=signal, hop_length=1, start_bpm=100.0, tightness=80,\n    #                                                   trim=True, bpm=None, units='frames');\n    #     peaktimes = xvals[beatinds.astype(int)];\n    #     peakvals = signal[beatinds.astype(int)];\n    #     return Event.FromStartsAndWeights(starts=peaktimes, weights=peakvals, type=event_type);\n\n\n    @staticmethod\n    def FromSignalPeaks(signal, sampling_rate, event_type=None, index_offset=None, **kwargs):\n        xvals = np.arange(len(signal));\n        xvals = xvals*truediv(1.0, sampling_rate);\n\n        time_params = dict(\n            pre_max_time=0.2,\n            post_max_time=0.2,\n            pre_avg_time=0.2,\n            post_avg_time=0.2,\n            wait_time=0.1,\n        )\n        tp_keys = list(time_params.keys());\n        time_params.update(kwargs);\n\n        delta = kwargs.get('delta');\n        if (delta is None):\n            delta = 0.2;\n\n        print(delta)\n\n        for p in tp_keys:\n            time_params[p] = int(round(sampling_rate * time_params[p]));\n\n        dparams = dict(\n            pre_max=time_params['pre_max_time'],\n            post_max=time_params['post_max_time'],\n            pre_avg=time_params['pre_avg_time'],\n            post_avg=time_params['post_avg_time'],\n            wait=time_params['wait_time'],\n            delta=delta\n        )\n\n        # print(dparams)\n        peakinds = librosa.util.peak_pick(x=signal, **dparams);\n        # print(peakinds)\n        if(not len(peakinds)):\n            return [];\n        if(index_offset is not None):\n            print(('index offset {}'.format(index_offset)))\n            for pi in range(len(peakinds)):\n                newi = peakinds[pi]+index_offset;\n                if(newi>=0 and newi<len(xvals)):\n                    print(('{} to {}'.format(peakinds[pi], newi)))\n                    peakinds[pi]=newi;\n\n\n        peaktimes = xvals[peakinds];\n        peakvals = signal[peakinds];\n        return Event.FromStartsAndWeights(starts=peaktimes, weights=peakvals, type=event_type);\n\n\n    @staticmethod\n    def PlotEventMatches(source_events, target_events, source_in=None, target_in=None):\n        t_height = 0.75;\n        s_height = 0.25;\n        if ((source_in is not None) and (target_in is not None)):\n            n_in = min(len(source_in), len(target_in));\n            evt = Event.ToStartTimes(target_in[:n_in]);\n            evs = Event.ToStartTimes(source_in[:n_in]);\n            plt.plot(evt, np.ones(len(evt)) * t_height, 'o');\n            plt.plot(evs, np.ones(len(evs)) * s_height, 'o');\n\n        s_et = Event.ToStartTimes(source_events);\n        t_et = Event.ToStartTimes(target_events);\n\n        for ev in range(len(target_events)):\n            plt.plot([s_et[ev], t_et[ev]], [s_height, t_height], '-');\n\n    @staticmethod\n    def GetWithFirstEventAt(events, first_event_time):\n        oute = [];\n        shift_time = events[0].start-first_event_time;\n        for e in events:\n            oute.append(e.getShifted(new_start_time=shift_time));\n        return oute;\n\n    @staticmethod\n    def GetWithStartTimesShifted(events, new_start_time):\n        oute = [];\n        for e in events:\n            oute.append(e.getShifted(new_start_time=new_start_time));\n        return oute;\n\n    @staticmethod\n    def GetScaled(events, scale):\n        oute = [];\n        for e in events:\n            oute.append(Event(e.start*scale, weight=e.weight, type=e.type, index=e.index));\n        return oute;\n\n    @staticmethod\n    def GetScaledAndStartingAt(events, scale, starting_at):\n        ev = Event.GetScaled(events, scale);\n        ev = Event.GetWithFirstEventAt(ev, starting_at);\n        return ev;\n\n    @staticmethod\n    def ClosestToTargetMatch(source_events, target_events):\n        def _closest_e(target_e):\n            def sortfunc_e(source_e):\n                return math.fabs(source_e[1].start-target_e.start);\n            return sortfunc_e;\n        def _getinds(s_sort):\n            inds = [];\n            for s in s_sort:\n                inds.append(s[0]);\n            return inds;\n        def _getevents(s_sorted):\n            evnts = [];\n            for s in s_sort:\n                evnts.append(s[1]);\n            return evnts;\n\n        S = [];\n        T = [];\n        for s in range(len(source_events)):\n            S.append([s, source_events[s]]);\n        for t in range(len(target_events)):\n            T.append([t, target_events[t]]);\n\n        S_sorted = [];\n        for t in T:\n            S_sorted.append(sorted(S, key=_closest_e(t[1])));\n\n        s_out_inds = [-1]*len(T);\n        match_map = {};\n        for ti in range(len(S_sorted)):\n            # print(S_sorted[ti][0][0]);\n            matched_source_event_i = S_sorted[ti][0][0];#sorted lists, first element, index value for index\n            existing_match = match_map.get(matched_source_event_i);\n            matchdist = math.fabs(source_events[matched_source_event_i].start - target_events[ti].start);\n            if(existing_match is not None):\n                if(matchdist<existing_match[1]):\n                    # print('overrule')\n                    s_out_inds[existing_match[0]]=-1;\n                    s_out_inds[ti]=matched_source_event_i;\n                    # print(\"ti {}\\nmatched {}\\n\".format(ti, matched_source_event_i));\n                    match_map[matched_source_event_i]=[ti, matchdist];\n            else:\n                match_map[matched_source_event_i] = [ti, matchdist];\n                s_out_inds[ti]=matched_source_event_i;\n\n        S_out = [];\n        T_out = [];\n        # print(\"s_out_inds: {}\".format(s_out_inds))\n        for e in range(len(s_out_inds)):\n            if(s_out_inds[e]>=0):\n                T_out.append(target_events[e]);\n                S_out.append(source_events[s_out_inds[e]]);\n\n        return S_out, T_out;\n\n    @staticmethod\n    def Sort(event_list, func=None):\n        assert(func is None or func=='start' or func=='time'), \"have not implemented sort by {}\".format(func);\n        event_list.sort(key=lambda x: x.start);\n        return event_list;\n\n    @staticmethod\n    def GetSorted(event_list, func=None):\n        clone = Event.Clone(event_list);\n        Event.Sort(clone, func=func);\n        return clone;\n\n    @staticmethod\n    def GetWithTwoWayMerged(event_list, merge_window = 0.1):\n        event_list_sorted = Event.GetSorted(event_list);\n        new_events = [];\n        new_events.append(event_list_sorted[0].clone());\n        for ei in range(1,len(event_list_sorted)):\n            thise = event_list_sorted[ei];\n            if((thise.start-new_events[-1].start)<merge_window):\n                if((thise.direction+new_events[-1].direction)==0):\n                    new_events[-1].start = 0.5*(thise.start+new_events[-1].start);\n                    new_events[-1].direction = 0;\n            else:\n                new_events.append(thise.clone());\n        return new_events\n\n\n    @staticmethod\n    def ApplyIndices(event_list):\n        for e in range(len(event_list)):\n            event_list[e].index = e;\n\n    @staticmethod\n    def PlotSignalAndEvents(signal, sampling_rate, events, time_range = None, ylim=None, **kwargs):\n        times = np.arange(len(signal));\n        times = times*truediv(1.0,sampling_rate);\n\n        if (kwargs.get('other_events')):\n            oet, oev = eventsToTimes(kwargs.get('other_events'), time_range);\n            plt.plot(oet, oev, 'x');\n\n        if(events is not None):\n            btimes = Event.ToStartTimes(events);\n            binds = np.round(btimes*sampling_rate).astype(int);\n            bvals = signal[binds];\n\n            mplt = plt.plot(times, signal, '-', btimes, bvals, 'o');\n        else:\n            mplt = plt.plot(times, signal, '-');\n\n        if(time_range is not None):\n            plt.xlim(time_range[0], time_range[1])\n        if(ylim is not None):\n            plt.ylim(ylim);\n        # plt.show()\n        return mplt;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/EventList.py",
    "content": "from .Event import *\n\nclass EventList(AObject):\n    \"\"\"Event (class): An event in time, either in video or audio\n        Attributes:\n            start: when the event starts\n    \"\"\"\n\n    def AOBJECT_TYPE(self):\n        return 'EventList';\n\n    def __init__(self, events=None):\n        AObject.__init__(self, path=None);\n        if(events is not None):\n            self.events = events;\n\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.events = [];\n\n    def list(self):\n        return self.events;\n\n    def Clone(self):\n        return EventList(Event.Clone(self.events));\n\n    def toDictionary(self):\n        d=AObject.toDictionary(self);\n        d['events']=self.serializeEvents();\n        return d;\n\n    def serializeEvents(self):\n        re = [];\n        for e in self.events:\n            re.append(e.toDictionary());\n        return re;\n\n    def getActiveEvents(self):\n        active_events = [];\n        for e in self.events:\n            if(e.is_active):\n                active_events.append(e);\n        return active_events;\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        events = d['events'];\n        for e in events:\n            newe = Event();\n            newe.initFromDictionary(e);\n            self.events.append(newe);\n\n    def unroll(self, assert_on_folds=None):\n        newlist = Event.GetUnrolledList(event_list=self.events, assert_on_folds=assert_on_folds);\n        self.events = newlist;\n\n    def getUnrolled(self, assert_on_folds=None):\n        return EventList(Event.GetUnrolledList(event_list=self.events, assert_on_folds=assert_on_folds));\n\n    def getFromIndices(self, inds):\n        return EventList(Event.NewFromIndices(event_list=self.events, inds=inds));\n\n    def getRolledToN(self, n_out, momentum = 0.1):\n        return EventList(Event.RollToN(self.events, n_out=n_out, momentum=momentum));\n\n\n    def toStartTimes(self):\n        return Event.ToStartTimes(self.events);\n\n    def _toGUIDicts(self):\n        return Event._ToGUIDicts(self.events);\n\n    @staticmethod\n    def _FromGUIDicts(gds, type=None):\n        events = Event._FromGUIDicts(gds, type=type);\n        return EventList(events);\n\n\n    @staticmethod\n    def FromJSON(json_path=None):\n        if (json_path is None):\n            json_path = fileui.GetFilePath();\n        elist = EventList();\n        elist.loadFromJSON(json_path=json_path);\n        return elist;\n\n    @staticmethod\n    def FromStartTimes(starts, type=None, event_class=None):\n        elist = EventList();\n        if(event_class is None):\n            event_class = Event;\n        for s in starts:\n            elist.events.append(event_class(start=s, type=type));\n        return elist;\n\n\n    def toWeights(self):\n        return Event.ToWeights(self.events);\n\n    def getDoubled(self):\n        return EventList(Event.Double(self.Clone().events));\n\n    def getHalved(self, offset=0):\n        return EventList(Event.Half(self.Clone().events, offset=offset));\n\n    def getThirded(self, offset=0):\n        return EventList(Event.Third(self.Clone().events, offset=offset));\n\n    @staticmethod\n    def FromSignalPeaks(**kwargs):\n        return EventList(Event.FromSignalPeaks(**kwargs));\n\n    @staticmethod\n    def PlotEventMatches(source_elist, target_elist, source_in=None, target_in=None):\n        return Event.PlotEventMatches(source_events=source_elist.events, target_events=target_elist.events, source_in=source_in, target_in=target_in);\n\n    def getWithFirstEventAt(self, first_event_time):\n        return EventList(Event.GetWithFirstEventAt(events=self.events, first_event_time=first_event_time));\n\n    def getWithStartTimesShifted(self, new_start_time):\n        return EventList(Event.GetWithStartTimesShifted(events = self.events, new_start_time=new_start_time));"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Image.py",
    "content": "#Image_Base\n#import numpy as np\n#import scipy as sp\nfrom PIL import Image as PIM\nfrom PIL import ImageDraw, ImageFont\n\nfrom .VisBeatImports import *\n# from PlotUtils import *\n\n\nVBMARK_SIZE = 0.135;\nVBMMARGIN = 0.02;\n\ndef imshow(imdata, new_figure = True):\n    if(ISNOTEBOOK):\n        #plt.imshow(self.data*0.0039215686274509);#divided by 255\n        if(new_figure):\n            plt.figure();\n        if(len(imdata.shape)<3):\n            plt.imshow(imdata, cmap='gray');\n        else:\n            plt.imshow(imdata);#divided by 255\n        plt.axis('off');\n\n\nclass Image(AObject):\n    \"\"\"Image\n    \"\"\"\n    IMAGE_TEMP_DIR = None;\n    USING_OPENCV=False;\n    _VBMRK = None;\n\n    def AOBJECT_TYPE(self):\n        return 'Image';\n\n    def __init__(self, data=None, path = None):\n        AObject.__init__(self, path=path);\n        self.data = data;\n        if(path and (not data)):\n            self.loadImageData();\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.data = None;\n\n    def setBlank(self, shape=None):\n        if(not shape):\n            self.data = np.zeros(self.data.shape);\n        else:\n            self.data = np.zeros([shape[0], shape[1], ]);\n\n    def loadImageData(self, path = None, force_reload=True):\n        if(path):\n            self.setPath(path);\n        if(self.a_info.get('file_path')):\n            if(force_reload or (not self.data)):\n                pim = PIM.open(fp=self.a_info['file_path']);\n                self.data = np.array(pim);\n\n    @property\n    def shape(self):\n        return self._getShape();\n\n    def _getShape(self):\n        return np.asarray(self.data.shape)[:];\n\n    @property\n    def dtype(self):\n        return self.data.dtype;\n\n    @property\n    def width(self):\n        return self._getWidth();\n\n    def _getWidth(self):\n        return self.shape[1];\n\n    @property\n    def height(self):\n        return self._getHeight();\n\n    def _getHeight(self):\n        return self.shape[0];\n\n    @property\n    def _is_float(self):\n        return (self.dtype.kind in 'f');\n\n    @property\n    def _is_int(self):\n        return (self.dtype.kind in 'iu');\n\n    @property\n    def _pixels_float(self):\n        if (self._is_float):\n            return self.data;\n        else:\n            return self.data.astype(np.float) * np.true_divide(1.0, 255.0);\n\n    @property\n    def _pixels_uint(self):\n        if (self._is_int):\n            return self.data;\n        else:\n            return (self.data * 255).astype(np.uint8);\n\n    @property\n    def n_channels(self):\n        return self._getNChannels();\n\n    def _getNChannels(self):\n        if(len(self.data.shape)<3):\n            return 1;\n        else:\n            return self.data.shape[2];\n\n    @staticmethod\n    def FromGrayScale(gray_data, color_map = None, format=None, **kwargs):\n        if(not color_map):\n            newim = Image(data=np.dstack((gray_data,gray_data,gray_data)));\n        else:\n            cmap=matplotlib.cm.get_cmap(name=color_map);\n            #norm = mpl.colors.Normalize(vmin=-20, vmax=10)\n            #cmapf = cm.ScalarMappable(norm=norm, cmap=cmap)\n            cmapf = matplotlib.cm.ScalarMappable(cmap=cmap);\n            if(format is None):\n                newim = Image(data=cmapf.to_rgba(gray_data)*255);\n            else:\n                assert(False), \"unrecognized format {}\".format(format);\n\n        newim.a_info['ColorType']='FromGrayScale';\n        return newim;\n\n    @staticmethod\n    def printTempDir():\n        print((Image.IMAGE_TEMP_DIR));\n\n    def scaleToValueRange(self, value_range=None):\n        is_int = self._is_int;\n        if(value_range is None):\n            value_range = [0.0,255.0];\n        data = self.data.ravel();\n        currentmin=np.min(data);\n        currentmax=np.max(data);\n        currentscale = currentmax-currentmin;\n        if(currentscale==0):\n            VBWARN(\"CANNOT SCALE CONSTANT IMAGE\")\n            return;\n        divscale = truediv(1.0,currentscale);\n        newrange=(value_range[1]-value_range[0]);\n        self.data = (self.data*divscale)*newrange;\n        newmin = (currentmin*divscale)*newrange;\n        self.data = self.data-newmin+value_range[0]\n        if(is_int and value_range[1]>254):\n            self.data = self.data.astype(np.int);\n\n\n    def nChannels(self):\n        if(len(self.data.shape)<3):\n            return 1;\n        else:\n            return self.data.shape[2];\n\n    def getClone(self):\n        rimg = Image(path=self.a_info.get('file_path'), data=self.data.copy());\n        return rimg;\n\n    def getGridPixel(self,x,y,repeatEdge=0):\n        xo = x;\n        yo = y;\n\n        blackedge = np.zeros(1);\n        if(len(self.data.shape)==3):\n            blackedge = np.zeros(self.data.shape[2])\n\n        if(y>=self.data.shape[0]):\n            if(repeatEdge==1):\n                yo = self.data.shape[0]-1\n            else:\n                return blackedge\n\n        if(y<0):\n            if(repeatEdge==1):\n                yo = 0\n            else:\n                return blackedge\n\n        if(x>=self.data.shape[1]):\n            if(repeatEdge==1):\n                xo=self.data.shape[1]-1\n            else:\n                return blackedge\n\n        if(x<0):\n            if(repeatEdge==1):\n                xo = 0\n            else:\n                return blackedge\n\n        return self.data[yo,xo]\n\n    def getPixel(self, x, y, repeatEdge=0):\n        if(isinstance(y,int) and isinstance(x,int)):\n            return self.getGridPixel(x,y)\n        else:\n            yf = int(np.floor(y))\n            yc = int(np.ceil(y))\n            xf = int(np.floor(x))\n            xc = int(np.ceil(x))\n\n            print('getting here?')\n            print(xf);\n            print(yf);\n\n            tl = self.getGridPixel(xf,yf,repeatEdge)\n            tr = self.getGridPixel(xc,yf,repeatEdge)\n            bl = self.getGridPixel(xf,yc,repeatEdge)\n            br = self.getGridPixel(xc,yc,repeatEdge)\n\n            yalpha = y-yf\n            xalpha = x-xf\n\n            topL = tr*xalpha+tl*(1.0-xalpha)\n            botL = br*xalpha+bl*(1.0-xalpha)\n\n            retv = botL*yalpha+topL*(1.0-yalpha)\n            return retv\n\n    def getShape(self):\n        return np.asarray(self.data.shape)[:];\n\n    def getScaled(self, shape=None, shape_xy=None):\n        shapeis = (shape is not None);\n        shapexyis = (shape_xy is not None);\n        assert((shapeis or shapexyis) and not (shapeis and shapexyis)), \"Must provide only one of shape or shape_xy for Image.getScaled\"\n        if(shapeis):\n            sz=[shape[0], shape[1], self.data.shape[2]];\n        else:\n            sz=[shape_xy[1],shape_xy[0],self.data.shape[2]];\n        imK = sp.misc.imresize(self.data, size=sz);\n        return Image(data=imK);\n\n    def getRotated(self, theta):\n        imR = sp.misc.imrotate(self.data, theta);\n        return Image(data=imR);\n\n\n    # def splatAtPixCoord(self, im, location=[0,0]):\n    #     self.data[location[0]:(location[0]+im.data.shape[0]), location[1]:(location[1]+im.data.shape[1]),:]=im.data;\n    def _splatAtPixCoord(self, im, location=[0,0], **kwargs):\n        is_int = self._is_int;\n        selftype = self.dtype;\n        region0 = [location[0], (location[0]+im.data.shape[0])];\n        region1 = [location[1], (location[1]+im.data.shape[1])];\n        if(im.n_channels<4):\n            self.data[region0[0]:region0[1], region1[0]:region1[1],:]=im.data;\n            return;\n        if(im.n_channels == 4):\n            alphamap = np.moveaxis(np.tile(im._pixels_float[:, :, 3], (3, 1, 1)), [0], [2]);\n\n            blenda = (im._pixels_float[:, :, :3]) * alphamap + self._pixels_float[region0[0]:region0[1], region1[0]:region1[1],:]*(1.0 - alphamap);\n            if(is_int):\n                blenda = (blenda*255).astype(selftype);\n            self.data[region0[0]:region0[1], region1[0]:region1[1], :] = blenda;\n\n\n\n    def reflectY(self):\n        self.data[:,:,:]=self.data[::-1,:,:];\n\n    def reflectX(self):\n        self.data[:,:,:]=self.data[:,::-1,:];\n\n    def PIL(self):\n        return PIM.fromarray(np.uint8(self.data));\n\n    def getRGBData(self):\n        return self.data[:,:,0:3];\n\n    def normalize(self, scale=1.0):\n        self.data = self.data/np.max(self.data.ravel());\n        self.data = self.data*scale;\n\n    def show(self, new_figure = True):\n        if(ISNOTEBOOK):\n            if(new_figure):\n                plt.figure();\n            if(self.nChannels()==1):\n                plt.imshow(self.PIL(), cmap='gray');\n            else:\n                plt.imshow(self.PIL());#divided by 255\n            plt.axis('off');\n        else:\n            self.PIL().show();\n\n    def writeToFile(self, out_path):\n        self.PIL().save(out_path);\n\n    def getEncodedBase64(self):\n        return base64.b64encode(self.data);\n\n    def getDataAsString(self):\n        return self.data.tostring();\n\n    @staticmethod\n    def FromBase64(encoded_data, shape):\n        d = base64.decodestring(encoded_data);\n        npar = np.frombuffer(d, dtype=np.float64);\n        rIm = Image(data=np.reshape(npar, shape));\n        return rIm;\n\n\n\n\n    @staticmethod\n    def FromDataString(data_string, shape, dtype=None):\n        if(dtype is None):\n            dtype=np.float64;\n        img_1d = np.fromstring(data_string, dtype=dtype);\n        reconstructed_img = img_1d.reshape((height, width, -1))\n\n\n###########################adapted from https://gist.github.com/turicas/1455973##########################\n    def _get_font_size(self, text, font_path, max_width=None, max_height=None):\n        if max_width is None and max_height is None:\n            raise ValueError('You need to pass max_width or max_height')\n        font_size = 1\n        text_size = self.get_text_size(font_path, font_size, text)\n        if (max_width is not None and text_size[0] > max_width) or (max_height is not None and text_size[1] > max_height):\n            raise ValueError(\"Text can't be filled in only (%dpx, %dpx)\" % text_size)\n        while True:\n            if (max_width is not None and text_size[0] >= max_width) or (max_height is not None and text_size[1] >= max_height):\n                return font_size - 1\n            font_size += 1\n            text_size = self.get_text_size(font_path, font_size, text)\n\n    def writeOutlinedText(self, xy, text,\n                   font_size=11,\n                   max_width=None,\n                   max_height=None,\n                   encoding='utf8', draw_context = None):\n        self.writeText(xy=[xy[0]+3, xy[1]+3], text=text, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=font_size,\n                       max_width=max_width,\n                       color=(0, 0, 0),\n                       max_height=max_height,\n                       encoding=encoding, draw_context=draw_context);\n        self.writeText(xy=xy, text=text, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=font_size,\n                       max_width=max_width,\n                       color=(255, 255, 255),\n                       max_height=max_height,\n                       encoding=encoding, draw_context=draw_context);\n\n\n    def writeText(self, xy, text, font_filename='RobotoCondensed-Regular.ttf',\n                   font_size=11,\n                   color=(0, 0, 0),\n                   max_width=None,\n                   max_height=None,\n                   encoding='utf8', draw_context = None):\n\n        x=xy[0];\n        y=xy[1];\n\n        font_paths = find_all_files_with_name_under_path(name=font_filename,\n                                                         path=os.path.dirname(os.path.abspath(__file__)));\n        font_path = font_paths[0];\n\n        if isinstance(text, str):\n            text = text.decode(encoding)\n        if font_size == 'fill' and (max_width is not None or max_height is not None):\n            font_size = self._get_font_size(text, font_path, max_width,\n                                           max_height)\n        text_size = self._get_text_size(font_path, font_size, text)\n\n\n        font = ImageFont.truetype(font=font_path, size=font_size);\n\n        # font = ImageFont.truetype(font_filename, font_size)\n        if x == 'center':\n            x = (self.data.shape[1] - text_size[0]) / 2\n        if y == 'center':\n            y = (self.data.shape[0] - text_size[1]) / 2\n\n        if(draw_context is None):\n            ipil = self.PIL();\n            draw = ImageDraw.Draw(ipil)\n            draw.text((x, y), text, font=font, fill=color)\n            datashape = self.data.shape;\n            self.data = np.array(ipil.getdata());\n            self.data.shape = datashape;\n        else:\n            draw_context.text((x, y), text, font=font, fill=color);\n        return text_size\n\n    def _get_text_size(self, font_path, font_size, text):\n        font = ImageFont.truetype(font_path, font_size)\n        return font.getsize(text)\n\n    @staticmethod\n    def _VBMark():\n        if(Image._VBMRK is None):\n            Image._VBMRK = Image(path=GetVBMarkPath());\n        return Image._VBMRK;\n\n    def _vbmark(self):\n        self._splatAtPixCoord(**self._vbmarker());\n\n    def _vbmarker(self):\n        vbm = Image._VBMark();\n        wmfrac = min(VBMARK_SIZE * self.width, VBMARK_SIZE * self.height);\n        scaleval = min(1.0, np.true_divide(wmfrac, vbm.width));\n        if (scaleval < 1.0):\n            vbms = vbm.getScaled(shape=[int(vbm.shape[0] * scaleval), int(vbm.shape[1] * scaleval), vbm.shape[2]]);\n        else:\n            vbms = vbm.clone();\n        margin = min(vbm.width, vbm.height, int(VBMMARGIN * self.width), int(VBMMARGIN * self.height));\n\n        return dict(im=vbms, location=[self.height - vbms.height - margin, self.width - vbms.width - margin]);\n\n    def writeTextBox(self, xy, text, box_width, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=11, color=(0, 0, 0), place='left',\n                       justify_last_line=False):\n\n        x = xy[0];\n        y = xy[1];\n\n        font_paths = find_all_files_with_name_under_path(name=font_filename,\n                                                         path=os.path.dirname(os.path.abspath(__file__)));\n        font_path = font_paths[0];\n\n        lines = []\n        line = []\n        words = text.split()\n        for word in words:\n            new_line = ' '.join(line + [word])\n            size = self._get_text_size(font_path, font_size, new_line)\n            text_height = size[1]\n            if size[0] <= box_width:\n                line.append(word)\n            else:\n                lines.append(line)\n                line = [word]\n        if line:\n            lines.append(line)\n        lines = [' '.join(line) for line in lines if line]\n        height = y\n        for index, line in enumerate(lines):\n            height += text_height\n            if place == 'left':\n                self.writeText((x, height), line,\n                                font_filename,\n                                font_size,\n                                color)\n            elif place == 'right':\n                total_size = self._get_text_size(font_path, font_size, line)\n                x_left = x + box_width - total_size[0]\n                self.writeText((x_left, height), line, font_filename,\n                                font_size, color)\n            elif place == 'center':\n                total_size = self._get_text_size(font_path, font_size, line)\n                x_left = int(x + ((box_width - total_size[0]) / 2))\n                self.writeText((x_left, height), line,\n                                font_filename,\n                                font_size, color)\n            elif place == 'justify':\n                words = line.split()\n                if (index == len(lines) - 1 and not justify_last_line) or len(words) == 1:\n                    self.writeText((x, height), line,\n                                    font_filename,\n                                    font_size,\n                                    color)\n                    continue\n                line_without_spaces = ''.join(words)\n                total_size = self._get_text_size(font_path, font_size,\n                                                line_without_spaces)\n                space_width = (box_width - total_size[0]) / (len(words) - 1.0)\n                start_x = x\n                for word in words[:-1]:\n                    self.writeText((start_x, height), word,\n                                    font_filename,\n                                    font_size, color)\n                    word_size = self._get_text_size(font_path, font_size,\n                                                   word)\n                    start_x += word_size[0] + space_width\n                last_word_size = self._get_text_size(font_path, font_size,\n                                                    words[-1])\n                last_word_x = x + box_width - last_word_size[0]\n                self.writeText((last_word_x, height), words[-1],\n                                font_filename,\n                                font_size, color)\n        return (box_width, height - y)\n#####################################################\n\nfrom . import Image_CV\nif(Image_CV.USING_OPENCV):\n    Image.USING_OPENCV = Image_CV.USING_OPENCV;\n    Image.RGB2Gray=Image_CV.RGB2Gray;\n    Image.GrayToRGB=Image_CV.Gray2RGB;\n    Image.cvGoodFeaturesToTrack=Image_CV.cvGoodFeaturesToTrack;\n    Image.withFlow=Image_CV.withFlow;\n    cvDenseFlowFarneback = Image_CV.cvDenseFlowFarneback;\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    ocv = Image_CV.ocv;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Image_CV.py",
    "content": "\n\n#CVFunctions\nfrom .VisBeatImports import *\nimport numpy as np\nimport scipy as sp\nfrom PIL import Image as PIM\n#from VBObject import *\nfrom . import Image as vbImage\nimport math\n\nDEFAULT_FLOW_HISTOGRAM_BINS = 8;\n\n\nUSING_OPENCV=True\ntry:\n    import cv2 as ocv\nexcept ImportError:\n    USING_OPENCV=False;\n    AWARN('OpenCV not installed; not importing Image_CV')\n\n\n#these are functions that use OpenCV that aren't class functions\nif(USING_OPENCV):\n    def flow2rgb(flow):\n        h, w = flow.shape[:2]\n        fx, fy = flow[:,:,0], flow[:,:,1]\n        ang = np.arctan2(fy, fx) + np.pi\n        v = np.sqrt(fx*fx+fy*fy)\n        hsv = np.zeros((h, w, 3), np.uint8)\n        hsv[...,0] = ang*(180/np.pi/2)\n        hsv[...,1] = 255\n        #v=np.minimum(v*4, 255);\n        v = np.log(v+1);\n        vmax = np.max(v[:]);\n        vf=v/vmax;\n        v=vf*255;\n        hsv[...,2] = v;#np.minimum(v*4, 255)\n        rgb = ocv.cvtColor(hsv, ocv.COLOR_HSV2BGR)\n        return rgb\n\n    def showFlowHSV(flow, new_figure = True):\n        if(ISNOTEBOOK):\n            #plt.imshow(self.data*0.0039215686274509);#divided by 255\n            if(new_figure):\n                plt.figure();\n            plt.imshow(PIM.fromarray(flow2rgb(flow)));\n            plt.axis('off');\n        else:\n            self.PIL().show();\n\n    def cornerHarris(im, blockSize=None, ksize=None, k=None):\n        if (blockSize is None):\n            blockSize = 2;\n        if (ksize is None):\n            ksize = 3;\n        if (k is None):\n            k = 0.04;\n        return ocv.cornerHarris(im, 2, 3, 0.04);\n\n    def cvDenseFlowFarneback(from_image, to_image, pyr_scale=None, levels=None, winsize=None, iterations=None, poly_n=None, poly_sigma=None, flags=None):\n        \"\"\"Can provide numpy arrays or Image objects as input. Returns the flow from->to.\"\"\"\n        # params for Farneback's method\n        from_im=from_image;\n        to_im=to_image;\n        from_is_ob = isinstance(from_image, vbImage.Image);\n        to_is_ob = isinstance(to_image, vbImage.Image)\n\n        if(from_is_ob):\n            if(from_image.nChannels()>1):\n                from_im=from_image.getClone();\n                from_im.RGB2Gray();\n            from_im=from_im.data;\n        if(to_is_ob):\n            if(to_image.nChannels()>1):\n                to_im=to_image.getClone();\n                to_im.RGB2Gray();\n            to_im=to_im.data;\n\n\n\n        inputs = dict( flow = None,\n                            pyr_scale = pyr_scale,\n                            levels = levels,\n                            winsize = winsize,\n                            iterations = iterations,\n                            poly_n = poly_n,\n                            poly_sigma = poly_sigma,\n                            flags=flags);\n\n        default_flow=None;\n        default_pyr_scale=0.5;\n        default_levels=int(math.log(float(min(to_im.shape)), 2))-4;\n        default_winsize = 15;\n        default_iterations=3;\n        default_poly_n=5;\n        default_poly_sigma=1.25;\n\n        use_params = dict(flow=default_flow,\n                          pyr_scale=default_pyr_scale,\n                          levels=default_levels,\n                          winsize=default_winsize,\n                          iterations=default_iterations,\n                          poly_n=default_poly_n,\n                          poly_sigma=default_poly_sigma,\n                          flags=0);\n\n        for key in inputs:\n            if(inputs[key] is not None):\n                use_params[key]=inputs[key];\n\n        return ocv.calcOpticalFlowFarneback(prev=from_im, next=to_im, **use_params);\n\n\n\n# These functions are to add to Image class\nif(USING_OPENCV):\n    def RGB2Gray(self):\n        if(self.nChannels()==1):\n            return;\n        else:\n            self.data = ocv.cvtColor(self.data, ocv.COLOR_RGB2GRAY);\n\n    def Gray2RGB(self):\n        if(self.nChannels()==1):\n            self.data = ocv.cvtColor(self.data, ocv.COLOR_GRAY2RGB)\n\n    def cvGoodFeaturesToTrack(self, maxCorners=None, qualityLevel=None, minDistance=None, corners=None, mask=None, blockSize=None, useHarrisDetector=None):\n        assert(self.data is not None), \"must provide image to find features\";\n\n        if(self.nChannels()==1):\n            gray_image=self.data.copy();\n        else:\n            gray_image=ocv.cvtColor(self.data, cv2.COLOR_RGB2GRAY);\n\n        argd={};\n        if(maxCorners is not None):\n            d['maxCorners']=maxCorners;\n        if(qualityLevel is not None):\n            d['qualityLevel']=qualityLevel;\n        if(minDistance is not None):\n            d['minDistance']=minDistance;\n        if(corners is not None):\n            d['corners']=corners;\n        if(mask is not None):\n            d['mask']=mask;\n        if(blockSize is not None):\n            d['blockSize']=blockSize;\n        if(useHarrisDetector is not None):\n            d['useHarrisDetector']=useHarrisDetector;\n        return ocv.goodFeaturesToTrack(gray_image, **argd);\n\n\n\n    def withFlow(self, flow, step=16):\n        clone = self.getClone();\n        if(clone.nChannels()<3):\n            clone.convertToRGB();\n        img = clone.data;\n        h, w = img.shape[:2]\n        y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)\n        # flow[y, x] is fx, fy\n        fx, fy = flow[y,x].T\n        # After vstack, each column: x, y, x+fx, y+fy\n        # After transpose: each row: x, y, x+fx, y+fy\n        # After reshape: each row: [[x, y], [x+fx, y+fy]]\n        lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)\n        lines = np.int32(lines + 0.5)\n        ocv.polylines(img, lines, 0, (0, 255, 0), thickness=3)\n        for (x1, y1), (x2, y2) in lines:\n            cv2.circle(img, (x1, y1), 1, (0, 255, 0), -1)\n        return clone\n\n    \n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/SourceLocationParser.py",
    "content": "\"\"\"\nThis code was a last minute hack. It works fine enough for parsing youtube urls, but I would use it for any kind of reference.\nBased loosely on video backends from django embed video.\n\"\"\"\n\nimport re\nimport requests\nimport os\nimport sys\nif sys.version_info.major == 3:\n    import urllib.parse as urlparse\nelse:\n    import urllib.parse\n\nclass SourceURL(object):\n    \"\"\"\n    Modified from django embed video\n    \"\"\"\n\n\n    allow_https = True\n    is_secure = False\n\n    @classmethod\n    def SourceLocationType(cls):\n        return cls.__name__;\n\n    def __init__(self, source_location):\n        self.source_location_type = self.SourceLocationType()\n        self._source_location = source_location\n\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        \"\"\"\n        unique string to identify file\n        :return:\n        \"\"\"\n        return self._getCode();\n\n    def _getCode(self):\n        raise NotImplementedError;\n\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        raise NotImplementedError;\n    # </editor-fold>\n\n\n    @property\n    def url(self):\n        \"\"\"\n        URL of video.\n        \"\"\"\n        return self.get_url()\n    def get_url(self):\n        raise NotImplementedError\n\n    @property\n    def protocol(self):\n        \"\"\"\n        Protocol used to generate URL.\n        \"\"\"\n        return 'https' if self.allow_https and self.is_secure else 'http'\n\n    @property\n    def thumbnail(self):\n        \"\"\"\n        URL of video thumbnail.\n        \"\"\"\n        return self.get_thumbnail_url()\n\n    @classmethod\n    def is_valid(cls, url):\n        return True if cls.re_detect.match(url) else False\n\nclass WebSourceException(Exception):\n    \"\"\" Parental class for all embed_media exceptions \"\"\"\n    pass\n\n\nclass VideoDoesntExistException(WebSourceException):\n    \"\"\" Exception thrown if video doesn't exist \"\"\"\n    pass\n\n\nclass UnknownBackendException(WebSourceException):\n    \"\"\" Exception thrown if video backend is not recognized. \"\"\"\n    pass\n\n\nclass UnknownIdException(VideoDoesntExistException):\n    \"\"\"\n    Exception thrown if backend is detected, but video ID cannot be parsed.\n    \"\"\"\n    pass\n\n\nclass YoutubeURL(SourceURL):\n    \"\"\"\n    for YouTube URLs.\n    \"\"\"\n\n    @classmethod\n    def SourceLocationType(cls):\n        return 'youtube';\n\n    # Compiled regex (:py:func:`re.compile`) to search code in URL.\n    # Example: ``re.compile(r'myvideo\\.com/\\?code=(?P<code>\\w+)')``\n    re_code = None\n\n    # Compilede regec (:py:func:`re.compile`) to detect, if input URL is valid for current backend.\n    # Example: ``re.compile(r'^http://myvideo\\.com/.*')``\n    re_detect = None\n\n    # Pattern in which the code is inserted.\n    # Example: ``http://myvideo.com?code=%s``\n    # :type: str\n    pattern_url = None\n\n    pattern_thumbnail_url = None\n\n    re_detect = re.compile(\n        r'^(http(s)?://)?(www\\.|m\\.)?youtu(\\.?)be(\\.com)?/.*', re.I\n    )\n\n    re_code = re.compile(\n        r'''youtu(\\.?)be(\\.com)?/  # match youtube's domains\n            (\\#/)? # for mobile urls\n            (embed/)?  # match the embed url syntax\n            (v/)?\n            (watch\\?v=)?  # match the youtube page url\n            (ytscreeningroom\\?v=)?\n            (feeds/api/videos/)?\n            (user\\S*[^\\w\\-\\s])?\n            (?P<code>[\\w\\-]{11})[a-z0-9;:@?&%=+/\\$_.-]*  # match and extract\n        ''',\n        re.I | re.X\n    )\n\n    pattern_url = '{protocol}://www.youtube.com/embed/{code}'\n    pattern_thumbnail_url = '{protocol}://img.youtube.com/vi/{code}/{resolution}'\n\n    resolutions = [\n        'maxresdefault.jpg',\n        'sddefault.jpg',\n        'hqdefault.jpg',\n        'mqdefault.jpg',\n    ]\n\n\n    def get_url(self):\n        \"\"\"\n        Returns URL folded from :py:data:`pattern_url` and parsed code.\n        \"\"\"\n        url = self.pattern_url.format(code=self.code, protocol=self.protocol)\n        url += '?' + self.query.urlencode() if self.query else ''\n        return url\n\n    def get_thumbnail_url(self):\n        \"\"\"\n        Returns thumbnail URL folded from :py:data:`pattern_thumbnail_url` and\n        parsed code.\n\n        :rtype: str\n        \"\"\"\n        return self.pattern_thumbnail_url.format(code=self.code,\n                                                 protocol=self.protocol)\n\n    def _getCode(self):\n\n        match = self.re_code.search(self._source_location)\n        if match:\n            return match.group('code')\n\n        parsed_url = urllib.parse.urlparse(self._source_location)\n        parsed_qs = urllib.parse.parse_qs(parsed_url.query)\n\n        if 'v' in parsed_qs:\n            code = parsed_qs['v'][0]\n        elif 'video_id' in parsed_qs:\n            code = parsed_qs['video_id'][0]\n        else:\n            raise UnknownIdException('Cannot get ID from `{0}`'.format(self._source_location))\n\n        return code\n\n    def get_thumbnail_url(self):\n        \"\"\"\n        Returns thumbnail URL folded from :py:data:`pattern_thumbnail_url` and\n        parsed code.\n\n        :rtype: str\n        \"\"\"\n        for resolution in self.resolutions:\n            temp_thumbnail_url = self.pattern_thumbnail_url.format(\n                code=self.code, protocol=self.protocol, resolution=resolution)\n            if int(requests.head(temp_thumbnail_url).status_code) < 400:\n                return temp_thumbnail_url\n        return None\n\n\n\nclass FilePathURL(SourceURL):\n    @classmethod\n    def SourceLocationType(cls):\n        return 'file_path';\n\n    def __init__(self, source_location):\n        self.source_location_type = self.SourceLocationType()\n        self._source_location = source_location;\n\n    @classmethod\n    def is_valid(cls, source_location):\n        return os.path.isfile(source_location);\n\n    def _getCode(self):\n        name_parts = os.path.splitext(os.path.basename(self._source_location));\n        return name_parts[0];\n\n\n\nSOURCE_LOCATION_TYPES = (\n    YoutubeURL,\n    FilePathURL,\n)\n\ndef ParseSourseLocation(url):\n    \"\"\"\n\n    :param url:\n    :return:\n    \"\"\"\n    for backend in SOURCE_LOCATION_TYPES:\n        if backend.is_valid(url):\n            return backend(url)\n\n    raise UnknownBackendException"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/TimeSignal.py",
    "content": "from .VBObject import *\nfrom .Event import *\nimport math\nfrom operator import truediv\nfrom .VisBeatImports import *\n\nclass TimeSignal(VBObject):\n    \"\"\"TimeSignal (class): A time signal, and a bunch of convenience functions to go with it.\n        Attributes:\n            sampling_rate: the sampling rate\n            visualizations dictionary of visualizations. (removed - too many dependencies)\n    \"\"\"\n\n    def VBBJECT_TYPE(self):\n        return 'TimeSignal';\n\n    def __init__(self, path=None, sampling_rate = None):\n        VBObject.__init__(self, path=path);\n        # self.initializeBlank();\n        # self.visualizations = AFuncDict(owner=self, name='visualizations');\n        # self.visualizations.functions.update(self.VIS_FUNCS);\n        if(sampling_rate):\n            self.sampling_rate=sampling_rate;\n\n    def initializeBlank(self):\n        VBObject.initializeBlank(self);\n        self.sampling_rate = None;\n\n\n    # <editor-fold desc=\"Property: 'frame_rate'\">\n    @property\n    def frame_rate(self):\n        return self._getFrameRate();\n    def _getFrameRate(self):\n        raise NotImplementedError;\n    # </editor-fold>\n\n\n    def getSampleAtTime(self, f):\n        prev_sample = self.getSampleAtIndex(math.floor(f));\n        next_sample = self.getSampleAtIndex(math.ceil(f));\n        sample_progress = f-np.floor(f);\n        return (next_sample*sample_progress)+(prev_sample*(1.0-sample_progress));\n\n    def getSampleAtIndex(self, i):\n        return self.getTimeForIndex();\n\n    def getDuration(self):\n        assert(False), \"getDuration must be implemented for subclass of TimeSignal\"\n\n    def getSampleDuration(self):\n        return 1.0/self.sampling_rate;\n\n    def getTimeForIndex(self, i):\n        return i*self.getSampleDuration();\n\n    # def toDictionary(self):\n    #     d = VBObject.toDictionary(self);\n    #     assert(False), \"haven't implemented toDictionary for {} yet\".format(self.VBOBJECT_TYPE())\n    #     #serialize class specific members\n    #     return d;\n\n    # def initFromDictionary(self, d):\n    #     VBObject.initFromDictionary(self, d);\n    #     assert(False), \"haven't implemented initFromDictionary for {} yet\".format(self.VBOBJECT_TYPE())\n    #     #do class specific inits with d;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/TimeSignal1D.py",
    "content": "from .TimeSignal import *\nimport math\n\nclass TimeSignal1D(TimeSignal):\n    \"\"\"TimeSignal1D (class): A time signal, and a bunch of convenience functions to go with it.\n        Attributes:\n            sampling_rate: the sampling rate\n            x:  the time signal\n    \"\"\"\n\n    def VBOJECT_TYPE(self):\n        return 'TimeSignal1D';\n\n    def __init__(self, path=None, sampling_rate = None, x=None):\n        TimeSignal.__init__(self, path=path, sampling_rate=sampling_rate);\n        if(x is not None):\n            self.x = x;\n        #self.initializeBlank(); # will be called by parent\n\n    def initializeBlank(self):\n        TimeSignal.initializeBlank(self);#YES KEEP call through weird loops\n        self.x = None;\n\n    def getSignal(self, resampled=False):\n        return self.x;\n\n    def getSignalSegment(self, time_range):\n        signal = self.getSignal();\n        seg_start = int(time_range[0]*self.sampling_rate);\n        seg_end = int(time_range[1]*self.sampling_rate);\n        return signal[seg_start:seg_end];\n\n    def getFullSignal(self):\n        return self.x;\n\n    def getSampleAtTime(self, f):\n        prev_sample = self.x[int(math.floor(f))];\n        next_sample = self.x[int(math.ceil(f))];\n        sample_progress = f-np.floor(f);\n        return (next_sample*sample_progress)+(prev_sample*(1.0-sample_progress));\n\n    def getSampleAtIndex(self, i):\n        return self.x[i];\n\n    def getDuration(self):\n        return truediv(len(self.getSignal()), self.sampling_rate);\n\n    def setValueRange(self, value_range=None):\n        if(value_range is None):\n            value_range = [0,1];\n        data = self.x[:];\n        currentscale = np.max(data)-np.min(data);\n        data = (data/currentscale)*(value_range[1]-value_range[0]);\n        data = data-np.min(data)+value_range[0]\n        self.x = data;\n\n    def setMaxAbsValue(self, max_abs_val=1.0):\n        data = self.x[:];\n        currentscale = np.max(np.fabs(data));\n        data = (data/currentscale)*max_abs_val;\n        self.x = data;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VBMIDI.py",
    "content": "# %load VisBeat/MidiParse.py\nimport mido\nimport numpy as np\nimport os\n# from TimeSignal1D import *\nfrom .Audio import *\nfrom .Event import *\n\nclass VBMIDITrack(object):\n    def __init__(self, track, ticks_per_beat):\n        self.mido_track = track;\n        self.name = track.name;\n        # print('Track {}: {}'.format(i, track.name));\n        self.tempo = next((msg.tempo for msg in track if msg.type == 'set_tempo'), None);\n        self.ticks_per_beat = ticks_per_beat;\n        # self._get_note_on_times();\n        self.note_on_times = None;\n\n\n    def getBPM(self):\n        return mido.tempo2bpm(self.tempo);\n\n    def getNoteOnTimes(self, include_negative=None):\n        if(self.note_on_times is None or (include_negative)):\n            self._get_note_on_times(include_negative = include_negative);\n        return self.note_on_times;\n\n\n    def _get_note_on_times(self, include_negative = None):\n        \"\"\"\n        Gets the starting time of each note.\n        \"\"\"\n        note_times = []\n        current_time = 0;\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                if msg.type == 'note_on' and msg.velocity > 0:\n                    if (include_negative or current_time>=0):\n                        note_times.append(current_time);\n\n\n        self.note_on_times = np.array(note_times);\n\n\n    def get_note_durations(self, track_num):\n        note_durations = []\n        currently_played_notes = {}\n        current_time = 0\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                if msg.type == 'note_on' and msg.velocity > 0 and msg.note not in currently_played_notes:\n                    currently_played_notes[msg.note] = current_time\n                    #if len(currently_played_notes) > 1:\n                    #    print \"Number of played notes have reached: \", len(currently_played_notes)\n                elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0):\n                    duration = current_time - currently_played_notes[msg.note]\n                    note_durations.append((currently_played_notes[msg.note], duration))\n                    currently_played_notes.pop(msg.note)\n        assert not bool(currently_played_notes), \"Finished looping through all messages. There should not be any notes playing at this point.\"\n        #print \"before sorting: \", note_durations\n        note_durations.sort(key=lambda x : x[0])\n        #print \"after sorting: \", note_durations\n        return np.array([ x[1] for x in note_durations ])\n\n    def get_mouth_events(self):\n        # note_times = []\n        current_time = 0;\n        number_on = 0;\n        events = [];\n        open_buffer = 0.1;\n        close_buffer = 0.1\n        last_type = 0;\n        events.append(Event(start=0, type='mouth_close', weight=1));\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                last_time = events[-1].start;\n                passed = current_time-last_time;\n\n                if msg.type == 'note_on' and msg.velocity > 0:\n                    if(last_type==0):\n                        if(passed>open_buffer):\n                            events.append(Event(start=current_time-open_buffer, type='mouth_closed', weight=0));\n                    events.append(Event(start=current_time, type='mouth_open', weight = truediv(msg.velocity,127)));\n                    number_on = number_on + 1;\n                    last_type=1;\n                if(msg.type == 'note_off' or (msg.type=='note_on' and msg.velocity == 0)):\n                    if (last_type == 1):\n                        if (passed > close_buffer):\n                            events.append(Event(start=current_time - close_buffer, type='mouth_opened', weight=0));\n                    events.append(Event(start=current_time, type='mouth_close', weight = truediv(msg.velocity,127)));\n                    number_on = number_on-1;\n                    last_type=0;\n                    # assert(number_on>-1);\n                    # if(number_on==0):\n        return events;\n        # self.note_on_times = np.array(note_times);\n\n    def getNoteOnTimesAsAudio(self, sampling_rate = None, note_sound=None, n_seconds=None):\n        assert(n_seconds is not None), \"must provide n seconds\"\n        if(sampling_rate is None):\n            sampling_rate = 16000;\n        if(note_sound is None):\n            note_sound = Audio.getPing();\n        s = Audio.Silence(n_seconds=n_seconds, sampling_rate=sampling_rate, name=self.name)\n        s = s.getWithSoundAdded(note_sound, self.getNoteOnTimes());\n        return s;\n\n\n\nclass VBMIDI(TimeSignal1D):\n    def __init__(self, path=None):\n        TimeSignal1D.__init__(self, path=path);\n        self.midi_file = mido.MidiFile(path)\n        self.tracks = [];\n        for i, track in enumerate(self.midi_file.tracks):\n            self.tracks.append(VBMIDITrack(track, self.midi_file.ticks_per_beat));\n\n    def getNoteOnTimes(self, include_negative=None):\n        return self.tracks[-1].getNoteOnTimes(include_negative=include_negative);\n\n    def getMouthEvents(self):\n        return self.tracks[-1].get_mouth_events();\n\n    def getNoteOnTimesAsAudio(self, sampling_rate=None, note_sound=None):\n        s = self.tracks[-1].getNoteOnTimesAsAudio(sampling_rate = sampling_rate, note_sound = note_sound, n_seconds = self.midi_file.length);\n        if (s.name is None):\n            s.name = self.getInfo('file_name')\n        return s;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VBObject.py",
    "content": "import os\nimport json\nfrom .VisBeatImports import *\nfrom .AFuncDict import *\nfrom .AObject import AObject\n\nclass VBObject(AObject):\n    \"\"\"VBObject (class): This is a paarent class used to implement common serialization and other functions. There ends\n        up being three different dictionaries of data.\n        a_info - for small labels and such. Part of AObject.\n        a_data - for data to be computed in experiments. I generally use this for things I don't want to automatically\n                save out to file.\n        features - these are features tied to the results of functions, and manager classes (e.g. VideoSource) will save\n                these to disk for future use.\n\n        FEATURE_FUNCS is a dictionary mapping the names of features to their corresponding functions.\n    \"\"\"\n    FEATURE_FUNCS={};\n\n    def __init__(self, path=None):\n        AObject.__init__(self, path=path);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.a_info.update({'VBObjectType': self.VBOBJECT_TYPE()});\n        self.features = AFuncDict(owner=self, name='features');\n        self.features.functions.update(self.FEATURE_FUNCS);\n\n    def saveFeature(self, name, path):\n        \"\"\"Subclasses can implement version of this that will check members for features if those features arent found here.\"\"\"\n        return self.features.saveEntry(name=name, path=path);\n\n    def saveFeatures(self, path):\n        return self.features.save(path=path);\n\n    def loadFeature(self, name, path):\n        \"\"\"Subclasses can implement version of this that will check whether feature is registered before loading.\"\"\"\n        return self.features.loadEntry(name=name, path=path);\n\n    def loadFeatures(self, path):\n        return self.features.load(path=path);\n\n    def getFeature(self,name, force_recompute=False, **kwargs):\n        \"\"\"Understood to get the value of a feature. can automatically recompute if feature has registered function.\"\"\"\n        params = kwargs;\n        assert (not kwargs.get('params')), \"STILL TRYING TO USE PARAMS INSTEAD OF KWARGS. FIX THIS\";\n        return self.features.getValue(name=name, params=kwargs, force_recompute=force_recompute);\n\n    def getFeatureEntry(self, name, params=None, force_recompute=False):\n        return self.features.getEntry(name=name, params=params, force_recompute=force_recompute);\n\n    def getFeatureParams(self, name):\n        return self.features.getParams(name=name);\n\n    def setFeature(self, name, value, params=None):\n        rval = self.features.setEntry(name=name, d=dict(value=value, params=params));\n        self.features.setEntryModified(name=name, is_modified=True);\n        return rval;\n\n    def removeFeature(self, name, assert_if_absent=True, set_modified=True):\n        self.features.removeEntry(name=name, assert_if_absent=assert_if_absent, set_modified=set_modified);\n\n\n\n    def hasFeature(self, name):\n        \"\"\"Just checks to see if it's there.\"\"\"\n        return self.features.hasEntry(name=name);\n\n    def getFeatureFunction(self, feature_name):\n        return self.features.getFunction(name=feature_name);\n\n    def getFeaturesList(self):\n        return self.features.getKeyList();\n\n    def getFeatureFunctionsList(self):\n        return self.features.getFunctionList();\n\n    def clearFeatureFiles(self, features_to_clear=None, **kwargs):\n        if(self.clear_feature_files_func):\n            self.clear_feature_files_func(self, features_to_clear=features_to_clear, **kwargs);\n        else:\n            VBWARN(\"CLEAR FEATURE FILES FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.VBOBJECT_TYPE()));\n\n\n    ########### VIRTUAL FUNCTIONS #############\n\n    def AOBJECT_TYPE(self):\n        return 'VBObject';\n\n    def VBOBJECT_TYPE(self):\n        return self.AOBJECT_TYPE();\n\n\n    # ##Example of how these functions should be written ina  subclass, for 'AssetManager' class\n    # def VBOBJECT_TYPE(self):\n    #     return 'AssetManager';\n    #\n    # def toDictionary(self):\n    #     d = VBObject.toDictionary(self);\n    #     #serialize class specific members\n    #     return d;\n    #\n    # def initFromDictionary(self, d):\n    #     VBObject.initFromDictionary(self, d);\n    #     #do class specific inits with d;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Video.py",
    "content": "#VideoVersion#from VisBeatImports import *\nfrom .AObject import *\nfrom .TimeSignal import *\nfrom .Audio import *\nfrom .Warp import *\nfrom .Image import *\nimport moviepy.editor as mpy\nfrom moviepy.audio.AudioClip import AudioArrayClip as MPYAudioArrayClip\n\nimport sys\n\nimport math\nfrom operator import truediv\n\n\ndef MPYWriteVideoFile(mpyclip, filename, **kwargs):\n    temp_audio_filename = get_temp_file_path(final_file_path='TEMP_'+filename+'.m4a', temp_dir_path=Video.VIDEO_TEMP_DIR);\n    return mpyclip.write_videofile(filename=filename, temp_audiofile= temp_audio_filename, audio_codec='aac', **kwargs);\n\n\n\nclass Video(TimeSignal):\n    \"\"\"Video (class): A video, and a bunch of convenience functions to go with it.\n        Attributes:\n    \"\"\"\n\n    VIDEO_TEMP_DIR = './'\n    FEATURE_FUNCS = TimeSignal.FEATURE_FUNCS.copy();\n\n    def AOBJECT_TYPE(self):\n        return 'Video';\n\n    def __init__(self, path=None, name=None, num_frames_total=None):\n        TimeSignal.__init__(self, path=path);\n        if(name):\n            self.name = name;\n        if(path):\n            self.loadFile(num_frames_total=num_frames_total);\n\n    def initializeBlank(self):\n        TimeSignal.initializeBlank(self);#YES KEEP\n        self.name = None;\n        self.sampling_rate = None;\n        self.audio=None;\n        self.reader = None;\n        self.writer = None;\n        self.num_frames_total=None;\n        self.reshape=None;\n        self.meta_data = None;\n        self.sampling_rate = None;\n        self.source = None;\n\n        # _gui is not saved\n        self._gui = None;\n\n    def _getFrameRate(self):\n        return self.sampling_rate;\n\n    # _gui is from TimeSignal\n    # <editor-fold desc=\"Property: 'gui'\">\n    @property\n    def gui(self):\n        return self._getGui();\n\n    def _getGui(self):\n        return self._gui;\n\n    @gui.setter\n    def gui(self, value):\n        self._setGui(value);\n\n    def _setGui(self, value):\n        self._gui = value;\n    # </editor-fold>\n\n\n    def getVersionInfo(self):\n        \"\"\"This is the info to be saved in asset version dictionary\"\"\"\n        d={};\n        d['name']=self.name;\n        d['sampling_rate']=self.sampling_rate;\n        d['num_frames_total']=self.num_frames_total;\n        d['duration']=self.getDuration();\n        d['start_time']=self.getStartTime();\n        d['end_time']=self.getEndTime();\n        d['meta_data']=self.meta_data;\n        return d;\n\n    def getName(self):\n        if(self.name is None):\n            return self.getInfo('file_name');\n        else:\n            return self.name;\n\n    def getTempDir(self):\n        if(self.source is not None):\n            return self.source.getDir('temp');\n        else:\n            return Video.VIDEO_TEMP_DIR;\n\n    def getStringForHTMLStreamingBase64(self):\n        svideo = io.open(self.getPath(), 'r+b').read()\n        encoded = base64.b64encode(svideo)\n        return \"data:video/mp4;base64,{0}\".format(encoded.decode('ascii'));\n\n\n    def n_frames(self):\n        if(not self.num_frames_total):\n            self.num_frames_total = self.calcNumFramesTotal();\n        return self.num_frames_total;\n\n    def getDuration(self):\n        return truediv(self.n_frames(), self.sampling_rate);\n\n    def getStartTime(self):\n        return 0;\n\n    def getEndTime(self):\n        return self.getDuration();\n\n    def getMPYClip(self, get_audio=True):\n        return mpy.VideoFileClip(self.getPath(), audio=get_audio);\n\n    def getAudio(self):\n        return self.audio;\n\n    def loadFile(self, file_path=None, num_frames_total=None):\n        if (file_path):\n            self.setPath(file_path=file_path);\n        if ('file_path' in self.a_info):\n            self.reader = imageio.get_reader(self.a_info['file_path'], 'ffmpeg');\n            self.meta_data = self.reader.get_meta_data();\n            self.sampling_rate = self.meta_data['fps'];\n            if (num_frames_total is not None):\n                self.num_frames_total = num_frames_total;\n            else:\n                self.num_frames_total = self.calcNumFramesTotal();\n\n            try:\n                self.audio = Audio(self.a_info['file_path']);\n                self.audio.name =self.name;\n            #except RuntimeError:\n            except Exception:\n                print((\"Issue loading audio for {}\".format(self.a_info['file_path'].encode('utf-8'))));\n                self.audio = Audio(sampling_rate=16000);\n                self.audio.x = np.zeros(int(np.ceil(self.audio.sampling_rate*self.getDuration())));\n\n    def openVideoWriter(self, output_file_path, fps=None):\n        if('outputs' not in self.a_info):\n            self.a_info['outputs'] = [];\n        out_fps = fps;\n        if(not out_fps):\n            out_fps=self.sampling_rate;\n        make_sure_dir_exists(output_file_path);\n        self.writer = imageio.get_writer(output_file_path, 'ffmpeg', macro_block_size = None, fps = out_fps);\n        self.a_info['outputs'].append(output_file_path);\n\n    def closeVideoWriter(self):\n        self.writer.close();\n        self.writer = None;\n\n    def getFrameShape(self):\n        fs=self.getInfo('frame_shape');\n        if(fs is not None):\n            return fs;\n        else:\n            self.setInfo(label='frame_shape', value=self.reader.get_data(0).shape);\n            return self.getInfo('frame_shape');\n\n    def calcNumFramesTotal(self):\n        #assert(False)\n        print((\"Calculating frames for {}...\".format(self.name)))\n        valid_frames = 0\n        example_frame = self.reader.get_data(0);\n        self.setInfo(label='frame_shape',value=example_frame.shape);\n        \n        # https://stackoverflow.com/questions/54778001/how-to-to-tackle-overflowerror-cannot-convert-float-infinity-to-integer\n        #for i in range(1, self.reader.get_length()):\n        for i in range(1, self.reader.count_frames()):\n            try:\n                self.reader.get_data(i);\n            except imageio.core.format.CannotReadFrameError as e:\n                break\n            valid_frames += 1\n        print(\"Done.\")\n        return valid_frames\n\n    def readFrameBasic(self, i):\n        \"\"\"You should basically never call this\"\"\"\n        fi=i;\n        if(fi<0):\n            fi=0;\n        if(fi>(self.num_frames_total-1)):\n            fi=(self.num_frames_total-1);\n        return np.asarray(self.reader.get_data(int(fi)));\n\n    def getFrame(self, f):\n        return self.readFrameBasic(round(f));\n\n    def getFrameFromTime(self, t):\n        f = t*self.sampling_rate;\n        return self.getFrame(f=f);\n\n    def getFrameLinearInterp(self, f):\n        if(isinstance(f,int) or f.is_integer()):\n            return self.readFrameBasic(int(f));\n        prev_frame = self.readFrameBasic(math.floor(f));\n        next_frame = self.readFrameBasic(math.ceil(f));\n        frame_progress = f-np.floor(f);\n        rframe =  (next_frame*frame_progress)+(prev_frame*(1.0-frame_progress));\n        return rframe.astype(prev_frame.dtype);\n\n    def writeFrame(self, img):\n        if self.writer.closed:\n            print('ERROR: Vid writer object is closed.')\n        else:\n            self.writer.append_data(img.astype(np.uint8))\n\n    def play(self):\n        if(ISNOTEBOOK):\n            print(\"Playing video:\")\n            video = io.open(self.getPath(), 'r+b').read()\n            encoded = base64.b64encode(video)\n            vidhtml=HTML(data='''<video alt=\"test\" controls>\n                <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" />\n             </video>'''.format(encoded.decode('ascii')));\n            IPython.display.display(vidhtml);\n            # return vidhtml;\n        else:\n             print(\"HOW TO PLAY VIDEO? NOT A NOTEBOOK.\")\n\n    def show(self):\n        self.play();\n\n    def write(self, output_path, output_sampling_rate=None):\n        assert output_path, \"MUST PROVIDE OUTPUT PATH FOR VIDEO\"\n\n        sampling_rate = output_sampling_rate;\n        if(not sampling_rate):\n            sampling_rate=self.sampling_rate;\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=self.getTempDir());\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate);\n\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,self.sampling_rate);\n        frame_start_times = np.linspace(0,self.getDuration(),num=nsamples,endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        for nf in range(len(frame_index_floats)):\n            self.writeFrame(self.getFrame(frame_index_floats[nf]));\n            fcounter+=1;\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n\n\n        self.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=self.audio, output_path=output_path);\n        os.remove(tempfilepath);\n        return rvid;\n\n    def VideoClip(self, start=None, end=None, name=None):\n        from . import VideoClip\n        if(start is None):\n            start = 0;\n        if(end is None):\n            end = self.getDuration();\n        clip = VideoClip.VideoClip(video=self, start=start, end=end);\n        if(name):\n            clip.name=name;\n        return clip;\n\n    def getImageFromFrame(self, i):\n        rimage = Image(data=self.getFrame(i));\n        rimage.setInfo(label='parent_video', value=self.getInfo('file_path'));\n        rimage.setInfo(label='frame_number',value=i);\n        return rimage;\n\n    def getImageFromTime(self, t):\n        rimage = Image(data=self.getFrameFromTime(t));\n        rimage.setInfo(label='parent_video', value=self.getInfo('file_path'));\n        rimage.setInfo(label='frame_time', value=t);\n        return rimage;\n\n\n    # def getFrameShape(self):\n    #     return self.getImageFromFrame(0).getShape();\n\n    def writeResolutionCopyFFMPEG(self, path, max_height=None):\n        if(max_height is None):\n            max_height=self.getFrameShape()[0];\n        mpc = self.getMPYClip();\n        clip_resized = mpc.resize(height=max_height); # make the height 360px ( According to moviePy documenation The width is then computed so that the width/height ratio is conserved.)\n        if((clip_resized.size[0]%2)>0):\n            clip_resized=clip_resized.crop(x1=0,width=clip_resized.size[0]-1);\n\n        # clip_resized.write_videofile(path);\n        MPYWriteVideoFile(clip_resized, path);\n\n        rvid = Video(path);\n        return rvid;\n\n    def writeFFMPEG(self, output_path):\n        mpc = self.getMPYClip();\n        # mpc.write_videofile(output_path, preset='fast', codec='mpeg4');\n        MPYWriteVideoFile(mpc, output_path, preset='fast', codec='mpeg4')\n        rvid = Video(output_path);\n        return rvid;\n\n    def writeResolutionCopy(self, path, max_height=None, reshape=None, input_sampling_rate_factor = None, output_sampling_rate=None):\n        print((self.getPath()))\n        if(input_sampling_rate_factor is not None):\n            original_sampling_rate = self.sampling_rate;\n            self.sampling_rate=input_sampling_rate_factor*self.sampling_rate;\n            original_audio_sampling_rate = self.audio.sampling_rate;\n            self.audio.sampling_rate=self.audio.sampling_rate*input_sampling_rate_factor;\n        output_path = path;\n        inshape = self.getFrameShape();\n        if(reshape==True):\n            imshape = [inshape[1],inshape[0],inshape[2]];\n        outshape = None;\n        if(max_height and (max_height<inshape[0])):\n            outshape = self.getFrameShape();\n            out_w_over_height = truediv(inshape[1],inshape[0]);\n            outshape[0]=(max_height);\n            outshape[1]=max_height*out_w_over_height;\n            if((math.floor(outshape[1])%2)==0):\n                outshape[1]=math.floor(outshape[1])\n            elif((math.ceil(outshape[1])%2)==0):\n                outshape[1]=math.ceil(outshape[1])\n            if((outshape[1]%2)!=0):\n                outshape[1]=outshape[1]-1;\n        sampling_rate = output_sampling_rate;\n        if(not sampling_rate):\n            sampling_rate=self.sampling_rate;\n\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=self.getTempDir());\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate);\n\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,self.sampling_rate);\n        frame_start_times = np.linspace(0,self.getDuration(),num=nsamples,endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        for nf in range(len(frame_index_floats)):\n            fim = self.getImageFromFrame(frame_index_floats[nf]);\n            if(reshape==True):\n                fim.data = np.reshape(fim.data, (fim.data.shape[1],fim.data.shape[0],fim.data.shape[2]));\n            if(outshape is not None):\n                fim = fim.getScaled(shape=outshape);\n            self.writeFrame(fim.data);\n\n            fcounter+=1;\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n        self.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=self.audio, output_path=output_path);\n        os.remove(tempfilepath);\n        if(input_sampling_rate_factor is not None):\n            #return original_sampling_rate\n            self.sampling_rate=original_sampling_rate;\n            self.audio.sampling_rate = original_audio_sampling_rate;\n        return rvid;\n\n    def writeWarped(self, output_path, warp, output_sampling_rate=None, output_audio=None, bitrate=None, vbmark = True, max_time = None, **kwargs):\n        sampling_rate = output_sampling_rate;\n        if (not sampling_rate):\n            sampling_rate = self.sampling_rate;\n\n        duration = self.getDuration();\n        old_frame_time = truediv(1.0, self.sampling_rate);\n\n        target_start = warp.getTargetStart();\n        target_end = warp.getTargetEnd();\n\n        target_duration = target_end - target_start;\n\n        if(max_time is not None and target_duration>max_time):\n            target_duration = max_time;\n            target_end = target_start+max_time;\n\n        print((\n            \"target start: {}\\ntarget end: {}\\ntarget duration: {}\".format(target_start, target_end, target_duration)));\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=False);\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(warp.warpTargetTime(st));\n        frame_index_floats = np.true_divide(np.array(unwarped_target_times), old_frame_time);\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=Video.VIDEO_TEMP_DIR);\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate, **kwargs);\n        start_timer = time.time();\n        last_timer = start_timer;\n        fcounter = 0;\n        if(vbmark):\n            vbmarker = self.getImageFromFrame(0)._vbmarker();\n\n        for nf in range(len(frame_index_floats)):\n            try:\n                nwfr = self.getFrame(frame_index_floats[nf]);\n                if(vbmark):\n                    nwfrm = Image(data=nwfr);\n                    nwfrm._splatAtPixCoord(**vbmarker);\n                    nwfr = nwfrm._pixels_uint;\n                self.writeFrame(nwfr);\n            except ValueError:\n                print((\"VALUE ERROR ON WRITEFRAME {}\".format(frame_index_floats[nf])));\n                self.writeFrame(self.getFrame(math.floor(frame_index_floats[nf])));\n            fcounter += 1;\n            if (not (fcounter % 50)):\n                if ((time.time() - last_timer) > 10):\n                    last_timer = time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0 * truediv(fcounter, len(frame_index_floats)),\n                                                                 last_timer - start_timer)));\n        self.closeVideoWriter();\n\n        silent_warped_vid = Video(tempfilepath);\n        if (not output_audio):\n            output_audio = self.getAudio();\n\n        cropped_output_audio = output_audio.AudioClip(start=target_start, end=target_end);\n\n        if ((self.getInfo('max_height') is None) and (bitrate is None)):\n            use_bitrate = \"20000k\";\n            print(('Using bitrate of {}'.format(use_bitrate)));\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path, bitrate=use_bitrate);\n        elif (bitrate is 'regular'):\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path);\n        else:\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path, bitrate=bitrate);\n\n        os.remove(tempfilepath);\n        rvid.setInfo(label='warp_used', value=warp);\n        return rvid;\n\n\n\n    def getVersionLabel(self):\n        return self.getInfo('version_label');\n\n    def getWarpsDir(self):\n        if(self.source is None):\n            return self.getTempDir();\n        version_label = self.getVersionLabel()\n        return self.source.getWarpsDir(version_label=version_label);\n\n    def getWithBeginningCroppedToAudio(self, target):\n        if(isinstance(target, Audio)):\n            B=target;\n        else:\n            B=target.getAudio();\n\n        A = self.getAudio();\n\n        AB = A.getShiftAmountTo(B);\n        BA = B.getShiftAmountTo(A);\n\n        if(AB<BA):\n            return self.VideoClip(name=self.name+'clipped_to_'+B.name);\n        else:\n            return self.VideoClip(start=BA, end=None, name=self.name+'clipped_to_'+B.name);\n\n    def getWarped(self, target,\n                  source_events=None, target_events=None,\n                  warp_type=None,\n                  max_time = None,\n                  source_time_range = None, target_time_range=None,\n                  output_sampling_rate=None, output_path=None,\n                  force_recompute=None, name_tag = None, vbmark = True, **kwargs):\n        \"\"\"\n\n        :param target_audio:\n        :param source_eventlist:\n        :param target_eventlist:\n        :param warp_type:\n        :param source_time_range:\n        :param target_time_range:\n        :param output_sampling_rate:\n        :param output_path:\n        :param force_recompute:\n        :param name_tag:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n\n        if(isinstance(target, Video)):\n            target_audio = target.audio;\n        else:\n            target_audio = target;\n\n        if(source_events is None):\n            source_events = self.audio.getBeatEvents();\n        if(target_events is None):\n            target_events = target_audio.getBeatEvents();\n\n        warp = Warp.FromEvents(source_events, target_events);\n\n        if(warp_type is None):\n            warp_type = 'quad';\n        warp.setWarpFunc(warp_type, **kwargs);\n\n        if(output_sampling_rate is None):\n            output_sampling_rate = self.sampling_rate;\n\n        if(hasattr(target, 'name')):\n            warpname=self.name+'_TO_'+target.name;\n        else:\n            warpname = self.name+ '_TO_TARGETAUDIO' + '_' + str(target.getInfo('name'));\n\n        if(name_tag is not None):\n            warpname = warpname+name_tag;\n\n        warpname = warpname+'.mp4';\n\n        if(output_path is None):\n            output_path = self.getWarpsDir()+os.sep+warpname;\n            make_sure_dir_exists(output_path);\n\n        if(not os.path.isfile(output_path) or force_recompute):\n            rvid = self.writeWarped(output_path=output_path, warp=warp, output_sampling_rate=output_sampling_rate, output_audio=target_audio, vbmark = vbmark, max_time = max_time);\n        else:\n            rvid = Video(path=output_path, name=warpname);\n        rvid.setFeature(name='warp_used', value=warp);\n        return rvid;\n\n\n    def getWithSoundsOnEvents(self, events, output_path=None, name_tag = None, mute_original=True,\n                              event_sound=None, force_recompute=None, **kwargs):\n        \"\"\"\n\n        :param events: Can be EventList, a list of events, or a list of numbers representing the times of the events.\n        :param output_path: if None, will try to get from Video.source\n        :param name_tag: what to label this output with in its name.\n        :param mute_original: whether to leave the original sound from the video in the output.\n        :param event_sound: Sound to play at each event.\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        assert(events is not None), 'must provide events or list of times to put sounds'\n\n        output_name = self.getName()+'_eventsounds';\n        if (name_tag):\n            output_name = output_name + '_' + name_tag;\n        if(output_path is None):\n            if(self.source is not None):\n                output_dir = self.source.getDirForVersion(version_label=self.getInfo('version_label'), version_group='sound_on_events');\n            else:\n                output_dir = self.getTempDir();\n            output_path=os.path.join(output_dir, output_name+'.mp4');\n            make_sure_dir_exists(output_dir);\n        if(not os.path.isfile(output_path) or force_recompute):\n            if(isinstance(events, EventList)):\n                etimes = events.toStartTimes();\n            elif(isinstance(events[0], Event)):\n                etimes = Event.ToStartTimes(events);\n            else:\n                etimes = events;\n            new_audio = self.getAudio().getWithSoundAdded(sound=event_sound, add_times=etimes,\n                                                          mute_original=mute_original, **kwargs);\n            audio_sig = new_audio.getSignal();\n            reshapex = audio_sig.reshape(len(audio_sig), 1);\n            reshapex = np.concatenate((reshapex, reshapex), axis=1);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=new_audio.sampling_rate);  # from a numeric arra\n            video_clip = self.getMPYClip();\n            video_clip = video_clip.set_audio(audio_clip);\n            # video_clip.write_videofile(output_path, codec='libx264', write_logfile=False);\n            MPYWriteVideoFile(video_clip, output_path, codec='libx264', write_logfile=False);\n\n        rvid = Video(path=output_path, name=output_name);\n        return rvid;\n\n\n    @staticmethod\n    def CreateFromVideoAndAudio(video_path=None, audio_path=None, video_object=None, audio_object=None,\n                                output_path=None, clip_to_video_length=True, return_vid=True, codec='libx264',\n                                bitrate=None, **kwargs):\n        assert (not (video_path and video_object)), \"provided both video path and object to CreateFromVideoAndAudio\"\n        assert (not (audio_path and audio_object)), \"provided both audio path and object to CreateFromVideoAndAudio\"\n        assert (output_path), \"Must provide output path for CreateFromVideoAndAudio\"\n\n        if (video_path):\n            video_object = Video(video_path);\n        if (audio_path):\n            audio_object = Audio(path=audio_path);\n\n        output_path = output_path.encode(sys.getfilesystemencoding()).strip();\n        make_sure_dir_exists(output_path);\n\n        # audio_sig = audio_object.getSignal();\n        audio_sig = audio_object.getStereo();\n        audio_sampling_rate = audio_object.getStereoSamplingRate();\n        is_stereo = True;\n\n        if (audio_sig is None):\n            is_stereo = False;\n            audio_sig = audio_object.getSignal();\n            audio_sampling_rate = audio_object.sampling_rate;\n            n_audio_samples_sig = len(audio_sig);\n        else:\n            n_audio_samples_sig = audio_sig.shape[1];\n\n        print((\"stereo is {}\".format(is_stereo)));\n\n        audio_duration = audio_object.getDuration();\n        video_duration = video_object.getDuration();\n\n        if (clip_to_video_length):\n            n_audio_samples_in_vid = int(math.ceil(video_duration * audio_sampling_rate));\n\n            if (n_audio_samples_in_vid < n_audio_samples_sig):\n                if (is_stereo):\n                    audio_sig = audio_sig[:, :int(n_audio_samples_in_vid)];\n                else:\n                    audio_sig = audio_sig[:int(n_audio_samples_in_vid)];\n            else:\n                if (n_audio_samples_in_vid > n_audio_samples_sig):\n                    nreps = math.ceil(truediv(n_audio_samples_in_vid, n_audio_samples_sig));\n                    if (is_stereo):\n                        audio_sig = np.concatenate(\n                            (audio_sig, np.zeros((2, n_audio_samples_in_vid - n_audio_samples_sig))),\n                            axis=1);\n                    else:\n                        audio_sig = np.tile(audio_sig, (int(nreps)));\n                        audio_sig = audio_sig[:int(n_audio_samples_in_vid)];\n\n        if (is_stereo):\n            # reshapex = np.reshape(audio_sig, (audio_sig.shape[1], audio_sig.shape[0]), order='F');\n            reshapex = np.transpose(audio_sig);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=audio_sampling_rate);  # from a numeric arra\n        else:\n            reshapex = audio_sig.reshape(len(audio_sig), 1);\n            reshapex = np.concatenate((reshapex, reshapex), axis=1);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=audio_sampling_rate);  # from a numeric arra\n\n        video_clip = video_object.getMPYClip();\n        video_clip = video_clip.set_audio(audio_clip);\n        # video_clip.write_videofile(output_path,codec='libx264', write_logfile=False);\n        if (bitrate is None):\n            # video_clip.write_videofile(output_path, codec=codec, write_logfile=False);\n            MPYWriteVideoFile(video_clip, output_path, codec=codec, write_logfile=False);\n        else:\n            MPYWriteVideoFile(video_clip, output_path, codec=codec, write_logfile=False, bitrate=bitrate);\n            # video_clip.write_videofile(output_path, codec=codec, write_logfile=False, bitrate=bitrate);\n        if (return_vid):\n            return Video(output_path);\n        else:\n            return True;\n\n    @staticmethod\n    def CreateByStackingVideos(video_objects=None, video_paths=None, output_path=None, audio = None, concatdim = 0, force_recompute=True, **kwargs):\n        assert output_path, \"MUST PROVIDE OUTPUT PATH FOR VIDEO\"\n        if(not force_recompute):\n            if(os.path.isfile(output_path)):\n                return Video(path=output_path);\n        matchdim = (concatdim+1)%2;\n        vids=[];\n        if(video_objects is not None):\n            vids=video_objects;\n\n        if(video_paths is not None):\n            for vp in video_paths:\n                vids.append(Video(path=video_paths));\n\n        output_path=output_path.encode(sys.getfilesystemencoding()).strip();\n        make_sure_dir_exists(output_path);\n        basevid = vids[0];\n        if(audio is None):\n            audio = basevid.audio;\n        sampling_rate = basevid.sampling_rate;\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=vids[0].getTempDir());\n        basevid.openVideoWriter(output_file_path=tempfilepath, fps=sampling_rate);\n        duration = basevid.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,sampling_rate);\n        #frame_start_times = np.linspace(self.getStartTime(),self.getEndTime(),num=nsamples,endpoint=False);\n        frame_start_times = np.linspace(0,duration,num=nsamples,endpoint=False);\n        #frame_index_floats = frame_start_times/old_frame_time;\n        frame_index_floats = frame_start_times*sampling_rate;\n        for nf in range(len(frame_index_floats)):\n            frameind = frame_index_floats[nf];\n            newframe = basevid.getFrame(frameind);\n            for vn in range(1,len(vids)):\n                addpart = vids[vn].getFrame(frameind);\n                partsize = np.asarray(addpart.shape)[:];\n                cumulsize = np.asarray(newframe.shape)[:];\n                if(partsize[matchdim]!=cumulsize[matchdim]):\n                    sz = partsize[:];\n                    sz[matchdim]=cumulsize[matchdim];\n                    addpart = sp.misc.imresize(addpart, size=sz);\n                newframe = np.concatenate((newframe, addpart), concatdim);\n            basevid.writeFrame(newframe);\n        basevid.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=audio, output_path=output_path, **kwargs);\n        os.remove(tempfilepath);\n        return rvid;\n\n    @staticmethod\n    def CreateFromVideoAndAudioPaths(video_path, audio_path, output_path, return_vid = True, **kwargs):\n        return Video.CreateFromVideoAndAudio(video_path=video_path, audio_path=audio_path, output_path=output_path,return_vid=return_vid, **kwargs);\n\n    @staticmethod\n    def CreateFromVideoAndAudioObjects(video, audio, output_path, clip_to_video_length=True, return_vid = True, **kwargs):\n        return Video.CreateFromVideoAndAudio(video_object=video, audio_object=audio, output_path=output_path, clip_to_video_length=clip_to_video_length, return_vid = return_vid, **kwargs);\n\n\n    def _getDefaultPeakPickingTimeParams(self, **kwargs):\n        single_frame = np.true_divide(1.0, self._getFrameRate());\n        time_params = dict(\n            pre_max_time=2.0 * single_frame,\n            post_max_time=2.0 * single_frame,\n            pre_avg_time=5.0 * single_frame,\n            post_avg_time=5.0 * single_frame,\n            wait_time=2.0 * single_frame,\n            delta=0.015,\n        )\n        time_params.update(kwargs);\n        return time_params;\n\n#   ###################\n\n    # FEATURE\n    def getFrameIndexes(self, force_recompute=False):\n        feature_name = 'frame_indexes';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = dict();\n            duration = self.getDuration();\n            nsamples = self.sampling_rate * duration;\n            frame_start_times = np.linspace(0, duration, num=nsamples, endpoint=False);\n            value = frame_start_times * self.sampling_rate;\n            self.setFeature(name=feature_name, value=value, params=params);\n        return self.getFeature(feature_name);\n\n\n    def getFeaturesList(self):\n        return super(Video, self).getFeaturesList()+self.audio.getFeaturesList();\n\n    def getVideoFeaturesList(self):\n        return super(Video, self).getFeaturesList();\n\n    def getFeatureFunctionsList(self):\n        return super(Video, self).getFeatureFunctionsList()+self.audio.getFeatureFunctionsList();\n\n    def getFeatureSourceType(self, name):\n        \"\"\"returns whether video or audio feature, instead of parent version which returns true or false\"\"\"\n        vidhas = super(Video, self).hasFeature(name=name);\n        if(vidhas):\n            return 'video';\n        audiohas = self.audio.hasFeature(name=name);\n        if(audiohas):\n            return 'audio';\n        return None;\n\n    def getFeature(self, name, force_recompute=False, **kwargs):\n        \"\"\"Returns None if feature is not already computed, and feature name is not implemented and registered with FEATURE_FUNCS\"\"\"\n        params = kwargs;\n        assert(not kwargs.get('params')), \"STILL TRYING TO USE PARAMS INSTEAD OF KWARGS. FIX THIS\";\n        ftry = super(Video, self).getFeature(name=name, force_recompute=force_recompute, **kwargs);\n        if(ftry is not None):\n            return ftry;\n        else:\n            return self.audio.getFeature(name=name, force_recompute=force_recompute, **kwargs);\n\n\nVideo.FEATURE_FUNCS['frame_indexes']=Video.getFrameIndexes;\nfrom . import Video_CV;\nif(Video_CV.USING_OPENCV):\n    Video.FEATURE_FUNCS.update(Video_CV.FEATURE_FUNCS);\n    Video.USING_OPENCV = Video_CV.USING_OPENCV;\n\n    Video.localRhythmicSaliencyFunction = Video_CV.localRhythmicSaliencyFunction\n    Video.visualBeatFunction = Video_CV.visualBeatFunction\n\n    Video.cvGetGrayFrame = Video_CV.cvGetGrayFrame;\n    Video.getImageFromFrameGray = Video_CV.getImageFromFrameGray;\n    Video.plotVisualBeats = Video_CV.plotVisualBeats;\n    Video.loadFlowFeatures = Video_CV.loadFlowFeatures;\n\n    Video.getVisualBeats = Video_CV.getVisualBeats\n    Video.getLocalRhythmicSaliency = Video_CV.getLocalRhythmicSaliency;\n    Video.getDirectogram = Video_CV.getDirectogram;\n    Video.getDirectogramPowers = Video_CV.getDirectogramPowers;\n    Video.getVisibleImpactEnvelope = Video_CV.getVisibleImpactEnvelope;\n    Video.getVisibleImpactEnvelopePowers = Video_CV.getVisibleImpactEnvelopePowers;\n    Video.getVisibleImpacts = Video_CV.getVisibleImpacts;\n    Video.getVisualBeats = Video_CV.getVisualBeats;\n    # Video.getBackwardVisualBeats = Video_CV.getBackwardVisualBeats;\n    # Video.getForwardVisualBeats = Video_CV.getForwardVisualBeats;\n    Video.getBackwardVisibleImpactEnvelope = Video_CV.getBackwardVisibleImpactEnvelope;\n    Video.getBothWayVisibleImpactEnvelope = Video_CV.getBothWayVisibleImpactEnvelope;\n    Video.getForwardVisibleImpactEnvelope = Video_CV.getForwardVisibleImpactEnvelope;\n    Video.getDirectionalFlux = Video_CV.getDirectionalFlux;\n    Video.getVisualTempogram = Video_CV.getVisualTempogram;\n    Video.getCutEvents = Video_CV.getCutEvents;\n    Video.computeImpactEnvelope = Video_CV.computeImpactEnvelope;\n    Video.computeDirectogramPowers = Video_CV.computeDirectogramPowers;\n    Video.visualBeatsFromEvents = Video_CV.visualBeatsFromEvents;\n    Video.plotVisualBeats = Video_CV.plotVisualBeats;\n    Video.plotImpactEnvelope = Video_CV.plotImpactEnvelope;\n    Video.plotVisibleImpacts = Video_CV.plotVisibleImpacts;\n    Video.getVisualBeatSequences = Video_CV.getVisualBeatSequences;\n    Video.printVisualBeatSequences = Video_CV.printVisualBeatSequences;\n    Video.getVisualBeatTimes = Video_CV.getVisualBeatTimes;\n    Video.findAccidentalDanceSequences = Video_CV.findAccidentalDanceSequences;\n    Video.plotEvents = Video_CV.plotEvents;\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n\nelse:\n    AWARN(\"Was not able to add functions that use OpenCV! Check OpenCV instalation and try again?\");\n\nfrom .vbgui import BeatGUI\nif(BeatGUI.VIEWER_INSTALLED):\n    def getEvents(self, **kwargs):\n        time_params = self._getDefaultPeakPickingTimeParams();\n        time_params.update(kwargs)\n        vbeats = self.getFeature('visual_beats', force_recompute=True, **time_params);\n        return vbeats;\n    def getEventList(self, **kwargs):\n        events = self.getEvents(**kwargs);\n        return EventList(events=events);\n    def runBeatGUIOnAudio(self):\n        audio = self.getAudio();\n        self.gui.run(local_saliency=audio.getLocalRhythmicSaliency(), frame_rate = audio._getFrameRate(), eventlist = audio.getEventList());\n\n\n    def runGUI(self, local_saliency=None, frame_rate = None, eventlist = 'default', frame_offset=None):\n        self.gui.run(local_saliency=local_saliency, frame_rate=frame_rate, eventlist=eventlist, frame_offset=frame_offset);\n\n    Video._getGui = BeatGUI.media_GUI_func;\n    Video.runGUI = runGUI;\n    Video.getEvents = getEvents;\n    Video.getEventList = getEventList;\n    Video.runBeatGUIOnAudio = runBeatGUIOnAudio;\n\nelse:\n    AWARN(\"BeatGUI not installed\");"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VideoClip.py",
    "content": "\nfrom .Video import *\nfrom .AudioClip import *\n\nclass VideoClip(Video):\n    \"\"\"VideoClip (class): A segment of a video, and a bunch of convenience functions to go with it.\n        Attributes:\n            start: The name of the video\n            end: The framerate of the video\n    \"\"\"\n\n    def AOBJECT_TYPE(self):\n        return 'VideoClip';\n\n    def __init__(self, video=None, start=None, end=None, clip_to_frame=True, path=None):\n        \"\"\"If a video is provided, we don't want to reload the video from disk. If a path is provided, we have no choice.\n        \"\"\"\n        assert(not (video and path)), \"provided both video object and path to VideoClip constructor.\"\n        assert((start is not None) and (end is not None)), \"must provide start time and end time to AudioClip constructor\"\n        Video.__init__(self, path = path);\n        self.initializeBlank();\n        self.start = start;\n        self.end = end;\n\n        if(video):\n            self.setPath(video.getPath());\n            self.reader = video.reader;\n            #self.writer = None; #this only comes up if we write later\n            self.sampling_rate=video.sampling_rate;\n            self.num_frames_total=video.num_frames_total;\n            time_per_frame=truediv(1.0,self.sampling_rate);\n            if(clip_to_frame):\n                self.start=time_per_frame*math.floor(truediv(self.start,time_per_frame));\n                self.end=time_per_frame*math.floor(truediv(self.end,time_per_frame));\n            if(video.name):\n                self.name = video.name+\"_{}_{}\".format(start,end);\n            self.audio = video.audio.AudioClip(start=start, end=end);\n        else:\n            assert(False),\"must provide video to VideoClip init\"\n\n    def initializeBlank(self):\n        Video.initializeBlank(self);\n        self.start = None;\n        self.end = None;\n\n\n    # def readFrameBasic(self, i):\n    #     return Video.getFrame(self, float(i)+self.start);\n\n    def getFrameLinearInterp(self, f):\n        return Video.getFrameLinearInterp(self, float(f)+self.start*self.sampling_rate);\n\n    def getFrame(self, f):\n        return Video.getFrame(self, float(f)+self.start*self.sampling_rate);\n\n    def getDuration(self, round_to_frames=False):\n        if(not round_to_frames):\n            return self.end-self.start;\n        else:\n            return truediv(self.n_frames(), self.sampling_rate);\n\n    def n_frames(self):\n        #return self.getLastFrameIndex()-self.getFirstFrameIndex();\n        return math.ceil((self.end-self.start)*self.sampling_rate);\n\n    # def getFirstFrameIndex(self):\n    #     return math.floor(self.start*self.sampling_rate);\n    #\n    # def getLastFrameIndex(self):\n    #     #I think floor is still right here, because the times mark beginnings of frames\n    #     return math.floor(self.end*self.sampling_rate);\n\n    def getStartTime(self):\n        return self.start;\n\n    def getEndTime(self):\n        return self.end;\n\n    def getMPYClip(self, get_audio=True):\n        return mpy.VideoFileClip(self.getPath(), audio=get_audio).subclip(self.getStartTime(), self.getEndTime());\n\n    def play(self):\n        if(ISNOTEBOOK):\n            print(\"Playing video:\")\n            IPython.display.display(self.getMPYClip().ipython_display(fps=self.sampling_rate, maxduration=self.getDuration()+1));\n        else:\n             print(\"HOW TO PLAY VIDEO? NOT A NOTEBOOK.\")\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VideoSource.py",
    "content": "from .VisBeatImports import *\nfrom .Video import *\nfrom .AFileManager import AFileManager\n\ntry:\n    import youtube_dl\nexcept ImportError:\n    AWARN('You need to install youtube-dl to use parts of VideoSource class that pull from YouTube. Try running:\\npip install youtube-dl')\n\n\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\nclass VideoSource(AFileManager):\n    \"\"\"Video (class): A video, and a bunch of convenience functions to go with it.\n        Attributes:\n            name: The name of the video\n            sampling_rate: The framerate of the video\n            audio: an Audio object, the audio for the video\n    \"\"\"\n\n    VIDEO_TEMP_DIR = './'\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n    def AOBJECT_TYPE(self):\n        return 'VideoSource';\n\n    def __init__(self, path, name=None, source_location=None, VideoClass = None, **kwargs):\n        \"\"\"\n        :param path: either the path to a json, or the path to a directory containing 'VideoSource.json',\n            or the path to a directory where said json should be created.\n        :param name: name for video\n        :param source_location: can be a path to a video file, or a youtube source from which to pull a video file\n        :param VideoClass: visbeat.Video by default, but can be changed if you are using a custom subclass.\n               Must be a subclass of visbeat.Video, and must be constructable with VideoClass(path)\n        \"\"\"\n        AFileManager.__init__(self, path=path);\n\n        if(VideoClass is not None):\n            self.VideoClass = VideoClass;\n\n        self.setSource(source_location=source_location, assert_valid=None, **kwargs);\n\n        # if (self.name is None):\n            # self.name = os.path.splitext(os.path.basename(path))[0]\n\n\n    @staticmethod\n    def NewVideoSource(destination, name, source_location=None, VideoClass = None, **kwargs):\n        vsdir = os.path.join(destination, name+os.sep);\n        make_sure_dir_exists(vsdir);\n        print((\"Video source at {}\".format(vsdir)));\n        return VideoSource(path=vsdir, name=name, source_location=source_location, **kwargs);\n\n    def initializeBlank(self):\n        AFileManager.initializeBlank(self);\n        self.source_location = None;\n        self.name = None;\n        self.video_file_name = None;\n        self.title_safe = None;\n        self.youtube_info_dict = None;\n        self.versions_info = {};\n\n        #\n        self.VideoClass = Video;\n\n    def toDictionary(self):\n        d = AFileManager.toDictionary(self);\n        d['source_location']=self.source_location;\n        if(self.name):\n            d['name']=self.name;\n        if(self.video_file_name):\n            d['video_file_name']=self.video_file_name;\n        if(self.title_safe):\n            d['title_safe']=self.title_safe;\n        if(self.youtube_info_dict):\n            d['youtube_info_dict']=self.youtube_info_dict;\n        if(self.versions_info):\n            d['versions_info']=self.versions_info;\n        return d;\n\n\n    def initFromDictionary(self, d):\n        AFileManager.initFromDictionary(self, d);\n        self.source_location = d['source_location'];\n        self.name = d.get('name');\n        self.video_file_name = d.get('video_file_name');\n        self.title_safe = d.get('title_safe');\n        self.youtube_info_dict = d.get('youtube_info_dict');\n        self.versions_info=d.get('versions_info');\n        if(self.versions_info is None):\n            self.versions_info = {};\n        #do class specific inits with d;\n\n\n    def initWithPath(self, path=None, clear_temp=None):\n        AFileManager.initWithPath(self, path=path, clear_temp=clear_temp);\n        self.setDir('versions', pathstring(self.getDirectoryPath() + os.sep + \"Versions\" + os.sep));\n        self.setDir('warps', pathstring(self.getDir('versions')+ os.sep + \"Warps\" + os.sep));\n        # self.setDir('midi', pathstring(self.getDirectoryPath() + os.sep + \"MIDI\" + os.sep));\n        # self.setDir('music', pathstring(self.getDirectoryPath() + os.sep + \"Music\" + os.sep));\n        self.setFeaturesDir();\n\n    def setFeaturesDir(self, features_dir=None):\n        if (features_dir is None):\n            self.setDir('features', pathstring(self.getDir('data') + os.sep + \"Features\" + os.sep))\n        else:\n            self.setDir('features', features_dir);\n\n\n\n    def getName(self):\n        \"\"\"\n        Gets name if set. If not set, returns file name without extension.\n        :return:\n        \"\"\"\n        if(self.name is not None):\n            return self.name;\n        elif(self.video_file_name is not None):\n            return os.path.splitext(self.video_file_name)[0];\n        else:\n            return None;\n\n\n###################\n\n\n    @staticmethod\n    def _versionLabelString(version_label=None):\n        if (version_label and version_label != 'Full'):\n            return str(version_label);\n        else:\n            return 'Full';\n\n    @staticmethod\n    def _versionGroupString(version_group=None):\n        if (version_group is None):\n            version_group = 'Original';\n        return version_group;\n\n    @staticmethod\n    def _getVersionLabelDirName(version_label=None):\n        if(isinstance(version_label, int)):\n            return (\"maxheight_{}\".format(version_label));\n        else:\n            return \"Full\";\n\n\n    def getVersionPath(self, version_label=None, version_group=None):\n        \"\"\"\n        Get path to version of video (path to video file). Return None if version has not been added.\n        :param version_label:\n        :return:\n        \"\"\"\n        return self.getVersionInfo(version_label=version_label, version_group=version_group, info_label='path');\n\n    def getDirForVersion(self, version_label=None, version_group=None):\n        vdir = self.getDir('versions') + os.sep + self._versionGroupString(version_group) + os.sep + self._getVersionLabelDirName(version_label)+os.sep;\n        return vdir;\n\n\n    def getVersionInfo(self, version_label, version_group=None, info_label=None):\n        \"\"\"\n        Get info about a version of the video\n        :param version_label:\n        :param info_label:\n        :return:\n        \"\"\"\n        assert(info_label is not None), \"should provide info_label to getVersionInfo()\"\n        d = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(d is not None):\n            return d.get(info_label);\n        else:\n            return None;\n\n    def getVersionDictionary(self, version_label=None, version_group=None):\n        if(version_group is None):\n            version_group='Original';\n        vis_d=self.versions_info.get(version_group);\n        if(vis_d is not None):\n            return vis_d.get(VideoSource._versionLabelString(version_label));\n        else:\n            return None;\n\n    def setVersionDictionary(self, version_label=None, version_group=None, d=None):\n        if(version_group is None):\n            version_group='Original';\n        vis_d=self.versions_info.get(version_group);\n        if(vis_d is None):\n            self.versions_info[version_group]={};\n            vis_d=self.versions_info.get(version_group);\n        vis_d[VideoSource._versionLabelString(version_label)]=d;\n        return;\n\n    def setVersionInfo(self, version_label=None, version_group=None, video_path=None, **kwargs):\n        version_dict = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(version_dict is None):\n            self.setVersionDictionary(version_label=version_label, version_group=version_group, d={});\n            version_dict = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(video_path is not None):\n            version_dict.update({'path':str(pathstring(video_path))});\n        if(kwargs is not None):\n            version_dict.update(kwargs);\n\n\n####################\n\n    def hardSave(self):\n        if (os.path.isfile(self.getJSONPath())):\n            os.rename(self.getJSONPath(), self.getDir('backup') + os.sep + self.AOBJECT_TYPE() + \".json\");\n        self.writeToJSON(self.getJSONPath());\n\n    def save(self):\n        if (self.getInfo('block_writing_to_json')):\n            return;\n        self.hardSave();\n\n####################\n\n\n    # def removeAllVersionFiles(self, asset_manager=None):\n    #     AWARN(\"This should wipe the directory, ya?\")\n    #     # AWARN(\"Remove all version files does not remove features and vis images! This still needs to be implemented!\")\n    #     # for vtype in self.versions_info:\n    #     #     for v in self.versions_info.get(vtype):\n    #     #         # print(self.versions_info.get(vtype).get(v));\n    #     #         vpath = self.versions_info.get(vtype).get(v).get('path');\n    #     #         assert(vpath), \"version {} did not have path\".format(vtype)\n    #     #         print(vpath)\n    #     #         if(os.path.isfile(vpath)):\n    #     #             print(\"REMOVING {}\".format(vpath))\n    #     #             os.remove(vpath);\n    #     #         if(asset_manager is not None and vtype=='Original'):\n    #     #             if(v=='Full'):\n    #     #                 rs=None;\n    #     #             else:\n    #     #                 rs = int(v);\n    #     #             asset_manager.removeFeaturesForLinkRes(link=self, max_height=rs);\n    #     # return True;\n\n    # def removeFeaturesForRes(self, max_height=None):\n    #     v = self.getVersionVideo(name=link.name, max_height = max_height);\n    #     v.clearFeatureFiles(features_to_clear=['all', 'each']);\n    #\n    #\n    # def removeFeatureFilesForVideo(self, video, features_to_remove=None):\n    #     if(features_to_remove is None):\n    #         return;\n    #     if(not isinstance(features_to_remove, list)):\n    #         features_to_remove=[features_to_remove];\n    #     for f in features_to_remove:\n    #         self.removeFeatureFileForVideo(video=video, feature_name=f);\n    #\n    #\n    # def removeFeatureFileForVideo(self, video, feature_name):\n    #     AWARN(\"still need to implement removeFeatureFileForVideo. Should just empty corresponding directory. Also implement 'each' that removes all.\")\n    #     # if(feature_name=='each'):\n    #     #     return self.removeFeatureFilesForVideo(video=video, features_to_remove=video.getFeatureFunctionsList());\n    #     # max_height = video.getInfo(label='max_height');\n    #     # link = self.hasLinkWithName(name=video.name);\n    #     # source_type=video.getFeatureSohahurceType(feature_name);\n    #     # ipath = self.getFeaturePathForLink(feature_name=feature_name, link=link, max_height=max_height, source_type=source_type);\n    #     # if(os.path.isfile(ipath)):\n    #     #     print(\"REMOVING {}\".format(ipath));\n    #     #     os.remove(ipath);\n    #\n    # def removeFeatureFiles(self, video, feature_name):\n    #     if(feature_name=='each'):\n    #         AWARN(\"IMPLEMENT DELETE FEATURE DIR AND CREATE CLEAN\");\n    #     version_label = video.getInfo(label='version_label');\n    #     AWARN(\"IMPLEMENT DELETE {} FOR VERSION_LABEL {}\".format(feature_name, version_label));\n    #     # ipath = self.getFeaturePathForLink(feature_name=feature_name, link=link, max_height=max_height, source_type=source_type);\n    #     # if(os.path.isfile(ipath)):\n    #     #     print(\"REMOVING {}\".format(ipath));\n    #     #     os.remove(ipath);\n    #\n    # def removeVersion(self, version_label=None, remove_files=True):\n    #     AWARN(\"Remove Resolution does not remove features! This still needs to be implemented!\")\n    #     for vtype in self.versions_info:\n    #         v = self.versions_info.get(vtype).get(VideoSource._versionLabelString(version_label));\n    #         if(v is not None):\n    #             vpath = v.get('path');\n    #             if(os.path.isfile(vpath)):\n    #                 print(\"REMOVING {}\".format(vpath))\n    #                 os.remove(vpath);\n    #             self.versions_info.get(vtype).pop(VideoSource._versionLabelString(version_label), None);\n    #     return True;\n    #\n    # def copyResolutionTo(self, version_label=None, output_dir=None):\n    #     assert(output_dir)\n    #     for vtype in self.versions_info:\n    #         v = self.versions_info.get(vtype).get(VideoSource._versionLabelString(version_label));\n    #         if(v is not None):\n    #             vpath = v.get('path');\n    #             if(os.path.isfile(vpath)):\n    #                 opath = os.path.join(output_dir,(vtype+'_'+VideoSource._versionLabelString(version_label)+self.video_file_name));\n    #                 print(\"COPYING {} to {}\".format(vpath,opath));\n    #                 shutil.copy2(vpath, opath);\n    #     return True;\n    #\n    # def copyAssetsTo(self, output_dir=None, asset_manager=None):\n    #     for vtype in self.versions_info:\n    #         output_type_dir=pathstring(output_dir+os.sep+vtype+os.sep);\n    #         make_sure_dir_exists(output_type_dir);\n    #         for v in self.versions_info.get(vtype):\n    #             output_a_dir = pathstring(output_type_dir+os.sep+v+os.sep);\n    #             make_sure_dir_exists(output_a_dir);\n    #             # print(self.versions_info.get(vtype).get(v));\n    #             vpath = self.versions_info.get(vtype).get(v).get('path');\n    #             if(vpath and os.path.isfile(vpath)):\n    #                 print(\"copying {} to {}\".format(vpath, output_a_dir));\n    #                 shutil.copy2(vpath, output_a_dir);\n    #                 if(asset_manager is not None and vtype=='Original'):\n    #                     if(v=='Full'):\n    #                         rs=None;\n    #                     else:\n    #                         rs = int(v);\n    #                     asset_manager.saveFeaturesForVersion(version_label=rs, output_dir = output_a_dir);\n\n    def getWarpsDir(self, version_label=None):\n        warpdir = self.getDir('warps');\n        resdir = self._getVersionLabelDirName(version_label=version_label);\n        rdir = pathstring(warpdir + os.sep + resdir + os.sep);\n        make_sure_path_exists(rdir);\n        return rdir;\n\n    # ############################# FROM ASSETMANAGER #######################\n\n    def getVersion(self, max_height=None, get_if_missing=True, load_features=True, **kwargs):\n        \"\"\"\n        Gets a version of the video with maximum height max_height. This function contains logic to decide whether/when\n            to pull the video. Use pullVersion to force pulling that overwrite's existing assets.\n        :param max_height:\n        :param get_if_missing:\n        :return:\n        \"\"\"\n        vpath = self.getVersionPath(version_label=max_height);\n        if(vpath and os.path.isfile(vpath)):\n            num_frames_total = self.getVersionInfo(version_label=max_height, info_label='num_frames_total');\n            if(num_frames_total):\n                v = self.RegisteredVideo(path=vpath, version_label = max_height, num_frames_total=num_frames_total, load_features=True);\n            else:\n                v = self.RegisteredVideo(path=vpath, version_label = max_height, load_features=True);\n                self.setVersionInfo(version_label=max_height, num_frames_total=v.num_frames_total);\n                self.save();\n            return v;\n        else:\n\n            if(get_if_missing):\n                vpath = self.pullVersion(max_height=max_height, **kwargs);\n                if(vpath):\n                    num_frames_total = self.getVersionInfo(version_label=max_height, info_label='num_frames_total');\n                    if(num_frames_total):\n                        v = self.RegisteredVideo(path=vpath, version_label = max_height, num_frames_total=num_frames_total, load_features=True);\n                    else:\n                        v = self.RegisteredVideo(path=vpath, version_label=max_height, load_features=True);\n                        self.setVersionInfo(version_label=max_height, num_frames_total=v.num_frames_total);\n                        self.save();\n                else:\n                    AWARN(\"COULDNT GET VIDEO FROM {}\".format(self.source_location));\n            else:\n                AWARN(\"COULDNT FIND VIDEO LOCALLY\");\n                return;\n        return v;\n\n    def saveFeaturesForVideo(self, video, features_to_save=None, output_dir=None, overwrite=True):\n        if(features_to_save is None):\n            return;\n        if(not isinstance(features_to_save, list)):\n            features_to_save=[features_to_save];\n        for f in features_to_save:\n            self.saveFeatureForVideo(video=video, feature_name=f, output_dir=output_dir, overwrite=overwrite);\n\n    def saveFeatureForVideo(self, video, feature_name, output_dir=None, overwrite=True):\n        if(feature_name=='each'):\n            return self.saveFeaturesForVideo(video=video, features_to_save=video.getFeaturesList(), output_dir=output_dir, overwrite=overwrite);\n\n        version_label = video.getInfo(label='version_label');\n        source_type = video.getFeatureSourceType(feature_name);\n        opath = self.getFeaturePath(feature_name=feature_name, version_label=version_label, source_type=source_type, output_dir=output_dir);\n        make_sure_dir_exists(opath);\n        if(not os.path.isfile(opath) or overwrite):\n            if(feature_name=='all'):\n                video.saveFeatures(path=opath);\n                return;\n            else:\n                vfeature = video.getFeature(name=feature_name, force_recompute=False);\n                if(vfeature is not None):\n                    video.saveFeature(name=feature_name, path=opath);\n\n    def loadFeaturesForVideo(self, video, features_to_load=None):\n        if(features_to_load is None):\n            return;\n        if(not isinstance(features_to_load, list)):\n            features_to_load=[features_to_load];\n        for f in features_to_load:\n            self.loadFeatureForVideo(video=video, feature_name=f);\n\n    def loadFeatureForVideo(self, video, feature_name):\n        if(feature_name=='each'):\n            return self.loadFeaturesForVideo(video=video, features_to_load=video.getFeatureFunctionsList());\n        version_label = video.getInfo(label='version_label');\n        source_type=video.getFeatureSourceType(feature_name);\n        ipath = self.getFeaturePath(feature_name=feature_name, version_label=version_label, source_type=source_type);\n        if(os.path.isfile(ipath)):\n            if(feature_name=='all'):\n                video.loadFeatures(path=ipath);\n            else:\n                video.loadFeature(name=feature_name, path=ipath);\n\n    def getFeaturePath(self, feature_name=None, source_type=None, version_label=None, output_dir=None):\n        assert(feature_name is not None), 'must provide name of feature VideoSource.getFeaturePath'\n        feature_dir = self.getFeatureDir(feature_name=feature_name, source_type = source_type);\n        fileext = '.pkl';\n        if(output_dir is None):\n            version = self._getVersionLabelDirName(version_label=version_label)+os.sep;\n            output_dir = pathstring(feature_dir);\n        outname = self.getName();\n        if(outname is None):\n            outname = 'version';\n        outname = outname+'_'+self._getVersionLabelDirName(version_label=version_label)+fileext;\n        opath = os.path.join(output_dir, outname);\n        return opath;\n\n    def getFeatureDir(self, feature_name=None, source_type=None):\n        if(source_type is None):\n            source_type='video'; # could be 'audio'\n        # AWARN(\"getDir('features')= {}\\nsource_type= {}\\nfeature_name= {}\".format(self.getDir('features'), source_type, feature_name))\n        ftypedir = pathstring(self.getDir('features') + os.sep + source_type + os.sep + feature_name + os.sep);\n        return ftypedir;\n\n    def saveFeaturesForVersion(self, version_label=None, output_dir=None):\n        assert(output_dir), 'must provide output dir';\n        v = self.getVersion(max_height=version_label);\n        v.save(features_to_save='all', output_dir=output_dir);\n\n\n    def RegisteredVideo(self, path=None, version_label=None, version_group = None, num_frames_total=None, load_features = True):\n        v = self.VideoClass(path=path, name=self.getName()+'_'+self._versionLabelString(version_label=version_label), num_frames_total=num_frames_total);\n        # v = Video(path=path, name=self.getName()+'_'+self._versionLabelString(version_label=version_label), num_frames_total=num_frames_total);\n        self.RegisterVideo(video=v, version_label=version_label, load_features=load_features);\n        return v;\n\n    def RegisterVideo(self, video, version_label = None, version_group = None, load_features=True):\n        def videosave(vidob, features_to_save='all', output_dir=None, overwrite=True):\n            self.saveFeaturesForVideo(video=vidob, features_to_save=features_to_save, output_dir=output_dir, overwrite=overwrite);\n            #self.save\n        def videoload(vidob, features_to_load='all', input_dir=None):\n            self.loadFeaturesForVideo(video=vidob, features_to_load=features_to_load);\n        def videoclear(vidob, features_to_clear='all'):\n            self.removeFeatureFilesForVideo(video=vidob, features_to_remove=features_to_clear);\n\n        video.setInfo(label='version_label', value=version_label);\n        video.setInfo(label='version_group', value=version_group);\n        video.setInfo(label='video_file_name', value=os.path.split(video.getPath())[1]);\n        # if(version_group is None):\n        video.save_func = videosave;\n        video.load_func = videoload;\n        video.clear_feature_files_func = videoclear;\n        video.source=self;\n\n        if(load_features is True and hasattr(video, \"loadFlowFeatures\")):\n            video.loadFlowFeatures();\n        elif(load_features is not None and (isinstance(load_features, list) or isinstance(load_features, str))):\n            video.load(features_to_load = load_features);\n\n        # return video;\n\n    def addVersion(self, path, version_label=None, version_group=None):\n        v = self.RegisteredVideo(path=path, version_label=version_label);\n        video_dict=v.getVersionInfo();\n        video_dict.update(dict(version_group=version_group));\n        self.setVersionInfo(video_path = path, version_label=version_label, **video_dict);\n        self.save();\n\n    def addVersionToVideo(self, video, new_video, version_label=None, version_group=None):\n        version_label = video.getInfo(label='version_label');\n        video_dict = new_video.getVersionInfo();\n        if ((version_group is not None) or (video_dict.get('version_group') is None)):\n            video_dict.update(dict(version_group=version_group));\n        self.setVersionInfo(video_path=new_video.getPath(), version_label=version_label, **video_dict);\n        self.save();\n\n\n    def setSource(self, source_location=None, assert_valid=True, **kwargs):\n        \"\"\"\n        Sets the source of this VideoSource. If file, copies the file to VideoSource directory as \"Original\" version,\n            unless copy argument is set to false.\n        :param source_location: either path to file, or youtube url\n        :param kwargs: see setSourceYoutube or setSourceFile for options\n        :return:\n        \"\"\"\n\n        if(source_location):\n            if(os.path.isfile(source_location)):\n                self.setSourceFile(path = source_location, **kwargs);\n            else:\n                self.setSourceYoutube(url=source_location, **kwargs);\n            return;\n        elif(kwargs.get('video_path')):\n            self.setSourceFile(**kwargs);\n            return;\n        elif(kwargs.get('url')):\n            self.setSourceYoutube(**kwargs);\n            return;\n        else:\n            if(assert_valid):\n                assert(False),'No valid source location provided to setSource.'\n\n\n\n\n    def setSourceYoutube(self, url=None, max_height=None, pull_fullres=True, **kwargs):\n        self.source_location=url;\n        self.setInfo(label='source_type', value='youtube');\n        if(pull_fullres):\n            self.pullYoutubeVideo(max_height=max_height, **kwargs);\n        self.save();\n\n    def setSourceFile(self, path=None, copy=True, **kwargs):\n        # assert(os.path.isfile(path)), 'Tried to set source but no file exists at {}'.format(path);\n        if(not os.path.isfile(path)):\n            return None;\n\n        self.video_file_name = os.path.basename(path);\n        if(not copy):\n            self.source_location = path;\n            self.setInfo(label='source_type', value='file_address');\n            return path;\n        # output_dir = self.getDir('versions') + os.sep + 'Original' + os.sep;\n        output_dir = self.getDirForVersion(version_label=None, version_group='Source');\n        make_sure_dir_exists(output_dir);\n        output_path = os.path.join(output_dir, self.video_file_name);\n        # max_height = kwargs.get('max_height');\n\n        # if(max_height is not None):\n        #     # print('max_height was {}'.format(max_height));\n        #     original = self.VideoClass(path=path);\n        #     original.writeResolutionCopyFFMPEG(path=output_path, max_height=kwargs.get('max_height'));\n        # else:\n        #     shutil.copy2(path, output_path);\n\n        shutil.copy2(path, output_path);\n\n        # self.addVersion(path=output_path, version_label='Original');\n        self.addVersion(path=output_path, version_label='Full');\n        self.setInfo(label='source_type', value='file');\n        self.source_location = output_path;\n        self.save();\n        return output_path;\n\n\n    def pullVersion(self, max_height=None, **kwargs):\n        # assert(self.source_location is not None), \"Could not pull version; source location is None.\"\n        if(self.source_location is None):\n            return None;\n        source_type = self.getInfo('source_type');\n        if(source_type=='youtube'):\n            return self.pullYoutubeVideo(max_height=max_height, **kwargs);\n        else:\n            return self.pullFileVideo(max_height=max_height, **kwargs)\n\n\n    def pullFileVideo(self, max_height=None, force_recompute=None):\n        original_path = self.source_location;\n        assert(os.path.isfile(original_path)), 'SOURCE FILE {} IS MISSING'.format(self.source_location);\n        original = self.VideoClass(path=original_path);\n        output_dir = self.getDirForVersion(version_label=max_height, version_group=None);\n        make_sure_dir_exists(output_dir);\n        output_path = os.path.join(output_dir, self.video_file_name);\n        if(max_height is None):\n            if(os.path.normpath(original_path) != os.path.normpath(output_path)):\n                shutil.copy2(original_path, output_path);\n        else:\n            original.writeResolutionCopyFFMPEG(path=output_path, max_height=max_height);\n        self.addVersion(path=output_path, version_label=max_height);\n        return self.getVersionPath(version_label=max_height);\n\n    def pullYoutubeVideo(self, max_height=None, write_subtitles=False, save_youtube_info=False,\n                  force_redownload=False):\n        \"\"\"\n        Downloads video from youtube with height<=max_height. Returns path to downloaded video.\n        :param max_height: maximum height of video to download\n        :param write_subtitles: whether to save the subtitles\n        :param save_youtube_info: whether to save the info json\n        :param force_redownload: whether to re-download if video exists\n        :return:\n        \"\"\"\n        assert (not self.getInfo('source_is_file')), \"tried to call pullYoutubeVideo on file source {}.\".format(self.getName());\n\n        old_vid_path = self.getVersionPath(version_label=max_height);\n\n        if ((not force_redownload) and old_vid_path and os.path.isfile(old_vid_path)):\n            AWARN(\"Old video version exists with path {}\\nSkipping download...\\n\".format(old_vid_path))\n            return old_vid_path;\n\n        # output_dir = self.getDir('versions') + os.sep + self._getVersionLabelDirName(version_label=max_height) + os.sep;\n        output_dir = self.getDirForVersion(version_label=max_height, version_group=None);\n        make_sure_path_exists(output_dir);\n\n        if ((not force_redownload) and self.video_file_name is not None):\n            path_guess = os.path.join(output_dir, self.video_file_name);\n            if (os.path.isfile(path_guess)):\n                AWARN(\"found existing file {}\\nSkipping download; set force_redownload=True to overwrite old version.\".format(path_guess));\n                self.addVersion(path=path_guess, version_label=max_height);\n                return path_guess;\n\n\n        ########Download From YouTube#########\n        vidpath_template = output_dir + '%(title)s-%(id)s' + '.%(ext)s';\n        ydl_opts = {\n            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',\n            'outtmpl': vidpath_template,\n        }\n        if (write_subtitles):\n            ydl_opts['writesubtitles'] = True;\n            ydl_opts['subtitlesformat'] = '[srt]';\n        if (max_height):\n            ydl_opts['format'] = 'bestvideo[height<={}][ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'.format(\n                max_height);\n        ydl_opts['writeinfojson'] = True;\n        info_dict = None;\n\n        AWARN(\"Downloading {} from {}...\".format(self.getName(), self.source_location));\n\n        with youtube_dl.YoutubeDL(ydl_opts) as ydl:\n            info_dict = ydl.extract_info(self.source_location, download=True)\n            # video_source = info_dict.get(\"source\", None)\n            # video_id = info_dict.get(\"id\", None)\n            # video_title = info_dict.get('title', None)\n        usedtitle = info_dict['title'].replace('\"', \"'\").replace('|', '_').replace(':', ' -').replace('/','_').replace('?', '');\n        usedfilename_withoutext = usedtitle + '-' + info_dict['id'];\n        usedfilename = usedfilename_withoutext + '.' + info_dict['ext'];\n        filepath = output_dir + os.sep + usedfilename;\n        filepathsafe = safe_file_name(filepath);\n        if (os.path.isfile(filepath)):\n            os.rename(filepath, filepathsafe);\n        else:\n            fpath = glob.glob(output_dir + os.sep + '*' + info_dict['id'] + '.mp4');\n            assert (len(fpath) == 1), \"Wrong number of files for {}\\nFound:\\n{}\".format(filepath, fpath);\n            os.rename(fpath[0], filepathsafe);\n            jpath = glob.glob(output_dir + os.sep + '*' + info_dict['id'] + '.info.json');\n            os.rename(jpath[0], safe_file_name(usedfilename_withoutext + '.info.json'));\n\n        print((\"Saved to {}\".format(filepathsafe)));\n\n        self.video_file_name = safe_file_name(usedfilename);\n        self.title_safe = safe_file_name(usedtitle);\n        if (save_youtube_info):\n            self.youtube_info_dict = info_dict;\n\n        # v = Video(path=filepathsafe);\n        # video_dict=v.toDictionary();\n        # self.setVersionInfo(video_path = filepathsafe, version_label=max_height, num_frames_total=v.num_frames_total, **video_dict);\n        # self.save();\n        self.addVersion(path=filepathsafe, version_label=max_height);\n        return self.getVersionPath(version_label=max_height);\n        # return youtube_link;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Video_CV.py",
    "content": "# from Video import *\nfrom .Image import *\nfrom .Event import *\nfrom .VisualBeat import *\nimport librosa\n\nFEATURE_FUNCS = {};\nVIS_FUNCS = {};\nVISVIDEO_FUNCS = {};\n\nFLOW_LOG_EPSILON=1.0;\nFLOW_UNIT_GAIN=10000.0;\n\nHISTOGRAM_FRAMES_PER_BEAT = 2;\nHISTOGRAM_DOWNSAMPLE_LEVELS = 3;\n\n\nVB_UPSAMPLE_FACTOR = 1.0;\nUSING_OPENCV = Image.USING_OPENCV;\n\nif(USING_OPENCV):\n\n    ##########################################################################\n    # ################ THESE ARE THE FUNCTIONS TO OVERRIDE! ################ #\n    # ################     FOR CUSTOM SALIENCY METRICS!     ################ #\n    ##########################################################################\n\n    # You can modify them here. But I would suggest elsewhere in your code\n    # just setting Video.localRhythmicSaliencyFunction and\n    # Video.visualBeatFunction to whatever you want. See how they are assigned\n    # when Video_CV is included in Video.py. -Abe\n\n    def localRhythmicSaliencyFunction(self, **kwargs):\n        \"\"\"\n        Change to use different function for local saliency\n        \"\"\"\n        return self.getVisibleImpactEnvelope(**kwargs);\n\n    def visualBeatFunction(self, **kwargs):\n        \"\"\"\n        Change to use different default strategy for selecting visual beats\n        \"\"\"\n        # beat_params = dict(\n        #     pre_max_time=0.2,\n        #     post_max_time=0.2,\n        #     pre_avg_time=0.2,\n        #     post_avg_time=0.2,\n        #     wait_time=0.1,\n        # )\n        beat_params = self._getDefaultPeakPickingTimeParams();\n        beat_params.update(kwargs);\n        return self.getVisibleImpacts(**beat_params);\n\n    # #################### This is how they are called #################### #\n\n    def getLocalRhythmicSaliency(self, force_recompute=False, **kwargs):\n        feature_name = 'local_rhythmic_saliency';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = dict();\n            params.update(kwargs);\n            params.update({'force_recompute':force_recompute});\n            result = self.localRhythmicSaliencyFunction(**params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getVisualBeats(self, force_recompute=False, **kwargs):\n        feature_name = 'visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            params.update({'force_recompute': force_recompute});\n            result = self.visualBeatFunction(**params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    # ##################################################################### #\n\n    ##########################################################################\n    # ###################################################################### #\n    ##########################################################################\n\n\n\n    def cvGetGrayFrame(self, f):\n        colorframe = self.getFrame(f).astype(np.uint8);\n        return ocv.cvtColor(colorframe, ocv.COLOR_RGB2GRAY);\n\n    def getImageFromFrameGray(self, f):\n        frame = self.getImageFromFrame(f);\n        frame.RGB2Gray();\n        return frame;\n\n    def flow2row(ang, amp, bins, subdivs, n_shifts, density):\n        h, w = ang.shape[:2];\n        ncells = np.power(4, subdivs);\n        nperd = np.power(2, subdivs);\n\n        xw = w-n_shifts[1];\n        yw = h-n_shifts[0];\n\n        xcells = np.arange(nperd + 1, dtype=float);\n        ycells = np.arange(nperd + 1, dtype=float);\n        xcells = np.floor((xcells / (nperd)) * xw);\n        ycells = np.floor((ycells / (nperd)) * yw);\n        # print(n_shifts)\n\n        ahis = np.zeros([ncells * bins, n_shifts[0]*n_shifts[1]]);\n\n        for dy in range(n_shifts[0]):\n            for dx in range(n_shifts[1]):\n                ampwin = amp[dy:dy+yw,dx:dx+xw];\n                angwin = ang[dy:dy+yw,dx:dx+xw];\n                cell_counter = 0;\n                for x in range(nperd):\n                    for y in range(nperd):\n                        ystart=int(ycells[y]);\n                        yend = int(ycells[y+1]);\n                        xstart = int(xcells[x]);\n                        xend = int(xcells[x + 1]);\n                        angcell = angwin[ystart:yend, xstart:xend];\n                        ampcell = ampwin[ystart:yend, xstart:xend];\n                        cahis, cbinbounds = np.histogram(angcell.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                                         weights=ampcell.ravel(), density=density);\n                        # print(\"ahis shape: {}\\ncahis shape: {}\\ndx, dy: {}, {}\\ncell_counter: {}\\nbins: {}\\n\".format(ahis.shape, cahis.shape, dx, dy, cell_counter, bins));\n                        ahis[cell_counter * bins:(cell_counter + 1) * bins, dx+dy*n_shifts[0]] = cahis;\n                        cell_counter = cell_counter + 1;\n        return ahis;\n\n    def getFlowFrame(self, frame_index):\n        prev_frame = self.cvGetGrayFrame(frame_index-1);\n        this_frame = self.vbGetGrayFrame(frame_index);\n        return cvDenseFlowFarneback(from_image=prev_frame, to_image=this_frame);\n\n    def getFlowFramePolar(self, frame_index):\n        \"\"\"\n        :param self:\n        :param frame_index:\n        :return: polar where polar[:,:,0] is amplitude, and polar[:,:,1] is angle\n        \"\"\"\n        flow = self.getFlowFrame(frame_index);\n        fx, fy = flow[:,:,0], flow[:,:,1];\n        polar = np.zeros(size(flow));\n        polar[:,:,0] = np.sqrt(fx * fx + fy * fy);\n        polar[:,:,1] = np.arctan2(fy, fx) + np.pi\n        return polar;\n\n    def computeDirectogramPowers(self, bins=None, dead_zone= 0.05, density=None, save_if_computed=True, noise_floor_percentile=None, **kwargs):\n        if(bins is None):\n            bins = 128;\n        if(noise_floor_percentile is None):\n            noise_floor_percentile = 20;\n\n        print((\"Computing Flow Features with deadzone {}\".format(dead_zone)))\n\n        signal_dim = 128;\n        m_histvals = np.zeros([signal_dim, self.n_frames(), 3]);\n\n        flow_averages = np.zeros([self.n_frames(), 1]);\n        sampling_rate=self.sampling_rate;\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        # print(sampling_rate, duration)\n        frame_start_times = np.linspace(0,duration,num=int(nsamples),endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        lastframe = self.cvGetGrayFrame(frame_index_floats[0]);\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        counter = 0;\n\n        for nf in range(len(frame_index_floats)):\n            nextframe= self.cvGetGrayFrame(frame_index_floats[nf]);\n            flow = cvDenseFlowFarneback(from_image=lastframe, to_image=nextframe);\n            h, w = flow.shape[:2];\n            fx, fy = flow[:,:,0], flow[:,:,1];\n\n            # if(filter_median):\n            #     fx = fx-np.median(fx.ravel());\n            #     fy = fy-np.median(fy.ravel());\n            #     assert(False), \"SHOULDNT BE FILTERING MEDIAN! VESTIGIAL CODE\"\n\n            ang = np.arctan2(fy, fx) + np.pi\n            amp = np.sqrt(fx*fx+fy*fy);\n\n            winstarty = int(dead_zone*h);\n            winendy = h-winstarty;\n            winstartx = int(dead_zone*w);\n            winendx = w-winstartx;\n            angw = ang[winstarty:winendy, winstartx:winendx];\n            ampw = amp[winstarty:winendy, winstartx:winendx];\n\n            mask0 = (ampw>np.percentile(ampw,noise_floor_percentile)).astype(float);\n            ahis0, cbinbounds = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=mask0.ravel(), density=density);\n            ahis1, cbinbounds1 = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=ampw.ravel(), density=density);\n            ahis2, cbinbounds2 = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=np.power(ampw, 2).ravel(), density=density);\n\n            m_histvals[:, counter, 0] = ahis0;\n            m_histvals[:, counter, 1] = ahis1;\n            m_histvals[:, counter, 2] = ahis2;\n\n            lastframe=nextframe;\n            counter+=1;\n            fcounter+=1;\n\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n        params = dict( bins = bins,\n                        deadzone=dead_zone,\n                        density=density);\n        params.update(kwargs);\n        self.setFeature(name='directogram_powers', value=m_histvals, params=params);\n        if(save_if_computed):\n            self.save(features_to_save=['directogram_powers']);\n        return m_histvals;\n\n    ######################### Other Features #############################\n\n    def getDirectogramPowers(self, force_recompute=False, **kwargs):\n        feature_name = 'directogram_powers';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            flow_powers = self.computeDirectogramPowers(**kwargs);\n        return self.getFeature(feature_name);\n\n    # def getDirectogram(self, bins = None, weights=None, density=None, force_recompute=False, save_if_computed=True, **kwargs):\n    def getDirectogram(self, **kwargs):\n        feature_name = 'directogram';\n        force_recompute = kwargs.get('force_recompute');\n        if((not self.hasFeature(feature_name)) or force_recompute):\n            flow_powers = self.getFeature('directogram_powers');\n            fh = flow_powers[:,:,1];\n            self.setFeature(name='directogram', value=fh, params=kwargs);\n        return self.getFeature(feature_name);\n\n    def getVisualTempo(self, force_recompute=None, **kwargs):\n        feature_name = 'visual_tempo';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            vbe = self.getFeature('local_rhythmic_saliency');\n            # assert librosa.__version__ == '0.7.1'\n            # result = librosa.beat.beat_track(onset_envelope=vbe, sr=self.sampling_rate, hop_length=1, **kwargs);\n            result = librosa.beat.beat_track(onset_envelope=vbe, sr=self.sampling_rate, hop_length=1, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=kwargs);\n        return self.getFeature(feature_name);\n\n    def getVisualTempogram(self, window_length=None, force_recompute=None, norm_columns = None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param window_length: in seconds\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'visual_tempogram';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            if(window_length is None):\n                window_length = DEFAULT_TEMPOGRAM_WINDOW_SECONDS;\n            params = kwargs;\n            params.update({'force_recompute': force_recompute});\n            vbe = self.computeImpactEnvelope(cut_suppression_seconds = None);\n            onset_envelope = vbe;\n            win_length = int(round(window_length * self.sampling_rate));\n            sr = self.sampling_rate;\n            hop_length = 1;\n\n            center=kwargs.get('center');\n            if(center is None):\n                center=True;\n            window='hann'\n            norm=np.inf;\n            ac_window = librosa.filters.get_window(window, win_length, fftbins=True)\n\n            # Center the autocorrelation windows\n            n = len(onset_envelope)\n\n            if center:\n                onset_envelope = np.pad(onset_envelope, int(win_length // 2),\n                                        mode='linear_ramp', end_values=[0, 0])\n            # Carve onset envelope into frames\n            odf_frame = librosa.util.frame(onset_envelope,\n                                   frame_length=win_length,\n                                   hop_length=hop_length)\n            # Truncate to the length of the original signal\n            if center:\n                odf_frame = odf_frame[:, :n]\n\n            odf_frame = librosa.util.normalize(odf_frame,axis=0,norm=norm)\n            if(norm_columns is None):\n                norm_columns = True;\n\n            if(norm_columns):\n                # Window, autocorrelate, and normalize\n                result = librosa.util.normalize(\n                    librosa.core.audio.autocorrelate(odf_frame * ac_window[:, np.newaxis], axis=0), norm=norm, axis=0);\n            else:\n                result = librosa.core.audio.autocorrelate(odf_frame * ac_window[:, np.newaxis], axis=0);\n                result = np.true_divide(result, np.max(result.ravel()));\n\n            tempo_bpms = librosa.tempo_frequencies(result.shape[0], hop_length=hop_length, sr=sr)\n            self.setFeature(name='tempogram_bpms', value=tempo_bpms);\n            ###########\n            self.setFeature(name=feature_name, value=result, params=params);\n\n        return self.getFeature(feature_name);\n\n    def getVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = False, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getForwardVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        \"\"\"\n        Same as getVisibleImpactEnvelope by default.\n        :param self:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'forward_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = False, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBackwardVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'backward_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=False, backward = True, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBothWayVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'both_way_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = True, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getVisibleImpactEnvelopePowers(self, force_recompute=False, **kwargs):\n        feature_name = 'impact_envelope_powers';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result0 = self.computeImpactEnvelope(power= 0, **params);\n            result = np.zeros([len(result0), 3]);\n            result[:, 0] = result0;\n            result[:, 1] = self.computeImpactEnvelope(power= 1, **params);\n            result[:, 2] = self.computeImpactEnvelope(power=2, **params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getCutTimes(self):\n        return Event.ToStartTimes(self.getCutEvents());\n\n    def getCutEvents(self, force_recompute=False, **kwargs):\n        \"\"\"\n        Hacky estimate of cuts in a video\n        :param self:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'cut_events';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            powers = self.getFeature('directogram_powers');\n            im0 = powers[:, :, 0];\n            im2 = powers[:, :, 2];\n            imc = np.true_divide(im2, 0.05 + im0);\n\n            medsig = np.median(imc, 0);\n            medall = np.median(imc);\n            cutsig = np.true_divide(medsig, medall)\n            cut_detection_ratio = kwargs.get('cut_detection_ratio');\n            if(cut_detection_ratio is None):\n                cut_detection_ratio=CUT_DETECTION_RATIO;\n            clipsig = (cutsig > cut_detection_ratio).astype(float);\n            clip_floorsig = (cutsig > CUT_DETECTION_FLOOR).astype(float);\n            clipsig = np.multiply(clipsig, clip_floorsig);\n\n            einds = np.flatnonzero(clipsig);\n            etimes = einds * truediv(1.0, self.sampling_rate);\n            ev = Event.FromStartTimes(etimes, type='cut');\n            ev = self.visualBeatsFromEvents(ev);\n            evout = []\n            for e in range(len(ev)):\n                ev[e].setInfo('frame', einds[e]);\n            result = ev;\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def visualBeatsFromEvents(self, events):\n        def downsample_hist(sig, levels):\n            nperbin = np.power(2, levels);\n            rshp = sig.reshape(-1, nperbin);\n            return rshp.sum(axis=1);\n        if(self.hasFeature('impact_envelope')):\n            svbe=self.getFeature('impact_envelope');\n        else:\n            svbe=self.computeImpactEnvelope(cut_suppression_seconds = None);\n        flow_powers = self.getFeature('directogram_powers');\n        vis_tempogram = self.getFeature('visual_tempogram');\n\n        vbeats = [];\n        for e in events:\n            b = VisualBeat.FromEvent(e);\n            ei = int(round(b.start*self.sampling_rate*VB_UPSAMPLE_FACTOR));\n            b.weight = svbe[ei];\n\n            histsize = int(128/int(np.power(2,HISTOGRAM_DOWNSAMPLE_LEVELS)))\n            histslice = np.zeros([histsize, HISTOGRAM_FRAMES_PER_BEAT]);\n            histslice = np.squeeze(np.mean(histslice, 1));\n            b.flow_histogram = downsample_hist(sig=histslice, levels=HISTOGRAM_DOWNSAMPLE_LEVELS);\n            b.flow_histogram = np.divide(b.flow_histogram, np.sum(b.flow_histogram));\n            b.local_autocor = vis_tempogram[:,ei];\n            b.local_autocor = b.local_autocor/np.max(b.local_autocor);\n            b.sampling_rate=self.sampling_rate;\n            vbeats.append(b);\n        return vbeats;\n\n    def getVisualBeatTimes(self, **kwargs):\n        return Event.ToStartTimes(self.getVisualBeats(**kwargs));\n\n    def getDirectionalFlux(self,\n                            f_sigma=None,\n                            median_kernel=None,\n                            power=None,\n                            **kwargs):\n        \"\"\"\n        The visual impact complement of a spectral flux matrix\n        :param self:\n        :param f_sigma: sigma for the gaussian used to filter, using sp.ndimage.filters.gaussian_filter\n        :param median_kernel: used in sp.signal.medfilt\n        :param power: Which power of the flow to use. Usually use 1.\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        def d_x(im):\n            d_im = np.zeros(im.shape);\n            d_im[:, 0] = im[:, 0];\n            for c in range(1, im.shape[1]):\n                d_im[:, c] = im[:, c] - im[:, c - 1];\n            return d_im;\n\n        if (f_sigma is None):\n            f_sigma = [5, 3];\n        if (median_kernel is None):\n            median_kernel = [3, 3];\n\n        if(power is None):\n            power = 1;\n\n        powers = self.getFeature('directogram_powers');\n        im = powers[:,:,power].copy();\n        if (f_sigma is not None):\n            im = sp.ndimage.filters.gaussian_filter(input=im, sigma=f_sigma, order=0);\n\n        im = sp.signal.medfilt(im, median_kernel);\n        return d_x(im);\n\n    def computeImpactEnvelope(self,\n                             forward=True,\n                             backward = False,\n                             f_sigma=None,\n                             median_kernel=None,\n                             highpass_window_seconds= 0.8,\n                             cut_percentile=99,\n                             power=None,\n                             crop = None,\n                             normalize = True,\n                             **kwargs):\n        \"\"\"\n\n        :param self:\n        :param forward: include impact going forward in time\n        :param backward: include impact going backward in time\n        :param f_sigma: sigma for the gaussian used to filter, using sp.ndimage.filters.gaussian_filter\n        :param median_kernel: used in sp.signal.medfilt\n        :param highpass_window_seconds: highpass window size in seconds\n        :param cut_percentile: percentile above which to consider cuts and to clip\n        :param power: Which power of the flow to use. Usually use 1.\n        :param crop:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        upsample_factor = kwargs.get('upsample_factor');\n        inputargs = dict(f_sigma=f_sigma,\n                         median_kernel=median_kernel,\n                         power=power,\n                         crop = crop);\n\n        inputargs.update(kwargs);\n        im_d = self.getDirectionalFlux(**inputargs);\n\n        if(forward and backward):\n            im = np.fabs(im_d);\n        elif(forward):\n            im = -im_d;\n            im = np.clip(im, 0, None)\n        elif(backward):\n            im = im_d;\n            im = np.clip(im, 0, None)\n        else:\n            assert(False), \"Must be at least one of either forward or backward.\"\n\n        vimpact = np.squeeze(np.mean(im, 0));\n        sampling_rate = self.sampling_rate;\n        if(upsample_factor is not None and (upsample_factor>1)):\n            newlen = upsample_factor * len(vimpact);\n            sampling_rate = upsample_factor*sampling_rate;\n            vimpact = sp.signal.resample(vimpact, newlen);\n\n        if(highpass_window_seconds):\n            order = kwargs.get('highpass_order');\n            if(order is None):\n                order = 5;\n            cutoff = truediv(1.0, highpass_window_seconds);\n            normal_cutoff = cutoff / (sampling_rate*0.5);\n            b, a = sp.signal.butter(order, normal_cutoff, btype='high', analog=False)\n            vimpact = sp.signal.filtfilt(b, a, vimpact);\n\n\n        normfactor = np.max(np.fabs(vimpact[:]));\n\n        if (cut_percentile is not None):\n            fx = np.fabs(vimpact);\n            pv = np.percentile(fx, cut_percentile);\n            pvlow = np.percentile(fx, cut_percentile-1);\n            normfactor = pv;\n            ptile = (vimpact > pv).astype(float);\n            pntile = (vimpact < -pv).astype(float);\n            pboth = ptile+pntile;\n            einds = np.flatnonzero(pboth);\n            lastind = -2;\n            for j in range(len(einds)):\n                if(einds[j]==(lastind+1)):\n                    vimpact[einds[j]]=0;\n                else:\n                    vimpact[einds[j]]=pvlow;\n\n        if(normalize):\n            vimpact = np.true_divide(vimpact, normfactor);\n        return vimpact;\n\n    # 0.8, cut_suppression_seconds = 0.4,\n    def computeImpactEnvelopeOld(self, f_sigma=None, median_kernel=None, highpass_window_seconds= 0.8, cut_percentile=99, power=None, crop = None, normalize=None, **kwargs):\n        \"\"\"\n        I believe this is the version of the function that I used in the original paper. Keeping it around for record.\n        :param self:\n        :param f_sigma:\n        :param median_kernel:\n        :param highpass_window_seconds:\n        :param cut_percentile:\n        :param power:\n        :param crop:\n        :param normalize:\n        :param kwargs:\n        :return:\n        \"\"\"\n        def d_x(im):\n            # d_im = np.zeros(im.shape, dtype=np.float128);\n            d_im = np.zeros(im.shape);\n            d_im[:, 0] = im[:, 0];\n            for c in range(1, im.shape[1]):\n                d_im[:, c] = im[:, c] - im[:, c - 1];\n            return d_im;\n\n        if (f_sigma is None):\n            f_sigma = [5, 3];\n        if (median_kernel is None):\n            median_kernel = [3, 3];\n\n        if(power is None):\n            power = 1;\n\n        upsample_factor = kwargs.get('upsample_factor');\n\n        powers = self.getFeature('directogram_powers');\n        print((\"computing impact env with power {}\".format(power)));\n        im = powers[:,:,power].copy();\n\n        if (f_sigma is not None):\n            im = sp.ndimage.filters.gaussian_filter(input=im, sigma=f_sigma, order=0);\n\n        im = sp.signal.medfilt(im, median_kernel);\n        im = -d_x(im);\n        im = np.clip(im, 0, None)\n\n        svbe = np.squeeze(np.mean(im, 0));\n        sampling_rate = self.sampling_rate;\n\n        if(upsample_factor is not None and (upsample_factor>1)):\n            newlen = upsample_factor * len(svbe);\n            sampling_rate = upsample_factor*sampling_rate;\n            svbe = sp.signal.resample(svbe, newlen);\n\n        if(highpass_window_seconds):\n            order = kwargs.get('highpass_order');\n            if(order is None):\n                order = 5;\n            cutoff = truediv(1.0, highpass_window_seconds);\n            normal_cutoff = cutoff / (sampling_rate*0.5);\n            b, a = sp.signal.butter(order, normal_cutoff, btype='high', analog=False)\n            svbe = sp.signal.filtfilt(b, a, svbe);\n\n\n        normfactor = np.max(np.fabs(svbe[:]));\n\n        if (cut_percentile is not None):\n            fx = np.fabs(svbe);\n            pv = np.percentile(fx, cut_percentile);\n            pvlow = np.percentile(fx, cut_percentile-1);\n            normfactor = pv;\n            ptile = (svbe > pv).astype(float);\n            pntile = (svbe < -pv).astype(float);\n            pboth = ptile+pntile;\n            einds = np.flatnonzero(pboth);\n            lastind = -2;\n            for j in range(len(einds)):\n                if(einds[j]==(lastind+1)):\n                    svbe[einds[j]]=0;\n                else:\n                    svbe[einds[j]]=pvlow;\n\n        if(normalize is not False):\n            svbe = np.true_divide(svbe, normfactor);\n        return svbe;\n\n    def getVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'visible_impacts';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            svbe = self.getFeature('impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n\n            peak_params = self._getDefaultPeakPickingTimeParams();\n            peak_params.update(kwargs); # if params given in arguments, those will override the defaults here.\n\n            v_events = Event.FromSignalPeaks(signal=svbe, sampling_rate=u_sampling_rate, **peak_params);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            result = self.visualBeatsFromEvents(v_events);\n\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getForwardVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'forward_visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            local_saliency = self.getFeature('forward_visual_impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n            v_events = Event.FromSignalPeaks(signal=local_saliency, sampling_rate=u_sampling_rate, event_type= 'forward', **kwargs);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            result = Event.SetDirections(v_events, direction=Event.DIRECTION_FORWARD);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBackwardVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'backward_visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            local_saliency = self.getFeature('backward_visual_impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n            v_events = Event.FromSignalPeaks(signal=local_saliency, sampling_rate=u_sampling_rate, **kwargs);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            # result = self.visualBeatsFromEvents(v_events);\n            result = Event.SetDirections(v_events, direction=Event.DIRECTION_BACKWARD);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n\n    def findAccidentalDanceSequences(self, target_n_beats = 7, n_samples=25, delta_range = None):\n        if(delta_range is None):\n            delta_range = [0.02, 0.5];\n\n        deltas = np.linspace(delta_range[0], delta_range[1], num=n_samples, endpoint=True);\n        deltapick = delta_range[0];\n        sequences = [];\n        for i, delta in enumerate(deltas):\n            peak_vars = self._getDefaultPeakPickingTimeParams(delta=delta);\n            sequences = self.getVisualBeatSequences(peak_vars=peak_vars, print_summary=False);\n            # print(\"Delta {} has top sequence with {} beats\".format(delta, len(sequences[0])));\n            if(len(sequences[0])<=target_n_beats):\n                deltapick = delta;\n                break;\n        print((\"Selected delta value {}\".format(deltapick)));\n        return sequences;\n\n\n    def getVisualBeatSequences(self,\n                               search_tempo=None,\n                               target_period=None,\n                               search_window=0.75,\n                               min_beat_limit=None,\n                               max_beat_limit=None,\n                               unary_weight=None,\n                               binary_weight=None,\n                               break_on_cuts=None,\n                               peak_vars=None,\n                               time_range=None,\n                               n_return = None,\n                               unsorted = False,\n                               print_summary = True,\n                               **kwargs):\n        \"\"\"\n\n        :param self:\n        :param search_tempo: optional tempo you would like to find visual beats at\n        :param target_period: optional target period you would like to use for finding beats. Ignored if search tempo is provided.\n        :param search_window: longest amount of time (seconds) allowed between beats before a segment is broken into multiple segments\n        :param min_beat_limit: only consider sequences with\n        :param unary_weight:\n        :param binary_weight:\n        :param break_on_cuts:\n        :param peak_vars:\n        :param kwargs:\n        :return:\n        \"\"\"\n        if (peak_vars is not None):\n            # impacts = self.getFeature('visible_impacts', force_recompute=True, **peak_vars);\n            impacts = self.getVisualBeats(force_recompute = True, **peak_vars);\n        else:\n            # impacts = self.getFeature('visible_impacts');\n            impacts = self.getVisualBeats();\n\n        if(time_range is not None):\n            impactseg = [];\n            for i in impacts:\n                if(i.start>time_range[0] and i.start < time_range[1]):\n                    impactseg.append(i);\n            impacts = impactseg;\n\n\n        if (search_tempo is not None):\n            tempo = search_tempo;\n            beat_time = np.true_divide(60.0, tempo);\n            sequences = VisualBeat.PullOptimalPaths_Basic(impacts, target_period=beat_time, unary_weight=unary_weight,\n                                                      binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                      window_size=search_window);\n\n        elif(target_period is not None):\n            sequences = VisualBeat.PullOptimalPaths_Basic(impacts, target_period=target_period, unary_weight=unary_weight,\n                                                          binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                          window_size=search_window);\n        else:\n            sequences = VisualBeat.PullOptimalPaths_Autocor(impacts, unary_weight=unary_weight, binary_weight=binary_weight,\n                                                        break_on_cuts=break_on_cuts, window_size=search_window);\n\n        r_sequences = [];\n\n        if(min_beat_limit is None):\n            min_beat_limit = 2;\n        if(max_beat_limit is None):\n            max_beat_limit = len(impacts)+1;\n\n        for S in sequences:\n            if ((len(S) > min_beat_limit) and (len(S) < max_beat_limit)):\n                r_sequences.append(S);\n\n        if(not unsorted):\n            r_sequences.sort(key=len, reverse=True);\n            if(n_return is not None):\n                r_sequences = r_sequences[:n_return];\n        if(print_summary):\n            print((\"{} segments\".format(len(r_sequences))));\n            for s in range(len(r_sequences)):\n                print((\"Segment {} has {} beats\".format(s, len(r_sequences[s]))));\n\n        return r_sequences;\n\n\n    def printVisualBeatSequences(self,\n                                 search_tempo=None,\n                                 target_period=None,\n                                 search_window=None,\n                                 min_beat_limit=None,\n                                 max_beat_limit=None,\n                                 unary_weight=None,\n                                 binary_weight=None,\n                                 break_on_cuts=None,\n                                 peak_vars=None,\n                                 n_return = None,\n                                 time_range=None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param target_period:\n        :param search_tempo:\n        :param search_window:\n        :param beat_limit:\n        :param unary_weight:\n        :param binary_weight:\n        :param break_on_cuts:\n        :param n_return:\n        :param peak_vars:\n        :param time_range:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        sorted = True;\n\n        sequence_args = dict(\n            search_tempo=search_tempo,\n            target_period=target_period,\n            search_window=search_window,\n            min_beat_limit=min_beat_limit,\n            max_beat_limit=max_beat_limit,\n            unary_weight=unary_weight,\n            binary_weight=binary_weight,\n            break_on_cuts=break_on_cuts,\n            peak_vars=peak_vars,\n            n_return=n_return,\n            time_range=time_range);\n\n        seqs = self.getVisualBeatSequences(**sequence_args)\n        print((\"sequence arguments were:\\n{}\".format(sequence_args)));\n        print((\"There were {} sequences total\".format(len(seqs))));\n        nclips = 0;\n        rsegments = [];\n        for S in seqs:\n            if (len(S) > 1):\n                nclips = nclips + 1;\n                rsegments.append(S);\n\n        # rsegments.sort(key=len, reverse=True);\n        # if (n_return is not None):\n        #     rsegments = rsegments[:n_return];\n\n        Event.PlotSignalAndEvents(self.getFeature('impact_envelope'),  sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=rsegments[0],  time_range=time_range);\n        return rsegments;\n\n    def plotEvents(self, events, time_range = 'default', **kwargs):\n        time_range_use = time_range;\n        if(time_range.lower() == 'default'):\n            time_range_use = [0,0];\n            time_range_use[0] = events[0].start-1;\n            time_range_use[1] = events[-1].start+1;\n\n        signal = self.getFeature('local_rhythmic_saliency');\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate * VB_UPSAMPLE_FACTOR, events=events, time_range=time_range_use, **kwargs);\n        plt.xlabel('Time (s)')\n        return mplt;\n\n    def plotCutEvents(self, **kwargs):\n        signal = self.getFeature('impact_envelope');\n        events = self.getFeature('cut_events', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n\n    def plotVisibleImpacts(self, **kwargs):\n        signal = self.getFeature('impact_envelope');\n        events = self.getFeature('visible_impacts', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n    def plotImpactEnvelope(self, **kwargs):\n        signal = self.getFeature('local_rhythmic_saliency');\n        # events = self.getFeature('visual_beats', **kwargs);\n        events = None;\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n    def plotVisualBeats(self, **kwargs):\n        signal = self.getFeature('local_rhythmic_saliency');\n        events = self.getFeature('visual_beats', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n\n    def loadFlowFeatures(self):\n        self.load(features_to_load=['directogram_powers', 'directogram']);\n\n    FEATURE_FUNCS['local_rhythmic_saliency'] = getLocalRhythmicSaliency;\n    FEATURE_FUNCS['directogram_powers'] = getDirectogramPowers;\n    FEATURE_FUNCS['directogram'] = getDirectogram;\n    FEATURE_FUNCS['impact_envelope'] = getVisibleImpactEnvelope;\n    FEATURE_FUNCS['impact_envelope_powers'] = getVisibleImpactEnvelopePowers;\n    FEATURE_FUNCS['visible_impacts'] = getVisibleImpacts;\n    FEATURE_FUNCS['visual_beats'] = getVisualBeats;\n    # FEATURE_FUNCS['backward_visual_beats'] = getBackwardVisualBeats;\n    # FEATURE_FUNCS['forward_visual_beats'] = getForwardVisualBeats;\n    FEATURE_FUNCS['backward_visual_impact_envelope'] = getBackwardVisibleImpactEnvelope;\n    FEATURE_FUNCS['both_way_visual_impact_envelope'] = getBothWayVisibleImpactEnvelope;\n    FEATURE_FUNCS['forward_visual_impact_envelope'] = getForwardVisibleImpactEnvelope;\n    FEATURE_FUNCS['directional_flux'] = getDirectionalFlux;\n    FEATURE_FUNCS['visual_tempogram'] = getVisualTempogram;\n    FEATURE_FUNCS['cut_events']=getCutEvents;\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VisBeatDefines.py",
    "content": "VB_DEBUG = True;\n\nDEFAULT_TEMPOGRAM_WINDOW_SECONDS = 5;\nAUDIO_DEFAULT_HOP_LENGTH = 512;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VisBeatExampleVideo.py",
    "content": "import os\nfrom visbeat3.SourceLocationParser import ParseSourseLocation\n\nclass VisBeatExampleVideo(object):\n    def __init__(self, name, url, start_beat=None, end_beat = None, display_name = None, code=None, leadin=None, **kwargs):\n        self.name = name;\n        self.url = url;\n        self.start_beat = start_beat;\n        self.end_beat = end_beat;\n        self._display_name = display_name;\n        self._code = code;\n        self.leadin = leadin;\n        for k in kwargs:\n            setattr(self, k, kwargs[k]);\n        if(code is None):\n            sloc = ParseSourseLocation(self.url);\n            self._code = sloc.code;\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        return self._getCode();\n    def _getCode(self):\n        return self._code;\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        self._code = value;\n    # </editor-fold>\n\n    # def _ytEmbedCode(self):\n\n    # <editor-fold desc=\"Property: 'display_name'\">\n    @property\n    def display_name(self):\n        return self._getDisplayName();\n    def _getDisplayName(self):\n        if(self._display_name is None):\n            return self.name;\n        else:\n            return self._display_name;\n    # </editor-fold>\n\n\n    def _ytWatchURL(self):\n        return 'https://www.youtube.com/watch?v={}'.format(self.code);\n\n    def _ytEmbedURL(self, autoplay=None):\n        s = 'https://www.youtube.com/embed/{}'.format(self.code);\n        if(autoplay):\n            s = s+'?autoplay=1';\n        return s;\n\n    def _ytThumbURL(self):\n        return 'https://ytimg.googleusercontent.com/vi/{}/default.jpg'.format(self.code);\n\n    def _fancyBoxCode(self, with_label = None):\n        \"\"\"\"\"\"\n        s = HTMLCode();\n        if(with_label):\n            s.addLine(\"<figure>\")\n        s.addLine('<a class=\"vb_youtube_fancybox\" data-fancybox href=\"{watchurl}\"><img alt=\"{alt_name}\" src=\"{thumburl}\" /></a>'.format(watchurl=self._ytWatchURL(),\n                                                                                                                                        alt_name = self.display_name,\n                                                                                                                                        thumburl = self._ytThumbURL()))\n\n        if(with_label):\n            s.addLine('<figcaption>');\n            # s.addLine('<a href=\"{watchurl}\">{displayname}</a>'.format(self.url, self.display_name));\n            s.addLine('{displayname}'.format(displayname=self.display_name));\n            s.addLine('</figcaption>')\n            s.addLine('</figure>');\n        return s.string;\n\n\nfrom bs4 import BeautifulSoup\nclass HTMLCode(object):\n    def __init__(self, start_string=None):\n        self._code = \"\";\n        self._lines = [];\n        if(start_string is not None):\n            self.add(start_string)\n        self._soup = None;\n\n    # <editor-fold desc=\"Property: 'string'\">\n    @property\n    def string(self):\n        return self._getString();\n    def _getString(self):\n        return BeautifulSoup(self.code).prettify();\n\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        return self._getCode();\n    def _getCode(self):\n        return self._code;\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        self._code = value;\n    # </editor-fold>\n\n\n    # <editor-fold desc=\"Property: 'soup'\">\n    @property\n    def soup(self):\n        return self._getSoup();\n    def _getSoup(self):\n        if(self._soup is None):\n            self._makeSoup();\n        return self._soup;\n\n    def _makeSoup(self):\n        self._soup = BeautifulSoup(self.code, 'html.parser');\n    # @soup.setter\n    # def soup(self, value):\n    #     self._setSoup(value);\n    # def _setSoup(self, value):\n    #     self._soup = value;\n    # </editor-fold>\n\n    def add(self, s):\n        self.code = self.code+s;\n\n    def addLine(self, s):\n        self.code = self.code+'\\n'+s;\n\n    def startTable(self, id=None, class_ = None, **kwargs):\n        targs = dict(table_width=\"80%\", border=1, cellspacing=1, cellpadding=1)\n        targs.update(kwargs);\n        s = '<table ';\n        if(id is not None):\n            s = s+'id=\"{}\" '.format(id);\n        if(class_ is not None):\n            s = s + 'class=\"{}\" '.format(class_);\n        s = s+'width=\"{table_width}\" border=\"{border}\" cellspacing=\"{cellspacing}\" cellpadding=\"{cellpadding}\">'.format(**targs);\n        self.addLine(s);\n        self.addLine('<tbody>');\n\n    def endTable(self):\n        self.addLine(\"</tbody>\");\n        self.addLine(\"</table>\");\n\n    def startRow(self):\n        self.addLine('<tr>');\n\n    def endRow(self):\n        self.addLine('</tr>');\n\n    def addColumnLabel(self, label):\n        self.addLine('<th scope=\"col\">')\n        self.addLine(label);\n        self.addLine('</th>');\n\n    def addRowLabel(self, label):\n        self.addLine('<th scope=\"row\">')\n        self.addLine(label);\n        self.addLine('</th>');\n\n    def addRowCell(self, content):\n        self.addLine(\"<td>\");\n        self.addLine(\"<div class = 'rowcelldiv'>\")\n        self.addLine(content);\n        self.addLine(\"</div>\")\n        self.addLine(\"</td>\");\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VisBeatImports.py",
    "content": "from .VisBeatDefines import *\nfrom .AImports import *\nfrom .AObject import AObject\nimport numpy as np\nimport scipy as sp\n\nimport os\nimport imageio\n\nimport matplotlib\ntry:\n    import matplotlib.pyplot as plt\nexcept ImportError as e:\n    AWARN(\"matplotlib problem... if you are using conda try installing with 'conda install matplotlib'\")\n    matplotlib.use('agg');\n    import matplotlib.pyplot as plt\nimport matplotlib.style as ms\n\nimport io\nimport base64\nimport math\nfrom operator import truediv\nimport time\nimport shutil\nfrom time import gmtime, strftime, localtime\nimport librosa;\nfrom ._mediafiles import GetVBMarkPath\n\ndef local_time_string():\n    return strftime(\"%Y-%m-%d_%H:%M:%S\", localtime());\n\n\ndef VBWARN(message):\n    print(message)\n    #\n    # def send_warnings_to_print_red(message, category, filename, lineno):\n    #     print(colored('{} WARNING! file: {} Line:{}\\n{}'.format(category, filename, lineno, message), 'red'))\n    # old_showwarning = warnings.showwarning\n    # warnings.showwarning = send_warnings_to_print_red;\n\nVB_MACHINE_ID = None;\n# if(VB_MACHINE_ID):\n    # matplotlib.use('PS');\n\nISNOTEBOOK = False;\nif(runningInNotebook()):\n    ISNOTEBOOK = True;\n    import IPython;\n    import IPython.display\n    ms.use('seaborn-muted')\n    if(not runningInSpyder()):\n        get_ipython().magic('matplotlib inline')\n        from IPython.lib import kernel\n        connection_file_path = kernel.get_connection_file()\n        connection_file = os.path.basename(connection_file_path)\n        kernel_id = connection_file.split('-', 1)[1].split('.')[0]\n        # print(\"Kernel ID:\\n{}\".format(kernel_id));\n    from IPython.display import HTML\n    VBIPY = IPython;\n    #%matplotlib inline\n# else:\n    # matplotlib.use('PS');\n\n\ndef vb_get_ipython():\n    return VBIPY;\n\ndef clipping_params(clip_bins=30, clip_fraction=0.95):\n    return dict(clip_bins=clip_bins, clip_fraction=clip_fraction);\n\ndef get_hist_clipped(signal, clip_bins=30, clip_fraction=0.95):\n    holdshape = signal.shape[:];\n    sigrav = signal.copy().ravel();\n    sigh, sigb = np.histogram(sigrav, bins=clip_bins);\n    maxbini=np.argmax(sigh);\n    totalmass = np.sum(sigh);\n    total_included = truediv(sigh[maxbini],totalmass);\n    prevbini = maxbini;\n    nextbini=maxbini;\n    bins_included = 1;\n    icounter=0;\n    while(total_included<clip_fraction and bins_included<clip_bins):\n        if((prevbini>=0 and sigh[prevbini]==0) and (nextbini<(clip_bins) and sigh[nextbini]==0)):\n            prevbini=prevbini-1;\n            nextbini=nextbini+1;\n        else:\n            if((prevbini>=0 and sigh[prevbini]>0) or nextbini>=clip_bins):\n                prevbini=prevbini-1;\n            if((nextbini<(clip_bins) and sigh[nextbini]>0) or prevbini<0):\n                nextbini=nextbini+1;\n        included_segment=sigh[max(prevbini,0):min(nextbini+1, clip_bins)];\n        total_included = truediv(np.sum(included_segment), totalmass);\n        bins_included=len(included_segment);\n        icounter+=1;\n    clipsig = np.clip(a=sigrav, a_min=sigb[max(prevbini,0)], a_max=sigb[min(nextbini,clip_bins)]);\n    clipsig.shape=signal.shape\n    return clipsig;\n\ndef np_scale_to_range(data, value_range=None):\n    if(value_range is None):\n        value_range = [0.0,255.0];\n    d = data.copy().ravel();\n    currentmin=np.min(d);\n    currentmax=np.max(d);\n    currentscale = currentmax-currentmin;\n    if(currentscale==0):\n        VBWARN(\"CANNOT SCALE CONSTANT ARRAY TO RANGE\")\n        return;\n    divscale = truediv(1.0,currentscale);\n    newrange=(value_range[1]-value_range[0]);\n    d = (d*divscale)*newrange;\n    newmin = (currentmin*divscale)*newrange;\n    d = d-newmin+value_range[0]\n    d.shape=data.shape;\n    return d\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/VisualBeat.py",
    "content": "from .Event import *\n\nclass VisualBeat(Event):\n    def VBOBJECT_TYPE(self):\n        return 'VisualBeat';\n\n    def __init__(self, start=None, type=None, weight=None, index=None, unrolled_start = None, direction=0):\n        Event.__init__(self, start=start, type=type, weight=weight, index=index, unrolled_start=unrolled_start, direction=direction);\n\n    def initializeBlank(self):\n        Event.initializeBlank(self);\n        self.flow_histogram = None;\n        self.local_autocor = None;\n        self.sampling_rate = None;\n\n    def __str__(self):\n        return \"start:{}\\ntype:{}\\nweight:{}\\nindex:{}\\nunrolled_start:{}\\nis_active:{}\\n\".format(self.start, self.type, self.weight, self.index, self.unrolled_start, self.is_active);\n\n    # def toGUIDict(self, is_active=1):\n    #     return dict(start=self.start, index=self.index, is_active=None)\n\n    def toDictionary(self):\n        d=Event.toDictionary(self);\n        # d['start']=self.start;\n        # d['type']=self.type;\n        # d['weight']=self.weight;\n        # d['index']=self.index;\n        # d['unrolled_start']=self.unrolled_start;\n        d['flow_histogram']=self.flow_histogram;\n        d['local_autocor']=self.local_autocor;\n        d['sampling_rate']=self.sampling_rate;\n        return d;\n\n    def initFromDictionary(self, d):\n        Event.initFromDictionary(self, d);\n        self.start = d['start'];\n        self.type = d['type'];\n        self.weight = d['weight'];\n        self.index = d['index'];\n        self.unrolled_start = d['unrolled_start'];\n        self.flow_histogram = d.get('flow_histogram');\n        self.local_autocor = d.get('local_autocor');\n        self.sampling_rate = d.get('sampling_rate');\n\n\n    def clone(self, start=None):\n        if(start):\n            newv = VisualBeat(start = start, type=self.type, weight=self.weight, index=self.index);\n        else:\n            newv = VisualBeat(start = self.start, type=self.type, weight=self.weight, index=self.index);\n        newv.flow_histogram = self.flow_histogram.copy();\n        newv.local_autocor = self.local_autocor.copy();\n        newv.sampling_rate = self.sampling_rate;\n        return newv;\n\n    @staticmethod\n    def FromEvent(e):\n        if(isinstance(e,VisualBeat)):\n            return e.clone();\n        else:\n            return VisualBeat(start=e.start, type=e.type, weight=e.weight, index=e.index);\n\n    @staticmethod\n    def time_window_func(max_separation, break_on_cuts=None):\n        def window_func(a, b):\n            if(break_on_cuts and (a.type=='cut' or b.type=='cut')):\n                return False;\n            if(np.fabs(a.start-b.start)<max_separation):\n                return True;\n            else:\n                return False;\n        return window_func;\n\n    @staticmethod\n    def tempo_binary_objective(target_period, binary_weight=None):\n        if(binary_weight is None):\n            binary_weight = 1.0;\n        def objective_func(a, b):\n            T = np.fabs(a.start-b.start);\n            return -np.power(np.log(truediv(T,target_period)), 2.0)*binary_weight;\n        return objective_func;\n\n    @staticmethod\n    def autocor_binary_objective(binary_weight=None, **kwargs):\n        if (binary_weight is None):\n            binary_weight = 1.0;\n\n        def objective_func(a, b):\n            T = np.fabs(a.start - b.start);\n\n            # assert(a.sampling_rate), \"b has no sampling rate\"\n            # assert(b.sampling_rate), \"a has no sampling rate\"\n            abin = int(round(np.true_divide(T,a.sampling_rate)));\n            score = (a.local_autocor[abin] - 1);\n            if (T < 0.25):\n                score = -1;\n            if(T>3.75):\n                score=-1;\n            return binary_weight*score;\n\n        return objective_func;\n\n    @staticmethod\n    def angle_binary_objective(binary_weight=None, absolute=None):\n        if (binary_weight is None):\n            binary_weight = 1.0;\n        # if (angle_weight is None):\n        #     angle_weight = 0.0;\n\n        def objective_func(a, b):\n            # T = np.fabs(a.start - b.start);\n            # tempo_score = -np.power(np.log(truediv(T, target_period)), 2.0) * binary_weight;\n            # should mask out unary contribution from orthogonal angles\n            if(absolute):\n                return binary_weight * (np.fabs(np.dot(a.flow_histogram, b.flow_histogram)) - 0.70710678118);  # cos 45 degrees\n            else:\n                return binary_weight * (np.dot(a.flow_histogram, b.flow_histogram));  # cos 45 degrees\n        return objective_func;\n\n    @staticmethod\n    def Double(events, type=None):\n        doubled = [];\n        for e in range(1, len(events)):\n            halfstart = 0.5 * (events[e].start + events[e - 1].start);\n            newhevent = events[e].clone(start=halfstart);\n            if(type is not None):\n                newhevent.type = type;\n            doubled.append(newhevent);\n            doubled.append(events[e]);\n        return doubled;\n\n    @staticmethod\n    def weight_unary_objective(unary_weight=None):\n        if(unary_weight is None):\n            unary_weight = 1.0;\n        def getweight_func(b):\n            return unary_weight*b.weight;\n        return getweight_func;\n\n    @staticmethod\n    def PullOptimalPaths_Basic(vis_beats, target_period, unary_weight=None, binary_weight=None, window_size=None, break_on_cuts = None):\n        if(window_size is None):\n            window_size = DEFAULT_WINDOW_FACTOR*target_period;\n        binary_objective = VisualBeat.tempo_binary_objective(target_period=target_period, binary_weight = binary_weight);\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation = window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def PullOptimalPaths(vis_beats, unary_fn=None, binary_fn=None, window_fn=None,  target_period=None, unary_weight=None, binary_weight=None, window_size=None,\n                               break_on_cuts=None):\n        if (window_size is None):\n            window_size = DEFAULT_WINDOW_FACTOR * target_period;\n\n        if(binary_fn == 'autocor'):\n            binary_objective = VisualBeat.autocor_binary_objective(binary_weight=binary_weight);\n        elif(binary_fn == 'angle'):\n            binary_objective = VisualBeat.angle_binary_objective(binary_weight=binary_weight);\n        else:\n            binary_objective = VisualBeat.tempo_binary_objective(target_period=target_period, binary_weight=binary_weight);\n\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation=window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def PullOptimalPaths_Autocor(vis_beats, unary_weight=None, binary_weight=None, window_size=None,\n                               break_on_cuts=None, **kwargs):\n        if (window_size is None):\n            # assert(False), 'no window size provided'\n            # window_size = DEFAULT_WINDOW_FACTOR * target_period;\n            window_size = 200;\n            AWARN('NO WINDOWSIZE PROVIDED! PullOptimalPaths_Autocor');\n        binary_objective = VisualBeat.autocor_binary_objective(binary_weight=binary_weight);\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation=window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def DynamicProgramOptimalPaths(vis_beats, unary_objective_func, binary_objective_func, window_func):\n        class Node(object):\n            def __init__(self, object, prev_node=None):\n                self.object = object;\n                self.prev_node = prev_node;\n                self.cum_score=None;\n\n        nodes = [];\n        beats = Event.GetSorted(vis_beats);\n        Event.ApplyIndices(beats);\n\n        for b in beats:\n            nodes.append(Node(object=b));\n\n        nodes[0].prev_node = None;\n        nodes[0].cum_score = unary_objective_func(nodes[0].object);\n        current_segment = [];\n        segments = [];\n        for n in range(1,len(nodes)):\n            current_node = nodes[n];\n            current_segment.append(current_node);\n            options = [];\n            j = n-1;\n            while(j>=0 and window_func(current_node.object,nodes[j].object)):\n                options.append(nodes[j]);\n                j = j-1;\n            if(len(options)==0):\n                current_node.prev_node=None;\n                current_node.cum_score=unary_objective_func(current_node.object);\n                segments.append(current_segment);\n                current_segment = [];\n            else:\n                best_choice = options[0];\n                best_score = options[0].cum_score+binary_objective_func(current_node.object, best_choice.object);\n                for o in range(1,len(options)):\n                    score = options[o].cum_score+binary_objective_func(current_node.object, options[o].object);\n                    if(score>best_score):\n                        best_choice=options[o];\n                        best_score=score;\n                current_node.prev_node = best_choice;\n                current_node.cum_score = best_score+unary_objective_func(current_node.object);\n        if(len(current_segment)>0):\n            segments.append(current_segment);\n        sequences = [];\n        for S in segments:\n            seq = [];\n            max_node = S[0];\n            max_score = max_node.cum_score;\n            for n in range(len(S)):\n                if(S[n].cum_score>max_score):\n                    max_node = S[n];\n                    max_score = max_node.cum_score;\n\n            trace_node = max_node;\n            while(trace_node.prev_node is not None):\n                seq.append(trace_node.object);\n                trace_node=trace_node.prev_node;\n            seq.reverse();\n            sequences.append(seq);\n\n        return sequences;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/Warp.py",
    "content": "\n\nfrom .VisBeatImports import *\nfrom .EventList import *\nimport math\n\nDEFAULT_LEAD_TIME = 0;\nDEFAULT_TAIL_TIME = 0;\n\nclass Warp(AObject):\n    \"\"\"Warp (class): defines how one time signal should be warped to another. Given primarily as source/target events to be matched.\n        Attributes:\n            source_events: source events\n            target_events: target events\n    \"\"\"\n\n    def VBOBJECT_TYPE(self):\n        return 'Warp';\n\n    def __init__(self, path=None):\n        AObject.__init__(self, path=path);\n        if(path):\n            self.loadFile();\n\n\n    @staticmethod\n    def FromEvents(source_events, target_events):\n        w = Warp();\n        sevents = source_events;\n        if(isinstance(source_events, EventList)):\n            sevents = source_events.events;\n\n        tevents = target_events;\n        if(isinstance(target_events, EventList)):\n            tevents = target_events.events;\n\n        w.source_events=sevents;\n        w.target_events=tevents;\n        # w.repeatShorterEvents();\n        return w\n\n    @staticmethod\n    def FromEventLists(source_eventlist, target_eventlist):\n        w = Warp();\n        w.source_events = source_eventlist.events;\n        w.target_events = target_eventlist.events;\n        # w.repeatShorterEvents();\n        return w\n\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.source_events = [];\n        self.target_events = [];\n        # self.a_info['WarpType'] = 'Linear';\n        self.warp_func = None;  # Warp.LinearInterp;\n        # self.warp_func_st = None;\n        # self.warp_func_ts = None;\n\n\n    def getTargetStart(self, lead=None):\n        target_start = self.target_events[0].getStartTime();\n        if (lead is None):\n            lead = min(target_start, DEFAULT_LEAD_TIME);\n        return target_start - lead;\n\n\n    def getTargetEnd(self, lead=None):\n        lastind = min(len(self.source_events), len(self.target_events)) - 1;\n        return self.target_events[lastind].getStartTime() + DEFAULT_TAIL_TIME;\n\n\n    def getSourceStart(self):\n        source_start = self.source_events[0].getUnrolledStartTime();\n        return source_start;\n\n\n    def getSourceEnd(self):\n        lastind = min(len(self.source_events), len(self.target_events)) - 1;\n        return self.source_events[lastind].getUnrolledStartTime();\n\n\n    def getWarpedSourceStart(self, lead=None):\n        source_start = self.source_events[0].getUnrolledStartTime();\n        if (lead is None):\n            lead = min(source_start, DEFAULT_LEAD_TIME);\n        return self.warpSourceTime(source_start - lead);\n\n\n    def getWarpedSourceEnd(self, tail=None):\n        last_event = min(len(self.source_events), len(self.target_events)) - 1;\n        source_end = self.source_events[last_event].getUnrolledStartTime();\n        if (tail is None):\n            tail = DEFAULT_TAIL_TIME;\n        source_end = source_end + tail;\n        return self.warpSourceTime(source_end);\n\n\n    def setWarpFunc(self, warp_type, **kwargs):\n        if (warp_type == 'square'):\n            self.warp_func = [Warp.SquareInterp, Warp.SquareInterp];\n        elif (warp_type == 'linear'):\n            self.warp_func = [Warp.LinearInterp, Warp.LinearInterp];\n        elif (warp_type == 'cubic'):\n            self.warp_func = [Warp.CubicInterp, Warp.CubicInterp];\n        elif (warp_type == 'quad'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_Quadratic(), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_Quadratic(), **kwargs)];\n        elif (warp_type == 'mouth'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_Mouth(**kwargs), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_Mouth(**kwargs), **kwargs)];\n        elif (warp_type == 'weight'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_Weight(use_to_weights=None, **kwargs), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_Weight(use_to_weights=True, **kwargs), **kwargs)];\n        elif (warp_type == 'half_accel'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_P(p=0.5),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_P(p=0.5),\n                                      **kwargs)];\n        elif (warp_type == 'p'):\n            p = kwargs.get('p');\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_P(p=p),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_P(p=p),\n                                      **kwargs)];\n        elif (warp_type == 'target_time_source_fraction'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_targettime_sourcefraction(**kwargs),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_targettime_sourcefraction(**kwargs),\n                                      **kwargs)];\n        elif (warp_type == 'target_source_fractions'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_target_source_fractions(**kwargs),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_target_source_fractions(**kwargs),\n                                      **kwargs)];\n        elif (warp_type is not None):\n            self.warp_func = [warp_type, warp_type];\n\n        self.setInfo('WarpType', warp_type);\n        return;\n\n\n    def warpSourceTime(self, t):\n        return self.warp_func[0](t, a_events=self.source_events, b_events=self.target_events);\n\n\n    def warpSourceTimes(self, t):\n        tw = t.copy();\n        for a in range(len(t)):\n            tw[a] = self.warpSourceTime(t[a]);\n        return tw;\n\n\n    def warpTargetTime(self, t):\n        return self.warp_func[1](t, a_events=self.target_events, b_events=self.source_events);\n\n\n    def warpTargetTimes(self, t):\n        tw = t.copy();\n        for a in range(len(t)):\n            tw[a] = self.warpTargetTime(t[a]);\n        return tw;\n\n\n    def plot(self, xlim=None, sampling_rate=None, new_figure=None, render_control_points=True, render_labels=True,\n             time_range=None, full_source_range=None, **kwargs):\n        if (sampling_rate is None):\n            sampling_rate = 30;\n\n        source_duration = self.getSourceEnd() - self.getSourceStart();\n        old_frame_time = truediv(1.0, sampling_rate);\n        target_start = self.getTargetStart();\n        target_end = self.getTargetEnd();\n\n\n\n        # if(xlim is not None):\n        #     target_start=xlim[0]\n\n        target_duration = target_end - target_start;\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=False);\n\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(self.warpTargetTime(st));\n\n        if (new_figure):\n            fig = plt.figure();\n\n        unwarped_target_times = np.array(unwarped_target_times);\n        # unwarped_target_times = unwarped_target_times-unwarped_target_times[0]+target_start;\n        plt.plot(target_start_times, unwarped_target_times, '-');\n\n        if (render_control_points):\n            lastind = min(len(self.source_events), len(self.target_events)) - 1;\n            targeteventtimes = Event.ToStartTimes(self.target_events[:lastind]);\n            sourceeventtimes = Event.ToStartTimes(self.source_events[:lastind]);\n            plt.plot(targeteventtimes, sourceeventtimes, 'o', label='Control Points');\n        if (xlim is not None):\n            xrng = [xlim[0] + target_start, xlim[1] + target_start];\n            ylim = [self.warpTargetTime(xrng[0]), self.warpTargetTime(xrng[1])];\n            plt.xlim(xrng);\n            plt.ylim(ylim);\n\n        if (time_range is not None):\n            plt.xlim(time_range);\n\n        if (render_labels):\n            plt.ylabel('Source Time');\n            plt.xlabel('Target Time');\n\n        plt.title('Warp Curve')\n\n        if (new_figure is not None):\n            return fig;\n\n\n    def plotImage(self, xlim=None, sampling_rate=None):\n        if (sampling_rate is None):\n            sampling_rate = 30;\n        target_start = self.getTargetStart();\n        target_end = self.getTargetEnd() + 10;\n        target_duration = target_end - target_start;\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=True);\n\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(self.warpTargetTime(st));\n\n        unwarped_target_times = np.array(unwarped_target_times);\n        pim = Image.PlotImage(signal=unwarped_target_times, show_axis=True, xvals=target_start_times,\n                              sampling_rate=sampling_rate, events=self.target_events, xlime=[0, 100], ylims=[0, 110]);\n        return pim;\n\n\n    def repeatShorterEvents(self, endpoints=False):\n        n_events = max(len(self.source_events), len(self.target_events));\n        self.source_events = Event.RepeatToLength(self.source_events, n=n_events, endpoints=endpoints);\n        self.target_events = Event.RepeatToLength(self.target_events, n=n_events, endpoints=endpoints);\n\n\n    @staticmethod\n    def FromEvents(source_events, target_events):\n        w = Warp();\n        w.source_events = source_events;\n        w.target_events = target_events;\n        # w.repeatShorterEvents();\n        return w\n\n\n    @staticmethod\n    def LinearInterp(t, a_events, b_events):\n        n_events = min(len(a_events), len(b_events));\n        next_a_event_index = n_events;\n        for s in range(n_events):\n            if (t < a_events[s].start):\n                next_a_event_index = s;\n                break;\n\n        prev_a_event_time = 0;\n        prev_b_event_time = 0;\n        if (next_a_event_index > 0):\n            prev_a_event_time = a_events[next_a_event_index - 1].start;\n            prev_b_event_time = b_events[next_a_event_index - 1].start;\n\n        next_a_event_time = a_events[n_events - 1].start;\n        next_b_event_time = b_events[n_events - 1].start;\n        if (next_a_event_index < n_events):\n            next_a_event_time = a_events[next_a_event_index].start;\n            next_b_event_time = b_events[next_a_event_index].start;\n\n        a_event_gap = next_a_event_time - prev_a_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_a_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (a_event_gap == 0):\n            return prev_b_event_time + t_progress;\n\n        next_weight = t_progress / (1.0 * a_event_gap);\n        return (next_weight * next_b_event_time) + ((1.0 - next_weight) * prev_b_event_time);\n\n\n    # additional_points = [];\n    # for i in range(-10, 11):\n    #     additional_points.append([0.1 * i, 0.51])\n    @staticmethod\n    def plotWarpMethodTest(warp_type, additional_points=None, **kwargs):\n        sev = [];\n        tev = [];\n\n        pts = [[1.0, 1.0],\n               [-1.0, 1.0],\n               [0.5, 1.0],\n               [1.0, 0.5],\n               [-1.0, 0.5],\n               [0.5, 0.5],\n               [1.0, 0.3],\n               [-1.0, 0.3],\n               [0.5, 0.3]];\n\n        if (additional_points is not None):\n            pts = pts + additional_points;\n\n        currentt = [0.0, 0.0];\n        sev.append(Event(start=0.0));\n        tev.append(Event(start=0.0));\n        for p in pts:\n            currentt[0] = currentt[0] + p[0];\n            currentt[1] = currentt[1] + p[1];\n            sev.append(Event(start=currentt[0]));\n            tev.append(Event(start=currentt[1]));\n\n        # warp_type = 'target_time_source_fraction';\n        # other_params['acceleration_target_time'] = 0.5;\n        # other_params['acceleration_source_fraction'] = 0.75;\n        warpf = Warp.FromEvents(sev, tev);\n        warpf.setWarpFunc(warp_type, **kwargs);\n\n        warpf.plot()\n\n\n    @staticmethod\n    def SquareInterp(t, a_events, b_events):\n        n_events = min(len(a_events), len(b_events));\n        next_a_event_index = n_events;\n        for s in range(n_events):\n            if (t < a_events[s].start):\n                next_a_event_index = s;\n                break;\n\n        prev_a_event_time = 0;\n        prev_b_event_time = 0;\n        if (next_a_event_index > 0):\n            prev_a_event_time = a_events[next_a_event_index - 1].start;\n            prev_b_event_time = b_events[next_a_event_index - 1].start;\n\n        next_a_event_time = a_events[n_events - 1].start;\n        next_b_event_time = b_events[n_events - 1].start;\n        if (next_a_event_index < n_events):\n            next_a_event_time = a_events[next_a_event_index].start;\n            next_b_event_time = b_events[next_a_event_index].start;\n\n        a_event_gap = next_a_event_time - prev_a_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_a_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (a_event_gap == 0):\n            return prev_b_event_time + t_progress;\n\n        progress_frac = t_progress / (1.0 * a_event_gap);\n        next_weight = math.pow(progress_frac, 2);\n        # accel = 3;\n        # bweight = math.pow(progress_frac,accel);\n        # aweight = math.pow(1.0-progress_frac,accel);\n        # sumweight = aweight+bweight;\n        # next_weight=bweight/sumweight;\n        return (next_weight * next_b_event_time) + ((1.0 - next_weight) * prev_b_event_time);\n\n\n    @staticmethod\n    def GetEventWarpFunc(from_events, to_events, f, lead_time=None, **kwargs):\n        start_cap_time = min(from_events[0].start, to_events[0].start);\n        if (lead_time is not None):\n            start_cap_time = min(start_cap_time, lead_time);\n        n_events = min(len(from_events), len(to_events));\n        # f_events = Event.GetUnrolledList(from_events[:n_events], assert_on_folds=True);\n        f_events = Event.GetUnrolledList(from_events[:n_events]);\n        t_events = Event.GetUnrolledList(to_events[:n_events]);\n\n        def rfunc(t, **kwargs):\n            next_f_event_index = n_events - 1;\n            for e in range(n_events):\n                if (t < f_events[e].unrolled_start):\n                    next_f_event_index = e;\n                    break;\n\n            if (next_f_event_index == 0):\n                from_cap_event = Event(start=f_events[0].start - start_cap_time, weight=0, type='startcap');\n                to_cap_event = Event(start=t_events[0].start - start_cap_time, weight=0, type='startcap')\n                return f(t, f_neighbors=[from_cap_event, f_events[0]], t_neighbors=[to_cap_event, t_events[0]]);\n\n            else:\n                return f(t,\n                         f_neighbors=[f_events[next_f_event_index - 1], f_events[next_f_event_index]],\n                         t_neighbors=[t_events[next_f_event_index - 1], t_events[next_f_event_index]]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Quadratic():\n        def rfunc(t, f_neighbors, t_neighbors, **kwargs):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            next_weight = math.pow(progress_frac, 2);\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Weight(use_to_weights=None, **kwargs):\n        print(\"USING WEIGHT-BASED WARP\");\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            if (use_to_weights):\n                weight = t_neighbors[1].weight;\n            else:\n                weight = f_neighbors[1].weight;\n\n            p = 1.0 - weight;\n            # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n            a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n            if (progress_frac < p):\n                next_weight = a * progress_frac;\n            else:\n                next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_P(p=None, **kwargs):\n        if (p is None):\n            p = 0.5;\n        print((\"USING P WARP with P={}\".format(p)));\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n            # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n            a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n            if (progress_frac < p):\n                next_weight = a * progress_frac;\n            else:\n                next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Mouth(p_acceleration_time=0.1, **kwargs):\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            if (f_neighbors[1].type == 'mouth_open' or t_neighbors[1].type == 'mouth_open'):\n                p = 1.0 - truediv(p_acceleration_time, to_event_gap);\n                if (p < 0):\n                    next_weight = math.pow(progress_frac, 2);\n                else:\n                    # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n                    a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n                    if (progress_frac < p):\n                        next_weight = a * progress_frac;\n                    else:\n                        next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            else:\n                next_weight = progress_frac;\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_targettime_sourcefraction(acceleration_target_time=0.1, acceleration_source_fraction=0.8, **kwargs):\n        \"\"\"\n        This assumes that you are mapping from the target to the source, as is the most common use case.\n        :param acceleration_target_time: amount of from time to spend accelerating\n        :param acceleration_source_fraction: fraction of source to accelerate through\n        :return:\n        \"\"\"\n        lin_source_fraction = 1.0 - acceleration_source_fraction;\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return to_times[\n                           0] + t_progress;  # is this right? doesnt seem to come up, not sure what behavior should be looking back on it...\n\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            time_left = from_event_gap - t_progress;\n\n            p = 1.0 - truediv(acceleration_target_time, from_event_gap);\n            p2 = p * p;\n            q = 1.0 - acceleration_source_fraction;\n\n            if (acceleration_target_time >= from_event_gap or q > (p2)):\n                next_weight = math.pow(progress_frac, 2);\n            elif (time_left >= acceleration_target_time):\n                lin_t_progress_frac = truediv(t_progress, from_event_gap - acceleration_target_time);\n                next_weight = lin_t_progress_frac * lin_source_fraction;\n            else:\n                pdnom = (p2 - 2.0 * p + 1.0)\n\n                # I just used matlab to symbolic inverse matrix of equations, then simplified by hand\n                a = ((1.0 - q) / pdnom) + (q / (p * (p - 1)));\n                b = ((2 * p * (q - 1)) / pdnom) - ((q * (p + 1)) / (p2 - p))\n                # c = ((p2 - (q * (2 * p - 1))) / pdnom) + (q / (p - 1));\n                c = 1 - a - b;\n\n                next_weight = a * progress_frac * progress_frac + b * progress_frac + c;\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_target_source_fractions(acceleration_target_fraction=0.8, acceleration_source_fraction=0.9, **kwargs):\n        \"\"\"\n        This assumes that you are mapping from the target to the source, as is the most common use case.\n        :param acceleration_target_fraction: fraction of target to spend accelerating\n        :param acceleration_source_fraction: fraction of source to accelerate through\n        :return:\n        \"\"\"\n        lin_source_fraction = 1.0 - acceleration_source_fraction;\n\n\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            print(acceleration_target_fraction)\n            print(acceleration_source_fraction)\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return to_times[\n                           0] + t_progress;  # is this right? doesnt seem to come up, not sure what behavior should be looking back on it...\n\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            time_left = from_event_gap - t_progress;\n\n            p = 1.0 - acceleration_target_fraction;\n            p2 = p * p;\n            q = 1.0 - acceleration_source_fraction;\n\n            if (acceleration_target_fraction >= 1 or q > (p2)):\n                next_weight = math.pow(progress_frac, 2);\n            elif (progress_frac <= p):\n                lin_t_progress_frac = truediv(t_progress, p * from_event_gap);\n                next_weight = lin_t_progress_frac * lin_source_fraction;\n            else:\n                pdnom = (p2 - 2.0 * p + 1.0)\n\n                # I just used matlab to symbolic inverse matrix of equations, then simplified by hand\n                a = ((1.0 - q) / pdnom) + (q / (p * (p - 1)));\n                b = ((2 * p * (q - 1)) / pdnom) - ((q * (p + 1)) / (p2 - p))\n                # c = ((p2 - (q * (2 * p - 1))) / pdnom) + (q / (p - 1));\n                c = 1 - a - b;\n\n                next_weight = a * progress_frac * progress_frac + b * progress_frac + c;\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_AB(const_factor, quad_factor, **kwargs):\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            next_weight = math.pow(progress_frac, 2);\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n\n    @staticmethod\n    def ABWarp():\n        next_from_event_time = from_events[n_events - 1].start;\n        next_to_event_time = to_events[n_events - 1].start;\n        if (next_from_event_index < n_events):\n            next_from_event_time = from_events[next_from_event_index].start;\n            next_to_event_time = to_events[next_to_event_index].start;\n\n        from_event_gap = next_from_event_time - prev_from_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_from_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (from_event_gap == 0):\n            return prev_to_event_time + t_progress;\n\n        progress_frac = t_progress / (1.0 * from_event_gap);\n        next_weight = math.pow(progress_frac, 2);\n        return (next_weight * next_to_event_time) + ((1.0 - next_weight) * prev_to_event_time);\n\n\n    @staticmethod\n    def CubicInterp(t, a_events, b_events):\n        # def CubicInterp(a_events, b_events, t):\n        f = Warp.CubicInterpFunc(a_events=a_events, b_events=b_events);\n        return f(t);\n\n\n    @staticmethod\n    def LinearInterpFunc(a_events, b_events):\n        if (a_events[0].start > 0):\n            ae = np.concatenate((np.asarray([0]), Event.ToStartTimes(a_events)));\n        else:\n            ae = Event.ToStartTimes(a_events);\n        be = Event.ToStartTimes(b_events);\n        if (len(be) > len(ae)):\n            be = be[:len(ae)];\n        elif (len(ae) > len(be)):\n            ae = ae[:len(be)];\n        return sp.interpolate.interp1d(ae, be, 'linear', bounds_error=False, fill_value='extrapolate');\n\n\n    @staticmethod\n    def CubicInterpFunc(a_events, b_events):\n        event_times = Event.ToStartTimes(a_events);\n        wevent_times = Event.ToStartTimes(b_events);\n        minlen = min(len(event_times), len(wevent_times));\n        event_times = event_times[:minlen];\n        wevent_times = wevent_times[:minlen];\n        splinecap = np.arange(0, 1, 0.25);\n\n        spline_times = np.concatenate((splinecap + event_times[0] - 1, event_times));\n        wspline_times = np.concatenate((splinecap + wevent_times[0] - 1, wevent_times));\n\n        spline_times = np.append(spline_times, splinecap + 0.5 + spline_times[-1]);\n        wspline_times = np.append(wspline_times, splinecap + 0.5 + wspline_times[-1]);\n\n        # get spline to translate initial times to warped times\n        splineX = sp.interpolate.interp1d(spline_times, wspline_times, kind='cubic', bounds_error=False,\n                                          fill_value='extrapolate');\n        return splineX;\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/__init__.py",
    "content": "\nfrom .VisBeatImports import *\nfrom .Video import *\nfrom .VideoClip import *\nfrom .VideoSource import *\nfrom .VisBeatExampleVideo import VisBeatExampleVideo\nimport re\nimport os;\nimport shutil\n\n\nfrom .SourceLocationParser import ParseSourseLocation\n\nVISBEAT_ASSETS_DIR = './VisBeatAssets/';\n\nfrom . import fileui\nfileui.INITIAL_DIR = VISBEAT_ASSETS_DIR;\n\n\ndef SetAssetsDir(assets_dir):\n    global VISBEAT_ASSETS_DIR;\n    VISBEAT_ASSETS_DIR = assets_dir;\n    make_sure_dir_exists(assets_dir);\n    AINFORM(\"VISBEAT_ASSETS_DIR set to {}\".format(VISBEAT_ASSETS_DIR));\n    make_sure_dir_exists(GetVideoSourcesDir());\n    temp_dir = os.path.join(VISBEAT_ASSETS_DIR, 'TEMP_FILES'+os.sep);\n    make_sure_dir_exists(temp_dir);\n    Video.VIDEO_TEMP_DIR = temp_dir;\n    fileui.INITIAL_DIR = VISBEAT_ASSETS_DIR;\n\ndef GetAssetsDir():\n    return VISBEAT_ASSETS_DIR;\n\ndef GetVideoSourcesDir():\n    video_sources_dir = os.path.join(GetAssetsDir(), 'VideoSources'+os.sep);\n    make_sure_dir_exists(video_sources_dir);\n    return video_sources_dir;\n\ndef PullVideo(name=None, source_location=None, max_height=240, **kwargs):\n    if(isinstance(name, VisBeatExampleVideo)):\n        assert(source_location is None), 'Provided VisBeatExampleVideo and source location? What are you trying to do?';\n        source_location = name.url;\n        vname = name.name;\n    elif(name is None):\n        assert(source_location is not None), \"Must provide an argument to pullvideo\";\n        sloc = ParseSourseLocation(source_location);\n        vname =sloc.code;\n    else:\n        vname = name;\n\n    vs = GetVideoSource(vname);\n    if(vs and vs.source_location==source_location):\n        v = vs.getVersion(max_height=max_height);\n        v.load(features_to_load = 'all');\n        return v;\n    \n    print(\"destination:\", GetVideoSourcesDir(), \"name:\", vname, \"source_location:\", source_location)\n    vs = VideoSource.NewVideoSource(destination=GetVideoSourcesDir(), name=vname, source_location=source_location, max_height=max_height, **kwargs);\n    v = vs.getVersion(max_height=max_height);\n    return v;\n\ndef ClipVideo(video, time_range, max_height=240):\n    video_fullres = video.source.getVersion();\n    vclip = video_fullres.VideoClip(start=time_range[0], end=time_range[1]);\n    vcdir = video.source.getDirForVersion(version_label='{}_{}'.format(str(time_range[0]), str(time_range[1])), version_group='Clips');\n    make_sure_dir_exists(vcdir);\n    vcname = video.getName() + 'clip_{}_{}'.format(str(time_range[0]), str(time_range[1]));\n    vcpath = os.path.join(vcdir, vcname+'.mp4');\n    vclip.write(output_path=vcpath);\n    vs = VideoSource.NewVideoSource(destination=GetVideoSourcesDir(), name=vcname, source_location=vcpath);\n    return vs.getVersion(max_height=max_height);\n\n\ndef GetVideoSource(name):\n    vname = name;\n    if (isinstance(name, VisBeatExampleVideo)):\n        vname = name.name;\n    path = os.path.join(GetVideoSourcesDir(), vname) + os.sep;\n    if (os.path.isdir(path)):\n        return VideoSource(path=path);\n\ndef LoadVideo(name, max_height=240):\n    vname = name;\n    if (isinstance(name, VisBeatExampleVideo)):\n        vname = name.name;\n\n    path = os.path.join(GetVideoSourcesDir(), vname)+os.sep;\n    if(os.path.isdir(path)):\n        vs = VideoSource(path=path);\n        v = vs.getVersion(max_height=max_height);\n        v.load(features_to_load = 'all');\n        return v;\n    else:\n        return None;\n\ndef Dancefer(source_video, target,\n             synch_video_beat=0, synch_audio_beat=0,\n             beat_offset = 0, leadin = None, nbeats=None,\n             source_harmonic = None, target_harmonic = None, source_harmonic_offset=None, target_harmonic_offset=None,\n             force_recompute=None, warp_type = 'quad',\n             name_tag=None, name_tag_prefix=None, output_path = None,\n             **kwargs):\n    \"\"\"\n\n    :param source_video: video to warp\n    :param target: music to warp to\n    :param synch_video_beat: integer specifying a beat (as in the nth beat) from the video to synchronize with synch_audio_beat\n    :param synch_audio_beat: integer specifying a beat (as in the nth beat) from the video to synchronize with synch_video_beat\n    :param beat_offset: Lets you offset which beats you want to render. This is mostly for testing different parts of an output.\n    :param leadin: how many beats before the synch beats to render\n    :param nbeats: lets you restrict output to rendering n beats\n    :param source_harmonic: can be None, 'half', or 'double'. 'half' will use every other beat, which you can offset with source_harmonic_offset. 'double' will add an additional beat between every consecutive beat. update - added 'third' for waltzes.\n    :param target_harmonic: can be None, 'half', or 'double'. 'half' will use every other beat, which you can offset with source_harmonic_offset. 'double' will add an additional beat between every consecutive beat. update - added 'third' for waltzes.\n    :param source_harmonic_offset: optional offset for harmonic\n    :param target_harmonic_offset: optional offset for harmonic\n    :param force_recompute:\n    :param warp_type:\n    :param name_tag:\n    :param name_tag_prefix:\n    :param output_path:\n    :param kwargs:\n    :return:\n    \"\"\"\n\n\n    if((output_path is not None) and (not force_recompute)):\n        if(os.path.exists(output_path)):\n            return Video(output_path);\n\n    if(isinstance(target, Video)):\n        target_audio = target.getAudio();\n    else:\n        target_audio = target;\n\n\n    synchaudio = synch_audio_beat;\n    synchvideo = synch_video_beat;\n    lead_in = leadin;\n    if(lead_in is None):\n        lead_in = min(synchaudio, synchvideo);\n    elif(isinstance(lead_in, str) and lead_in[0]=='<'):\n        # lead_in = min(synchaudio, synchvideo, int(lead_in));\n        lead_in = min(synchaudio, int(lead_in));\n\n    start_audio_beat = synchaudio-lead_in;\n    start_video_beat = synchvideo-lead_in;\n\n    if(beat_offset and beat_offset>0):\n        start_audio_beat = start_audio_beat+beat_offset;\n        start_video_beat = start_video_beat+beat_offset;\n\n    print((\"Warping {} to {}\".format(source_video.getName(), target_audio.getName())));\n    bitrate = None;\n    vbeats = source_video.audio.getBeatEvents()\n    tbeats = target_audio.getBeatEvents()\n\n    if(start_video_beat < 0):\n        if(synchvideo == 0):\n            vbeats = [vbeats[0].clone()]+vbeats;\n            vbeats[0].start = vbeats[0].start-(vbeats[2].start-vbeats[1].start);\n        vbadd = Event.SubdivideIntervals(vbeats[:2], -start_video_beat);\n        vbeats = vbadd+vbeats[2:];\n        start_video_beat = 0;\n\n\n    vbeats = vbeats[start_video_beat:];\n    tbeats = tbeats[start_audio_beat:];\n\n    if(source_harmonic=='half'):\n        vbeats = Event.Half(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'third'):\n        vbeats = Event.Third(vbeats, source_harmonic_offset);\n    elif(source_harmonic == 'double'):\n        vbeats = Event.Double(vbeats);\n\n    if (target_harmonic == 'half'):\n        tbeats = Event.Half(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'third'):\n        tbeats = Event.Third(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'double'):\n        tbeats = Event.Double(tbeats);\n\n\n    if(nbeats):\n        print((\"Rendering {} beats of result\".format(nbeats)))\n        if(len(vbeats)>nbeats):\n            vbeats = vbeats[:nbeats];\n            print((len(vbeats)))\n        if(len(tbeats)>nbeats):\n            tbeats = tbeats[:nbeats];\n            print((len(tbeats)))\n    else:\n        if(vbeats[-1].start<source_video.getDuration()):\n            print(tbeats)\n            print((\"length of tbeats is: {}\".format(len(tbeats))));\n            print((\"start_video_beat: {}, start_audio_beat: {}\".format(start_video_beat, start_audio_beat)))\n            newbeat = vbeats[-1].clone();\n            deltatime = source_video.getDuration()-newbeat.start;\n            newbeat.start = source_video.getDuration();\n            target_newbeat = tbeats[-1].clone();\n            target_newbeat.start = min(target_newbeat.start+deltatime, target_audio.getDuration());\n            tbeats.append(target_newbeat);\n\n    if(warp_type is 'weight'):\n        vbeats = source_video.visualBeatsFromEvents(vbeats);\n\n    if(name_tag is None):\n        name_tag = warp_type+'_sab_'+str(start_audio_beat)+'_svb_'+str(start_video_beat);\n    if(name_tag_prefix is not None):\n        name_tag = name_tag+name_tag_prefix;\n\n    warp_args = dict(target=target_audio,\n                     source_events=vbeats,\n                     target_events = tbeats,\n                     warp_type=warp_type,\n                     force_recompute=force_recompute,\n                     name_tag = name_tag)\n    if(bitrate):\n        warp_args.update(dict(bitrate=bitrate));\n\n    warp_args.update(kwargs);\n    warped_result = source_video.getWarped(**warp_args);\n\n    if(output_path):\n        final_output_path = output_path;\n        if(os.path.isfile(final_output_path)):\n            output_filename = os.path.basename(output_path);\n            name_parts = os.path.splitext(output_filename);\n            output_filename_base = name_parts[0];\n            output_directory_path = os.path.dirname(output_path);\n            if (output_directory_path == ''):\n                output_directory_path = '.'\n            output_ext = name_parts[1];\n            ntry = 1;\n            tryname = output_filename_base+ '_' + str(ntry);\n            while (os.path.isfile(os.path.join(output_directory_path, tryname+output_ext)) and ntry<100):\n                ntry = ntry+1;\n                tryname = output_filename_base + '_' + str(ntry);\n\n            final_output_path = os.path.join(output_directory_path, tryname + output_ext);\n        shutil.copy2(src=warped_result.getPath(), dst=final_output_path);\n        n_frames_total = warped_result.num_frames_total;\n        warp_used = warped_result.getInfo('warp_used');\n        warped_result_final = Video(path = final_output_path, num_frames_total=n_frames_total);\n        warped_result_final.setInfo(label='warp_used', value=warp_used);\n        os.remove(warped_result.getPath())\n        warped_result = warped_result_final;\n    return warped_result;\n\ndef get_temp_file_path(final_file_path=\"TEMP\", temp_dir_path = None):\n    pparts = os.path.split(final_file_path);\n    destfolder = pparts[0]+os.sep;\n    tempdir = temp_dir_path;\n    if(tempdir is None):\n        tempdir='.';\n    destfolder=pathstring(tempdir+os.sep);\n    tempname = 'TEMP_'+pparts[1];\n    temptry = 0;\n    while(os.path.isfile(destfolder+tempname)):\n        temptry=temptry+1;\n        tempname = 'TEMP{}_'.format(temptry)+pparts[1];\n    return pathstring(destfolder+tempname);\n\n\ndef AutoDancefer(source, target, output_path = None, synch_video_beat = 0, synch_audio_beat = 0, beat_offset = 0, **kwargs):\n    sourcev = PullVideo(source_location=source);\n    targetv = PullVideo(source_location=target);\n\n    result =  Dancefer(source_video=sourcev, target=targetv, output_path=output_path, force_recompute = True, synch_audio_beat=synch_audio_beat, synch_video_beat=synch_video_beat, beat_offset=beat_offset,**kwargs)\n    AINFORM(\"\\n\\n\\nResult saved to {}\\n\\n\\n\".format(result.getPath()));\n    return result;\n\n#########\n\n\ndef Dancify(source_video, target,\n            source_beats=None, target_beats=None,\n            synch_video_beat=0, synch_audio_beat=0,\n            beat_offset = 0, leadin = None, nbeats=None,\n            unfold_to_n=None,\n            source_harmonic = None, source_harmonic_offset=None,\n            target_harmonic = None, target_harmonic_offset=None,\n            force_recompute=None, warp_type = 'quad',\n            name_tag=None, name_tag_prefix=None, output_path = None,\n            momentum = 0.1,\n            **kwargs):\n    \"\"\"\n\n    :param source_video:\n    :param target:\n    :param source_beats:\n    :param target_beats:\n    :param synch_video_beat:\n    :param synch_audio_beat:\n    :param beat_offset:\n    :param leadin:\n    :param nbeats:\n    :param unfold_to_n:\n    :param source_harmonic:\n    :param target_harmonic:\n    :param source_harmonic_offset:\n    :param target_harmonic_offset:\n    :param force_recompute:\n    :param warp_type:\n    :param name_tag:\n    :param name_tag_prefix:\n    :param output_path:\n    :param momentum:\n    :param kwargs:\n    :return:\n    \"\"\"\n\n\n    if((output_path is not None) and (not force_recompute)):\n        if(os.path.exists(output_path)):\n            return Video(output_path);\n\n    if(isinstance(target, Video)):\n        target_audio = target.getAudio();\n    else:\n        target_audio = target;\n\n\n    synchaudio = synch_audio_beat;\n    synchvideo = synch_video_beat;\n    lead_in = leadin;\n    if(lead_in is None):\n        lead_in = min(synchaudio, synchvideo);\n    elif(isinstance(lead_in, str) and lead_in[0]=='<'):\n        # lead_in = min(synchaudio, synchvideo, int(lead_in));\n        lead_in = min(synchaudio, int(lead_in));\n\n    start_audio_beat = synchaudio-lead_in;\n    start_video_beat = synchvideo-lead_in;\n\n    if(beat_offset and beat_offset>0):\n        start_audio_beat = start_audio_beat+beat_offset;\n        start_video_beat = start_video_beat+beat_offset;\n\n    print((\"Warping {} to {}\".format(source_video.getName(), target_audio.getName())));\n    bitrate = None;\n    vbeats = source_beats;\n    if(source_beats is None):\n        vbeats = source_video.getVisualBeats();\n\n\n    tbeats = target_beats;\n    if(target_beats is None):\n        tbeats = target_audio.getBeatEvents();\n\n    if(start_video_beat < 0):\n        if(synchvideo == 0):\n            vbeats = [vbeats[0].clone()]+vbeats;\n            vbeats[0].start = vbeats[0].start-(vbeats[2].start-vbeats[1].start);\n        vbadd = Event.SubdivideIntervals(vbeats[:2], -start_video_beat);\n        vbeats = vbadd+vbeats[2:];\n        start_video_beat = 0;\n\n\n    vbeats = vbeats[start_video_beat:];\n    tbeats = tbeats[start_audio_beat:];\n\n    if (source_harmonic == 'half'):\n        vbeats = Event.Half(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'third'):\n        vbeats = Event.Third(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'double'):\n        vbeats = Event.Double(vbeats);\n\n    if (target_harmonic == 'half'):\n        tbeats = Event.Half(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'third'):\n        tbeats = Event.Third(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'double'):\n        tbeats = Event.Double(tbeats);\n\n\n    if(nbeats):\n        print((\"Rendering {} beats of result\".format(nbeats)))\n        if(len(vbeats)>nbeats):\n            vbeats = vbeats[:nbeats];\n            print((len(vbeats)))\n\n\n    if(unfold_to_n):\n        vbeats = Event.UnfoldToN(vbeats, unfold_to_n, momentum=momentum);\n\n    if (len(tbeats) > len(vbeats)):\n        tbeats = tbeats[:len(vbeats)];\n\n    if(warp_type is 'weight'):\n        vbeats = source_video.visualBeatsFromEvents(vbeats);\n\n    if(name_tag is None):\n        name_tag = warp_type+'_sab_'+str(start_audio_beat)+'_svb_'+str(start_video_beat);\n    if(name_tag_prefix is not None):\n        name_tag = name_tag+name_tag_prefix;\n\n    warp_args = dict(target=target_audio,\n                     source_events=vbeats,\n                     target_events = tbeats,\n                     warp_type=warp_type,\n                     force_recompute=force_recompute,\n                     name_tag = name_tag)\n    if(bitrate):\n        warp_args.update(dict(bitrate=bitrate));\n\n    warp_args.update(kwargs);\n    warped_result = source_video.getWarped(**warp_args);\n\n    if(output_path):\n        final_output_path = output_path;\n        if(os.path.isfile(final_output_path)):\n            output_filename = os.path.basename(output_path);\n            name_parts = os.path.splitext(output_filename);\n            output_filename_base = name_parts[0];\n            output_directory_path = os.path.dirname(output_path);\n            if (output_directory_path == ''):\n                output_directory_path = '.'\n            output_ext = name_parts[1];\n            ntry = 1;\n            tryname = output_filename_base+ '_' + str(ntry);\n            while (os.path.isfile(os.path.join(output_directory_path, tryname+output_ext)) and ntry<100):\n                ntry = ntry+1;\n                tryname = output_filename_base + '_' + str(ntry);\n\n            final_output_path = os.path.join(output_directory_path, tryname + output_ext);\n        shutil.copy2(src=warped_result.getPath(), dst=final_output_path);\n        n_frames_total = warped_result.num_frames_total;\n        warp_used = warped_result.getInfo('warp_used');\n        warped_result_final = Video(path = final_output_path, num_frames_total=n_frames_total);\n        warped_result_final.setInfo(label='warp_used', value=warp_used);\n        os.remove(warped_result.getPath())\n        warped_result = warped_result_final;\n    return warped_result;\n\n\n\n    def getVBSegments(self,source_video,\n                      source_beats = None,\n                      search_tempo=None,\n                      search_window=None,\n                      max_height=None,\n                      beat_limit=None,\n                      n_return=None,\n                      unary_weight=None,\n                      binary_weight=None,\n                      break_on_cuts=None,\n                      peak_vars=None):\n\n        source = source_video;\n        if(source_beats is None):\n            if (peak_vars is not None):\n                vbeats = source.getFeature('simple_visual_beats', **peak_vars);\n            else:\n                vbeats = source.getFeature('simple_visual_beats');\n        else:\n            vbeats = source_beats;\n\n        #\n\n        if (search_tempo is not None):\n            tempo = search_tempo;\n            beat_time = np.true_divide(60.0, tempo);\n            clips = VisualBeat.PullOptimalPaths_Basic(vbeats, target_period=beat_time, unary_weight=unary_weight,\n                                                      binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                      window_size=search_window);\n        else:\n            clips = VisualBeat.PullOptimalPaths_Autocor(vbeats, unary_weight=unary_weight, binary_weight=binary_weight,\n                                                        break_on_cuts=break_on_cuts, window_size=search_window);\n\n        if (beat_limit is None):\n            beat_limit = 2;\n\n        print((\"There were {} candidates\".format(len(vbeats))));\n        nclips = 0;\n        segments = [];\n\n        for S in clips:\n            if (len(S) > beat_limit):\n                nclips = nclips + 1;\n                segments.append(S);\n\n        if (n_return is not None):\n            segments.sort(key=len, reverse=True);\n            segments = segments[:n_return];\n        return segments;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/_dancefer_examples.py",
    "content": "\n\nfrom .VisBeatExampleVideo import *\nfrom ._music_examples import *\n\n# dances = [];\ndances.append(VisBeatExampleVideo(display_name = 'SNSD: HAHAHA', name='snsd_hahaha', url='https://www.youtube.com/watch?v=OxNsx0eMsGU', start_beat=42));\ndances.append(VisBeatExampleVideo(display_name = 'Boston Dynamics: Spot the Dancing Robot', name='spot_the_dancing_robot', url='https://www.youtube.com/watch?v=kHBcVlqpvZ8', start_beat = 9));\ndances.append(VisBeatExampleVideo(display_name = 'Michael Jackson: Thriller', name = 'thriller', url = 'https://www.youtube.com/watch?v=wlHUJbl-t7o', start_beat = 4))\ndances.append(VisBeatExampleVideo(display_name = 'LMFAO: Party Rock Anthem',name='party_rock', url='https://www.youtube.com/watch?v=WZRMpC_wh0M', start_beat=4, leadin=4))\ndances.append(VisBeatExampleVideo(display_name = 'BTS: Boy in Luv', name='boy_in_luv', url='https://www.youtube.com/watch?v=gqz6Adx63w8', start_beat=34));\ndances.append(VisBeatExampleVideo(display_name = 'Thays Monaro: Redneck Woman',name='gwilson_redneck_woman', url='https://www.youtube.com/watch?v=1apy8YPygKo', start_beat=65))\ndances.append(VisBeatExampleVideo(display_name = 'Music Express: Dancing in the Street', name='dance_cc_dancing_in_the_street', url='https://www.youtube.com/watch?v=fzZ2CoL3IMQ', start_beat=3));\ndances.append(VisBeatExampleVideo(display_name = 'Barney and Friends: Mr. Golden Sun',name='barney_mr_golden_sun', url='https://www.youtube.com/watch?v=ya4yyg9XiI4', start_beat=24))\ndances.append(VisBeatExampleVideo(display_name = 'M. Express: Friends Forever', name='dance_cc_friends_forever', url='https://www.youtube.com/watch?v=T6ZX6wkJ5Ns', start_beat=2));\ndances.append(VisBeatExampleVideo(display_name = 'Just Dance Kids: Gummy Bear',name='jdk_gummy_bear', url='https://www.youtube.com/watch?v=KVE-T2_vLpY', start_beat=60))\ndances.append(VisBeatExampleVideo(display_name = 'M. Express: Feelin Good',name='dance_cc_feelin_good', url='https://www.youtube.com/watch?v=uBWp9rr6w08', start_beat=49));\n# dances.append(VisBeatExampleVideo(display_name = 'Kiesza: Hideaway', name='hideaway', url='https://www.youtube.com/watch?v=Vnoz5uBEWOA', start_beat=124))\ndances.append(VisBeatExampleVideo(display_name = 'SNSD: Genie', name='snsd_genie', url='https://www.youtube.com/watch?v=6SwiSpudKWI', start_beat=141));\ndances.append(VisBeatExampleVideo(display_name = 'Momoland Boom Boom', name='momoland_boom_boom', url='https://www.youtube.com/watch?v=0HKfjsM2hSw', start_beat = 145));#33#\ndances.append(VisBeatExampleVideo(display_name = 'Snap: Rhythm is a Dancer', name='rhythm_is_a_dancer', url='https://www.youtube.com/watch?v=fDWFVI8PQOI', start_beat=65));\ndances.append(VisBeatExampleVideo(display_name = 'Janet Jackson: Rhythm Nation', name='rhythm_nation', url='https://www.youtube.com/watch?v=OAwaNWGLM0c', start_beat = 226));\ndances.append(VisBeatExampleVideo(display_name = 'BTS Just One Day', name='bts_just_one_day', url='https://www.youtube.com/watch?v=KQeAg45p2UI', start_beat=200));\n\n\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n\n\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/_dancify_examples.py",
    "content": "from .VisBeatExampleVideo import *\nfrom ._music_examples import *\n\ndances.append(VisBeatExampleVideo(display_name = 'Turtle', name='turtle', url='https://www.youtube.com/watch?v=PWD4gktEUAY', start_beat=0));\ndances.append(VisBeatExampleVideo(display_name = 'Louie The Cat', name='louie_the_cat', url='https://www.youtube.com/watch?v=hqFG6d86ygI', start_beat=None));\n\n\n\naccidental_dances = [];\naccidental_dances.append(VisBeatExampleVideo(display_name=\"Trump IACP Full\", name=\"trump_iacp_full\", url='https://www.youtube.com/watch?v=pu4dPTi6SEg', target_n_beats = 7))\naccidental_dances.append(VisBeatExampleVideo(display_name=\"Trump Tax Reform WH.gov Full\", name=\"trump_taxreform_remarks_1\", url=\"https://www.youtube.com/watch?v=zB-lhTEQdKY\"))\n# accidental_dances.append(VisBeatExampleVideo(display_name=\"\", name=\"\", url=\"\"))\n\n\nsynth = [];\nsynth.append(VisBeatExampleVideo(name='synth_ball_metronome_w_noise', url = 'https://youtu.be/-mqJIGdro6A', start_beat = None));\nsynth.append(VisBeatExampleVideo(name='synth_test_ball_1', url = 'https://youtu.be/SjXsMYBJEF8', start_beat = None));\nsynth.append(VisBeatExampleVideo(name='synth_test_ball_1_gt_impact_sounds', url = 'https://youtu.be/tsdsQm4iTNg', start_beat = None));\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/_mediafiles.py",
    "content": "import os\n\n\nVB_MEDIA_UTILS_PATH = os.path.abspath(__file__)\nVB_MEDIA_UTILS_DIR = os.path.abspath(os.path.dirname(__file__));\nMEDIAFILES_DIR = os.path.join(VB_MEDIA_UTILS_DIR, 'assets'+os.sep)\n\nAUDIO_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'audio'+os.sep);\nAUDIO_FILES = [];\nAUDIO_FILE_PATHS = {};\nfor filename in os.listdir(AUDIO_FILES_DIR):\n    # if(reduce(lambda x,y: x or y, map(lambda ext: filename.lower().endswith(ext), Audio.MEDIA_FILE_EXTENSIONS()))):\n    AUDIO_FILES.append(filename);\n    AUDIO_FILE_PATHS[filename]=(os.path.join(AUDIO_FILES_DIR, filename));\n\n\ndef GetTestAudioPath(filename):\n    return AUDIO_FILE_PATHS[filename];\n\n\nVIDEO_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'video'+os.sep);\nVIDEO_FILES = [];\nVIDEO_FILE_PATHS = [];\nif(os.path.exists(VIDEO_FILES_DIR)):\n    for filename in os.listdir(VIDEO_FILES_DIR):\n        VIDEO_FILES.append(filename);\n        VIDEO_FILE_PATHS.append(os.path.join(VIDEO_FILES_DIR, filename));\n\n\n\nIMAGE_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'images'+os.sep);\nIMAGE_FILES = [];\nIMAGE_FILE_PATHS = {};\nfor filename in os.listdir(IMAGE_FILES_DIR):\n    IMAGE_FILES.append(filename);\n    IMAGE_FILE_PATHS[filename] = (os.path.join(IMAGE_FILES_DIR, filename));\n\ndef GetTestImagePath(filename=None):\n    if(filename is None):\n        filename = \"VisBeatWatermark.png\"\n    return IMAGE_FILE_PATHS[filename];\n\ndef GetVBMarkPath():\n    return IMAGE_FILE_PATHS[\"VisBeatWatermark.png\"];\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/_music_examples.py",
    "content": "from .VisBeatExampleVideo import *\ndances = [];\n\nmusic = [];\n\nmusic.append(VisBeatExampleVideo(display_name = 'U Cant Touch This', name='cant_touch_this', url='https://www.youtube.com/watch?v=_NNYI8VbFyY', start_beat=2, leadin=2));\nmusic.append(VisBeatExampleVideo(display_name = 'Mary Poppins: Supercalifrag.', name='supercalifrag', url='https://www.youtube.com/watch?v=rihNRTTcztQ', start_beat = 5, leadin = 3));\nmusic.append(VisBeatExampleVideo(display_name = 'Migos: Walk It Talk It',name='walkit_talkit', url='https://www.youtube.com/watch?v=fGqdIPer-ms', start_beat = 134));\nmusic.append(VisBeatExampleVideo(display_name = 'Rammstein: Du Hast',name='du_hast', url = 'https://www.youtube.com/watch?v=W3q8Od5qJio', start_beat = 193));\nmusic.append(VisBeatExampleVideo(display_name = 'Taylor Swift: Shake It Off', name='shake_it_off', url='https://www.youtube.com/watch?v=nfWlot6h_JM', start_beat=112));\nmusic.append(VisBeatExampleVideo(display_name = 'Michael Jackson: Billie Jean', name='billie_jean', url='https://www.youtube.com/watch?v=Zi_XLOBDo_Y', start_beat=169));\nmusic.append(VisBeatExampleVideo(display_name = 'Hall and Oates: You Make My Dreams', name='you_make_my_dreams', url='https://www.youtube.com/watch?v=EErSKhC0CZs', start_beat=95));\nmusic.append(VisBeatExampleVideo(display_name = 'Parry Gripp: Breakfast Burrito',name=\"breakfast_burrito\", url='https://www.youtube.com/watch?v=prPjpwsGiws', start_beat=32))\nmusic.append(VisBeatExampleVideo(display_name = 'Pharrell Williams: Happy',name='happy', url='https://www.youtube.com/watch?v=y6Sxv-sUYtM', start_beat=69, leadin=3))\nmusic.append(VisBeatExampleVideo(display_name = 'Aqua: Barbie Girl',name='barbie_girl', url='https://www.youtube.com/watch?v=ZyhrYis509A', start_beat=67, leadin=4));\nmusic.append(VisBeatExampleVideo(display_name = 'Jhameel: Montage',name='music_cc_jhameel_montage', url='https://www.youtube.com/watch?v=vYr_nCmsgoE', start_beat=103))\nmusic.append(VisBeatExampleVideo(display_name = 'Vengaboys: We like to Party',name='we_like_to_party', url='https://www.youtube.com/watch?v=6Zbi0XmGtMw', start_beat=65))\nmusic.append(VisBeatExampleVideo(display_name = 'Rick Astley: Never Gonna Give You Up', name='rick_roll', url='https://www.youtube.com/watch?v=dQw4w9WgXcQ', start_beat = 3, leadin=3));\nmusic.append(VisBeatExampleVideo(display_name = 'Mark Ronson: Uptown Funk ft. Bruno Mars', name='uptown_funk', url='https://www.youtube.com/watch?v=OPf0YbXqDm0', start_beat=32));\nmusic.append(VisBeatExampleVideo(display_name = 'Missy Elliot: Work It', name='work_it', url='https://www.youtube.com/watch?v=cjIvu7e6Wq8', start_beat=52, leadin = 1));\nmusic.append(VisBeatExampleVideo(display_name = 'If I only had a brain', name='only_had_a_brain', url='https://www.youtube.com/watch?v=nauLgZISozs', start_beat=14));\nmusic.append(VisBeatExampleVideo(display_name = 'Kane Brown: Lose It', name='kb_lose_it', url='https://www.youtube.com/watch?v=Z8nkc2KKjd8', start_beat=56));\n# music.append(VisBeatExampleVideo(display_name = 'Check Meowt', name='pg_check_meowt', url='https://youtu.be/NjKYX4bQpf0', start_beat = 16));\n# music.append(VisBeatExampleVideo(display_name = 'Wu-Tang Clan: Protect Ya Neck', name='wutang_protect_ya_neck', url='https://www.youtube.com/watch?v=R0IUR4gkPIE', start_beat = None));\n# music.append(VisBeatExampleVideo(display_name = 'Ice Cube: It Was A Good Day',name='it_was_a_good_day', url='https://www.youtube.com/watch?v=h4UqMyldS7Q', start_beat=64, harmonic = 'half'));"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/command_line.py",
    "content": ""
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/fileui/__init__.py",
    "content": "\nfrom sys import platform\nif platform == \"linux\" or platform == \"linux2\":\n    PLATFORM = 'linux';\nelif platform == \"darwin\":\n    PLATFORM = 'osx';\nelif platform == \"win32\":\n    PLATFORM = 'windows'\n\nSUPPORTED = False;\n\nINITIAL_DIR ='./';\n\nif(PLATFORM == 'osx'):\n    from . import uipath\n\n    def GetFilePath(initial_path=None):\n        if(initial_path is None):\n            return uipath.uiGetFilePath(initial_path=INITIAL_DIR);\n        else:\n            return uipath.uiGetFilePath(initial_path);\n    def GetDirectory(initial_path=None):\n        if(initial_path is None):\n            return uipath.uiGetDirectory(initial_path=INITIAL_DIR);\n        else:\n            return uipath.uiGetDirectory(initial_path);\n    def GetSaveFilePath(initial_path=None, file_extension = None):\n        if(initial_path is None):\n            return uipath.uiGetSaveFilePath(initial_path=INITIAL_DIR, file_extension=file_extension);\n        else:\n            return uipath.uiGetSaveFilePath(initial_path=initial_path, file_extension=file_extension);\n\n    def Show(path):\n        uipath.showInFinder(path);\n\n    def Open(path):\n        uipath.openOSX(path);\n    SUPPORTED = True;\nelse:\n    def GetFilePath(initial_path=None):\n        return None;\n    def GetDirectory(initial_path=None):\n        return None;\n    def GetSaveFilePath(initial_path=None, file_extension = None):\n        return None;\n    def Show(path):\n        return None;\n    def Open(path):\n        return None;"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/fileui/uipath.py",
    "content": "import os\nimport subprocess\n\n\n\ndef uiGetFilePath(initial_path=None):\n    try:\n        if(initial_path):\n            output = subprocess.check_output(\"osascript -e 'set strPath to POSIX file \\\"{}\\\"' -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\" default location strPath' -e 'set theDocument to (the POSIX path of theDocument)'\".format(initial_path), shell=True)\n        else:\n            output = subprocess.check_output(\"osascript -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\"' -e 'set theDocument to (the POSIX path of theDocument)'\", shell=True)\n        return output.replace('\\n', '');\n    except subprocess.CalledProcessError as e:\n        print((e.output));\n    # assert(False)\n    #     grabpath = get_ipython().run_cell_magic(u'bash', u'', \"osascript -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\"' -e 'set theDocument to (the POSIX path of theDocument)'>&2\")\n\ndef uiGetDirectory(initial_path=None):\n    try:\n        if(initial_path):\n            output = subprocess.check_output(\"osascript -e 'set strPath to POSIX file \\\"{}\\\"' -e 'set thedir to choose folder with prompt \\\"Please select a file:\\\" default location strPath' -e 'set thedir to (the POSIX path of thedir)'\".format(initial_path), shell=True)\n        else:\n            output = subprocess.check_output(\"osascript -e 'set thedir to choose folder with prompt \\\"Please select a directory:\\\"' -e 'set thedir to (the POSIX path of thedir)'\", shell=True)\n        return output.replace('\\n', '');\n    except subprocess.CalledProcessError as e:\n        print((e.output));\n    # assert(False)\n\ndef uiGetSaveFilePath(initial_path=None, file_extension=None):\n    try:\n        osastr = \"osascript \";\n        if(initial_path):\n            osastr = osastr+\"-e 'set strPath to POSIX file \\\"{}\\\"' \".format(initial_path);\n        osastr = osastr+\"-e 'set theDocument to choose file name with prompt \\\"Save As File:\\\" \";\n        if(initial_path):\n            osastr = osastr+\"default location strPath\";\n        osastr = osastr+\"' \";\n        osastr = osastr+\"-e 'set theDocument to (the POSIX path of theDocument)'\"\n        output = subprocess.check_output(osastr, shell=True);\n        ostring = output.replace('\\n', '');\n        if (file_extension is not None):\n            if (not ostring.endswith(file_extension)):\n                ostring = ostring + file_extension;\n        return ostring;\n    except subprocess.CalledProcessError as e:\n        AWARN('ERROR')\n        print((e.output));\n\ndef showInFinder(path):\n    return openOSX(get_dir_from_path(path));\n\ndef openOSX(path):\n    return subprocess.check_output(\"open {}\".format(put_string_in_quotes(path)), shell=True);\n\ndef put_string_in_quotes(s):\n    return \"\\\"\"+s+\"\\\"\"\n\ndef get_file_name_from_path(pth):\n    return os.path.split(pth)[1];\n\ndef get_dir_from_path(pth):\n    return (os.path.split(pth)[0]+os.sep);"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/vbgui/BeatGUI.py",
    "content": "from visbeat3.AImports import *\n\nVIEWER_INSTALLED = 1;\ntry:\n    import vbwidget as Viewer\nexcept ImportError as e:\n    VIEWER_INSTALLED = 0;\n    AWARN(\"VBViewer not installed. Consider installing for full functionality.\")\n\nfrom ..TimeSignal import *\nfrom ..EventList import *\n\n\n\n#this is what media should call to get its gui object\ndef media_GUI_func(self):\n    if (self._gui is None):\n        self._gui = BeatGUI();\n        self._gui.media = self;\n    return self._gui;\n\nclass BeatGUI(AObject):\n    \"\"\"\n\n    \"\"\"\n    def AOBJECT_TYPE(self):\n        return 'BeatGUI';\n\n    def __init__(self, media=None, path=None, clear_temp=None):\n        \"\"\"If you provide a directory, it will look for a existing AFileManager.json in that directory, or create one if it does not already exist.\n            If you provide a json, it will use that json, unless the json doesn't exist, in which case it will complain...\n        \"\"\"\n        AObject.__init__(self, path=path);\n        if(media is not None):\n            self.media = media;\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self._widget = None;\n        self._media = None;\n\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n\n    #########\n\n    # <editor-fold desc=\"Property: 'media'\">\n    @property\n    def media(self):\n        return self._getMedia();\n    def _getMedia(self):\n        return self._media;\n    @media.setter\n    def media(self, value):\n        self._setMedia(value);\n    def _setMedia(self, value):\n        self._media = value;\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'media_type'\">\n    @property\n    def media_type(self):\n        return self._getMediaType();\n    def _getMediaType(self):\n        if(self.media is None):\n            return None;\n        else:\n            return self.media.AObjectType();\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'widget'\">\n    @property\n    def widget(self):\n        return self._getWidget();\n    def _getWidget(self):\n        if (self._widget is None):\n            self._widget = Viewer.VBVSignal();\n        return self._widget;\n    @widget.setter\n    def widget(self, value):\n        self._setWidget(value);\n    def _setWidget(self, value):\n        self._widget = value;\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'frame_rate'\">\n    @property\n    def frame_rate(self):\n        return self._getFrameRate();\n    def _getFrameRate(self):\n        gfr = self.widget.frame_rate;\n        if (gfr is None):\n            media = self.media;\n            if (media is not None):\n                gfr = media.getFrameRate();\n        return gfr;\n    @frame_rate.setter\n    def frame_rate(self, value):\n        self._setFrameRate(value);\n    def _setFrameRate(self, value):\n        self.widget.frame_rate = float(value);\n    # </editor-fold>\n\n\n    # <editor-fold desc=\"Property: 'frame_offset'\">\n    @property\n    def frame_offset(self):\n        return self._getFrameOffset();\n    def _getFrameOffset(self):\n        return self.widget.frame_offset;\n    @frame_offset.setter\n    def frame_offset(self, value):\n        self._setFrameOffset(value);\n    def _setFrameOffset(self, value):\n        self.widget.frame_offset = value;\n    # </editor-fold>\n\n    def run(self, local_saliency=None, frame_rate = None, eventlist = 'default', frame_offset=None):\n        if(frame_rate is None):\n            # self.widget.frame_rate = float(self.getMedia().getFrameRate());\n            self.frame_rate = self.media._getFrameRate();\n        else:\n            # self.widget.frame_rate = float(frame_rate);\n            self.frame_rate = frame_rate;\n\n        if(local_saliency is None):\n            self.widget.signal = self.media.getLocalRhythmicSaliency().tolist();\n            # self.widget.signal = self.getBothWayVisualImpactEnvelope(highpass_window_seconds=None, force_recompute = True).tolist();\n        else:\n            self.widget.signal = local_saliency.tolist();\n\n        if(frame_offset is None):\n            self.frame_offset = 0;\n        elif(frame_offset is 'guess'):\n            self.frame_offset = self.guessFrameOffset();\n        else:\n            self.frame_offset = frame_offset;\n\n        if(eventlist is None):\n            self.widget.events = [];\n        elif(eventlist == 'default'):\n            self.widget.events = EventList._toGUIDicts(self.media.getEventList());\n        else:\n            self.widget.events = EventList._toGUIDicts(eventlist);\n        self.widget.data_string = self.media.getStringForHTMLStreamingBase64();\n        return self.widget;\n\n\n    def guessFrameOffset(self):\n        if(isinstance(self.media, Video)):\n            return self.media.reader.get_length() - self.media.n_frames();\n        else:\n            return 0;\n\n\n    def deactivateAllEvents(self):\n        newes = []\n        gevents = self.getEventDicts();\n        for e in gevents:\n            newe = e;\n            newe['is_active']=0;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n    def activateAllEvents(self):\n        newes = []\n        gevents = self.getEventDicts();\n        for e in gevents:\n            newe = e;\n            newe['is_active'] = 1;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n    def activatePattern(self, pattern=None, prefix=None, apply_to_active=None):\n        assert(pattern), \"must provide pattern to activate\"\n        newes = []\n        gevents = self.getGUIEventDicts();\n        counter = 0;\n        prefix_length = 0;\n        if(prefix_length is not None):\n            prefix_length = len(prefix);\n        for i, e in enumerate(gevents):\n            if (apply_to_active):\n                if (e.get('is_active')):\n                    if (counter < prefix_length):\n                        e['is_active']=prefix[counter];\n                    else:\n                        e['is_active'] = pattern[(counter - prefix_length) % len(pattern)];\n                    counter = counter + 1;\n                else:\n                    print((\"Skipping beat {}, inactive\".format(i)));\n            else:\n                if (i < prefix_length):\n                    e['is_active'] = prefix[i];\n                else:\n                    e['is_active'] = pattern[(i - prefix_length) % len(pattern)];\n            newes.append(e);\n\n        self.widget.events = [];\n        self.widget.events = newes;\n\n\n    def shiftEventsByNFrames(self, n_frames=None):\n        assert(n_frames), \"must provide number of frames to shift by\"\n        newes = []\n        gevents = self.getEventDicts();\n        sample_step = np.true_divide(1.0,self.getFrameRate());\n        for e in gevents:\n            newe = e;\n            newe['start'] = newe['start']+n_frames*sample_step;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n\n    def getActiveEventTimes(self):\n        gevents = self.getEventDicts(active_only=True);\n        revents = []\n        for e in gevents:\n            revents.append(e.get('time'));\n        return np.asarray(revents);\n\n    def getEventTimes(self):\n        gevents = self.getEventDicts();\n        revents = []\n        for e in gevents:\n            revents.append(e.t);\n        return np.asarray(revents);\n\n    def getEvents(self, active_only=None):\n        return Event._FromGUIDicts(self.getEventDicts(active_only = active_only));\n\n    def getEventList(self, active_only=None):\n        elist = EventList._FromGUIDicts(self.getEventDicts(active_only=active_only));\n        elist.setInfo(label='html_frame_offset', value=self.getFrameOffset());\n        return elist;\n\n    def getActiveEvents(self):\n        return self.getEvents(active_only=True);\n\n    def getEventDicts(self, active_only = None):\n        gevents = self.widget.events[:];\n        if(not active_only):\n            return gevents;\n        else:\n            nevents = []\n            for e in gevents:\n                if(e.get('is_active')):\n                    nevents.append(e);\n            return nevents;\n\n    def saveEvents(self, save_path = None):\n        elist = self.getEventList(active_only=False);\n        if(save_path is not None):\n            elist.writeToJSON(json_path=save_path);\n            self.widget.last_save_path = save_path;\n        else:\n            save_path = self.widget.last_save_path;\n            if(save_path is None):\n                save_path = uiGetSaveFilePath(file_extension='.json');\n            if(save_path is not None):\n                elist.writeToJSON(json_path=save_path);\n                self.widget.last_save_path = save_path;\n\n    def saveEventsAs(self, save_path = None):\n        elist = self.getEventList(active_only=False);\n        if (save_path is not None):\n            elist.writeToJSON(json_path=save_path);\n            self.widget.last_save_path = save_path;\n            print(('savepath not none {}'.format(save_path)))\n        else:\n            save_path = uiGetSaveFilePath(file_extension='.json');\n            print(('savepath from ui {}'.format(save_path)))\n            if (save_path is not None):\n                print(('save path from ui {}'.format(save_path)));\n                elist.writeToJSON(json_path=save_path);\n                self.widget.last_save_path = save_path;\n        print(save_path)\n\n    def setEvents(self, events):\n        self.widget.events = Event._ToGUIDicts(events);\n\n    def setEventList(self, event_list):\n        if(event_list.getInfo('html_frame_offset') is not None):\n            self.widget.frame_offset = event_list.getInfo('html_frame_offset');\n        self.widget.events = event_list._toGUIDicts();\n\n\n    def loadEvents(self, load_path = None):\n        if(load_path is None):\n            load_path = uiGetFilePath();\n        elist = EventList();\n        elist.loadFromJSON(json_path=load_path);\n        self.setEventList(event_list = elist);\n\n\n\n    def getEventListWithSelectedSegments(self):\n        eventlist = self.getEventList();\n        events = eventlist.events;\n        segments = [];\n        for i, e in enumerate(events):\n            if(e.direction>-1): # meaning not a back beat\n                newseg = [];\n                for si in range(i, len(events)):\n                    newseg.append(si);\n                    if(events[si].direction<0): # meaning a back beat\n                        break;\n                segments.append(newseg);\n        eventlist.setInfo(label='selected_segments', value=segments);\n        return eventlist;\n\n\n\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/lib/visbeat3/vbgui/__init__.py",
    "content": "\n"
  },
  {
    "path": "src/video2npz/visbeat3/build/scripts-3.7/dancefer",
    "content": "#!/opt/anaconda3/envs/py37/bin/python\n\nimport sys\nimport matplotlib\nmatplotlib.use('PS')\nimport visbeat3\n\nsource_url = 'https://www.youtube.com/watch?v={}'.format(sys.argv[0]);\ntarget_url = 'https://www.youtube.com/watch?v={}'.format(sys.argv[1]);\n\noutput_path = sys.argv[2];\n\nresult = visbeat3.AutoDancefer(source=source_url, target = target_url,\n                              output_path = output_path,\n                              synch_video_beat = 0,\n                              synch_audio_beat = 0,\n                              beat_offset = 64,\n                              nbeats = 128);\nresult.play();\n"
  },
  {
    "path": "src/video2npz/visbeat3/setup.cfg",
    "content": "[metadata]\n# This includes the license file(s) in the wheel.\n# https://wheel.readthedocs.io/en/stable/user_guide.html#including-license-files-in-the-generated-wheel-file\nlicense_files = LICENSE\n\n[bdist_wheel]\n# This flag says to generate wheels that support both Python 2 and Python\n# 3. If your code will not run unchanged on both Python 2 and 3, you will\n# need to generate separate wheels for each Python version that you\n# support. Removing this line (or setting universal to 0) will prevent\n# bdist_wheel from trying to make a universal wheel. For more see:\n# https://packaging.python.org/guides/distributing-packages-using-setuptools/#wheels\nuniversal=0"
  },
  {
    "path": "src/video2npz/visbeat3/setup.py",
    "content": "import setuptools\n\nwith open(\"README.md\", \"r\") as fh:\n    long_description = fh.read()\n\nsetuptools.setup(\n  name=\"visbeat3\",\n  version=\"0.0.8\",\n  author=\"Haofan Wang\",\n  author_email=\"haofanwang.ai@gmail.com\",\n  description=\"Python3 Implementation for 'Visual Rhythm and Beat' SIGGRAPH 2018\",\n  long_description=long_description,\n  long_description_content_type=\"text/markdown\",\n  url=\"https://github.com/haofanwang/visbeat3\",\n  packages=setuptools.find_packages(),\n  # install_requires=[\n  #       'numpy',\n  #       'scipy',\n  #       'bs4',\n  #       'librosa==0.6.0',\n  #       'imageio==2.9.0',\n  #       'requests',\n  #       'moviepy==1.0.3',\n  #       'termcolor',\n  #       'youtube-dl',\n  #       'matplotlib',\n  #       'numba==0.48.0'\n  #   ],\n  scripts=['bin/dancefer'],\n  include_package_data=True,\n  package_data={'data': ['visbeat3/assets/*']},\n  classifiers=[\n  \"Programming Language :: Python :: 3\",\n  \"License :: OSI Approved :: Apache Software License\",\n  \"Operating System :: OS Independent\",\n  ],\n)\n"
  },
  {
    "path": "src/video2npz/visbeat3/test.py",
    "content": "import visbeat3 as vb\nimport os\n\nvideo_dir = '../videos/'\ntempos = {}\n# try:\n#     for file in os.listdir(video_dir):\n#         if file == '.DS_Store':\n#             continue\n#         vlog = vb.PullVideo(name=file, source_location=video_dir+file, max_height=360)\n#         # vbeats = vlog.getVisualBeatSequences(search_window=None)[0]\n#         # print(\"vbeats are\", vbeats)\n#         vb.Video.getVisualTempo = vb.Video_CV.getVisualTempo\n#         tempo = vlog.getVisualTempo()\n#         print(file, \"tempo\", tempo)\n#         tempos[file] = tempo\n# finally:\n#     print(tempos)\nvlog = vb.PullVideo(source_location=\"../videos/wzk_vlog_beat_enhance1_track1238.mp4\", max_height=360)\nvb.Video.getVisualTempo = vb.Video_CV.getVisualTempo\ntempo = vlog.getVisualTempo()\nprint(tempo)\n# vbeats = vlog.getVisualBeatSequences(search_window=None)[0]\n# for vbeat in vbeats:\n#     print(vbeat.start, vbeat.type, vbeat.weight, vbeat.index, vbeat.unrolled_start, vbeat.direction)"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/ADefines.py",
    "content": "# AD_DEBUG = 1;\n\nAD_DEBUG = 0;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AFileManager.py",
    "content": "from .AObject import *\n#import shutil\nfrom distutils.dir_util import copy_tree\n\nclass AFileManager(AObject):\n    \"\"\"AFileManager (class): Manages assets. This should really be replaced with a database of some sort...\n        Attributes:\n            todo\n    \"\"\"\n\n    @staticmethod\n    def AOBJECT_TYPE():\n        return 'AFileManager';\n\n    def getJSONPath(self):\n        return self.getPath();\n\n    def __init__(self, path=None, clear_temp=None):\n        \"\"\"If you provide a directory, it will look for a existing AFileManager.json in that directory, or create one if it does not already exist.\n            If you provide a json, it will use that json, unless the json doesn't exist, in which case it will complain...\n        \"\"\"\n        AObject.__init__(self, path=path);\n        # self.initializeBlank();\n        self.initWithPath(path=path, clear_temp=clear_temp);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.directories = {};\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n    def initWithPath(self, path=None, clear_temp=None):\n        oldpath = None\n        newpath = path;\n        if(path):\n            if(os.path.isfile(path)):\n                self.loadFromJSON(self.getJSONPath()); #assume path property is already set to 'path'\n                oldpath = self.getPath(); #whatever was in the json, having overwritten path property\n            elif(os.path.isdir(path)):\n                json_file_path = path+os.sep+self.getJSONName();\n                self.setPath(json_file_path);\n                if(os.path.isfile(self.getJSONPath())):\n                    self.loadFromJSON(json_file_path);\n                    oldpath = self.getPath();\n                    newpath = json_file_path;\n                    # self.setPath(file_path=json_file_path);\n                else:\n                    newpath=self.getJSONPath()\n                    self.writeToJSON(json_path=newpath);#no json file found, so we create one\n            else:\n                assert False, \"Given AFileManager path is neither an existing directory or file! path: {} (AFileManager.py)\".format(path)\n\n            self.setPath(file_path=newpath);\n\n            if(oldpath):\n                oldir = get_dir_from_path(pathstring(oldpath));\n                newdir = get_dir_from_path(pathstring(newpath));\n                if(oldir != newdir):\n                    AWARN(\"FILEMANAGER FOUND FILE MOVED FROM:\\n{}\\nTO:\\n{}\\nUPDATING DIRECTORIES...\".format(oldir,\n                                                                                                            newdir));\n                    for d in self.directories:\n                        dpth = self.directories[d];\n                        if(dpth.startswith(oldir)):\n                            dpthst = dpth.lstrip(oldir);\n                            self.directories[d]=os.path.join(newdir,dpthst);\n                            AWARN(\"{} updated to {}\".format(dpth, self.directories[d]));\n\n\n            self.setDir('data', pathstring(self.getDirectoryPath()+os.sep+\"Data\"+os.sep));\n            self.setDir('backup', pathstring(self.getDir('data')+\"Backups\"+os.sep));\n            self.setDir('temp', pathstring(self.getDir('data')+\"TEMP\"+os.sep));\n            temp_dir = self.getDir('temp');\n            if(os.path.isdir(temp_dir) and (clear_temp)):\n                for the_file in os.listdir(temp_dir):\n                    file_path = os.path.join(temp_dir, the_file);\n                    try:\n                        if os.path.isfile(file_path):\n                            os.remove(file_path);\n                            #os.unlink(file_path);\n                            #elif os.path.isdir(file_path): shutil.rmtree(file_path)\n                    except Exception as e:\n                        print(e)\n            make_sure_path_exists(temp_dir);\n            #Video.VIDEO_TEMP_DIR = temp_dir;\n\n    def setDir(self, name, path):\n        # AWARN(\"setting {} to {}\".format(name, path))\n        # assert(name is not 'log')\n        self.directories[name]=path;\n        make_sure_path_exists(path);\n        return path;\n\n    def addDir(self, name):\n        assert(name not in self.directories), \"tried to add {} dir to AFileManager, but this dir is already set\"\n        return self.setDir(name, pathstring(self.getDirectoryPath()+os.sep+name+os.sep));\n\n    def getDir(self, name):\n        # printDictionary(self.directories)\n        return self.directories.get(name);\n\n\n    def emptyDir(self, name):\n        dpth = self.getDir(name);\n        if(dpth is not None and os.path.isdir(dpth)):\n            shutil.rmtree(dpth);\n            make_sure_path_exists(dpth);\n\n    def deleteDir(self, name):\n        dpth = self.getDir(name);\n        if (dpth is not None and os.path.isdir(dpth)):\n            shutil.rmtree(dpth);\n            d = dict(self.directories);\n            del d[name];\n            self.directories=d;\n\n\n    def toDictionary(self):\n        d = AObject.toDictionary(self);\n        d['directories']=self.directories;\n        #serialize class specific members\n        return d;\n\n    def copyPathToDir(self, path_to_copy, dest_dir):\n        dest_path = self.getDir(dest_dir);\n        if(dest_path):\n            if(os.path.isdir(path_to_copy)):\n                copy_tree(src=path_to_copy, dst=dest_path);\n            elif(os.path.isfile(path_to_copy)):\n                shutil.copy2(path_to_copy, dest_path)\n        return;\n\n    def copyDirToPath(self, dir_to_copy, dest_path):\n        src_path = self.getDir(dir_to_copy);\n        if(src_path):\n            if(os.path.isdir(dest_path)):\n                copy_tree(src=src_path, dst=dest_path);\n        return;\n\n    @staticmethod\n    def copyRandomFractionOfFilesInSourceDir(source_dir, dest_dir, fraction=1.0, ext=None):\n        \"\"\"\n        Copies a random fraction of files in source directory... Wrote this for splitting training/test data in ML applications.\n        :param source_dir:\n        :param dest_dir:\n        :param fraction:\n        :param ext:\n        :return:\n        \"\"\"\n        directories = []\n        subdirnames = []\n        filepaths = [];\n        for filename in os.listdir(source_dir):\n            path = os.path.join(source_dir, filename)\n            if os.path.isdir(path):\n                directories.append(path)\n                subdirnames.append(filename)\n            else:\n                # namepart, extpart = os.path.splitext(filename);\n                if((ext is None) or filename.lower().endswith(ext)):\n                    filepaths.append(path);\n\n        n_to_copy = int(len(filepaths)*fraction);\n        random_seed = 0;\n        random.seed(random_seed);\n        random.shuffle(filepaths);\n        copy_sources = filepaths[:n_to_copy];\n        for src, dst in zip(copy_sources, [dest_dir]*len(copy_sources)):\n            #print(\"src: {}\\ndst: {}\".format(src, dst));\n            shutil.copy2(src, dst);\n\n        for d in range(len(directories)):\n            subdest = pathstring(os.path.join(dest_dir,subdirnames[d])+os.sep);\n            make_sure_dir_exists(subdest);\n            AFileManager.copyRandomFractionOfFilesInSourceDir(source_dir=directories[d], dest_dir=subdest, fraction=fraction, ext=ext);\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        self.directories = d['directories'];\n\n    def save(self):\n        if(os.path.isfile(self.getJSONPath())):\n            os.rename(self.getJSONPath(), self.getDir('backup')+os.sep+self.AOBJECT_TYPE()+\".json\");\n        self.writeToJSON(self.getJSONPath());\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AFuncDict.py",
    "content": "from .AParamDict import *\nimport pickle as pickle\nimport os\nclass AFuncDict(AParamDict):\n    \"\"\"AFuncDict (class): Extends AParamDict so that functions can be assigned to features and called whenever\n        computing those features is necessary.\n        Attributes:\n            data: name -> value, params\n            feature funcs: name -> function for evaluating\n    \"\"\"\n\n    def __init__(self, owner=None, name=None, path=None):\n        AParamDict.__init__(self, owner=owner, name=name, path=path);\n        self.functions = {};\n\n    def getEntry(self, name=None, params=None, force_recompute=False):\n        d = self.data.get(name);\n        if((d is not None) and (not force_recompute)):\n            return d;\n        else:\n            f = self.getFunction(name=name);\n            if(f is not None):\n                if(params is not None):\n                    if(not params.get('force_recompute')):\n                        params.update(dict(force_recompute=force_recompute));\n                    self.setValue(name=name, value=f(self=self.owner, **params), params=params, modified=True);\n                else:\n                    self.setValue(name=name, value=f(self=self.owner, force_recompute=force_recompute), params=params, modified=True);\n            return self.data.get(name);\n        return None;\n\n    def getValue(self, name=None, params=None, force_recompute=False):\n        d = self.getEntry(name=name, params=params, force_recompute=force_recompute);\n        if(d is not None):\n            return d.get('value');\n        else:\n            return None;\n\n    def getParams(self, name=None):\n        d = self.data.get(name);\n        if(d is not None):\n            return d.get('params');\n        else:\n            return None;\n\n    def getFunction(self, name=None):\n        return self.functions.get(name);\n\n    def setValue(self, name, value=None, params=None, modified=True):\n        self.data[name]['value']=value;\n        self.data[name]['params']=params;\n        self.setEntryModified(name=name, is_modified=modified)\n        #self.data[name]['modified']=modified;\n\n    def setFunction(self, name, function=None):\n        self.functions[name]=function;\n\n    def saveEntry(self, name, path, force=False):\n        \"\"\"Save one entry to one file.\"\"\"\n        if(self.data.get(name) is None):\n            return None;\n        if(self.isEntryModified(name=name) or force or (not os.path.isfile(path))):\n            #pickleToPath\n            f = open(path, 'wb');\n            pickle.dump(self.getEntry(name=name), f, protocol=2);\n            f.close();\n            self.setEntryModified(name=name, is_modified=False);\n            #assert(False), \"should not be saving in this test\";\n        return True;\n\n    def setEntryModified(self, name, is_modified=True):\n        self.data[name]['modified']=is_modified;\n        if(is_modified):\n            self.setModified(is_modified=True);\n\n    def isEntryModified(self, name):\n        entry = self.data.get(name);\n        if(entry is not None):\n            m=entry.get('modified');\n            if(m is not None):\n                return m;\n            else:\n                return True;\n        else:\n            assert(False), \"checking mod bit on entry that does not exist\"\n\n    def isModified(self):\n        return self.modified;\n\n    def setModified(self, is_modified):\n        self.modified=is_modified;\n\n    def save(self, path, force=False):\n        \"\"\"save all entries to one file.\"\"\"\n        if(force or self.isModified()):\n            f = open(path, 'wb');\n            pickle.dump(self.data, f, protocol=2);\n            f.close();\n            self.setModified(is_modified=False);\n            #assert(False), \"should not be saving in this test\";\n        return True;\n\n    def loadEntry(self, name, path):\n        \"\"\"load one entry from one file.\"\"\"\n        f=open(path, 'rb');\n        self.setEntry(name=name, d=pickle.load(f));\n        f.close();\n        self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def load(self, path):\n        \"\"\"Load a set of entries all from one file.\"\"\"\n        f=open(path, 'rb');\n        newd = pickle.load(f);\n        self.data.update(newd);\n        f.close();\n        return True;\n\n    def getKeyList(self):\n        return list(self.data.keys());\n\n    def getFunctionList(self):\n        return list(self.functions.keys());\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AImports.py",
    "content": "#AImports\nfrom . import ADefines as defines\nimport os\nimport os.path\nimport errno\nimport json\nimport pickle as pickle\nimport glob\nimport subprocess\nfrom operator import truediv\nimport shutil\nimport time\nfrom time import gmtime, strftime, localtime\nimport random\nfrom . import fileui\n\n\n\ntry:\n    from termcolor import colored\n    def AWARN(message):\n        if (defines.AD_DEBUG):\n            print((colored(message, 'red')))\n    def AINFORM(message):\n        if(defines.AD_DEBUG):\n            print((colored(message, 'blue')))\nexcept ImportError:\n    if (defines.AD_DEBUG):\n        print(\"You do not have termcolor installed (pip install termcolor). AWARN will just show as plain print statements when defines.AD_DEBUG==True...\")\n    def AWARN(message):\n        if (defines.AD_DEBUG):\n            print(message);\n    def AINFORM(message):\n        if (defines.AD_DEBUG):\n            print(message);\n\ndef local_time_string():\n    return strftime(\"%Y-%m-%d_%H:%M:%S\", localtime());\n\ndef get_temp_file_path(final_file_path=\"TEMP\", temp_dir_path = None):\n    pparts = os.path.split(final_file_path);\n    destfolder = pparts[0]+os.sep;\n    tempdir = temp_dir_path;\n    if(tempdir is None):\n        tempdir='.';\n    destfolder=pathstring(tempdir+os.sep);\n    tempname = 'TEMP_'+pparts[1];\n    temptry = 0;\n    while(os.path.isfile(destfolder+tempname)):\n        temptry=temptry+1;\n        tempname = 'TEMP{}_'.format(temptry)+pparts[1];\n    return pathstring(destfolder+tempname);\n\n\ndef runningInNotebook():\n    try:\n        shell = get_ipython().__class__.__name__\n        if shell == 'ZMQInteractiveShell':\n            return True   # Jupyter notebook or qtconsole\n        elif shell == 'TerminalInteractiveShell':\n            return False  # Terminal running IPython\n        else:\n            return False  # Other type (?)\n    except NameError:\n        return False      # Probably standard Python interpreter\n\ndef getshellname():\n    try:\n        shell = get_ipython().__class__.__name__\n        return shell;\n    except NameError:\n        return False      # Probably standard Python interpreter\n\n\ndef runningInSpyder():\n    return 'SpyderKernel' in str(get_ipython().kernel.__class__);\n\ndef pickleToPath(d, path):\n    # assert(False)\n    print(\"pickling\")\n    f = open(path, 'wb');\n    pickle.dump(d, f, protocol=2);\n    f.close();\n    return True;\n\ndef unpickleFromPath(path):\n    f=open(path, 'rb');\n    d=pickle.load(f);\n    f.close();\n    return d;\n\ndef make_sure_path_exists(path):\n    try:\n        os.makedirs(path)\n    except OSError as exception:\n        if exception.errno != errno.EEXIST:\n            raise\n\ndef make_sure_dir_exists(path):\n    pparts = os.path.split(path);\n    destfolder = pparts[0]+os.sep;\n    try:\n        os.makedirs(destfolder)\n    except OSError as exception:\n        if exception.errno != errno.EEXIST:\n            raise\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\ndef pathstring(path):\n    return path.replace(os.sep+os.sep, os.sep);\n\ndef is_interactive():\n    import __main__ as main\n    return not hasattr(main, '__file__')\n\ndef printOb(obj):\n    for attr in dir(obj):\n        print(\"#### Obj.%s = %s\\n\" % (attr, getattr(obj, attr)))\n\ndef pathstring(path):\n    return path.replace(os.sep+os.sep, os.sep);\n\ndef get_prepended_name_file_path(original_file_path, string_to_prepend):\n    pparts = os.path.split(original_file_path);\n    destfolder = pparts[0]+os.sep;\n    pname = string_to_prepend+pparts[1];\n    return pathstring(destfolder+pname);\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\ndef change_extension(input_path, new_ext):\n    nameparts = os.path.splitext(input_path);\n    return nameparts[0]+new_ext;\n\ndef printDictionary(obj):\n    if type(obj) == dict:\n        for k, v in list(obj.items()):\n            if hasattr(v, '__iter__'):\n                print(k)\n                printDictionary(v)\n            else:\n                print('%s : %s' % (k, v))\n    elif type(obj) == list:\n        for v in obj:\n            if hasattr(v, '__iter__'):\n                printDictionary(v)\n            else:\n                print(v)\n    else:\n        print(obj)\n\ndef spotgt_shift_bit_length(x):\n    #smallest power of two greater than\n    return 1<<(x-1).bit_length()\n\ndef get_file_name_from_path(pth):\n    return os.path.split(pth)[1];\n\ndef get_dir_from_path(pth):\n    return (os.path.split(pth)[0]+os.sep);\n\ndef get_file_names_from_paths(pths):\n    r = [];\n    for p in pths:\n        r.append(get_file_name_from_path(p));\n    return r;\n\ndef writeDictionaryToJSON(d, json_path=None):\n    if(json_path):\n        with open(json_path, 'w') as outfile:\n            json.dump(d, outfile, sort_keys = True, indent = 4, ensure_ascii=False);\n\n\ndef vtt_to_srt(fileContents):\n    replacement = re.sub(r'([\\d]+)\\.([\\d]+)', r'\\1,\\2', fileContents)\n    replacement = re.sub(r'WEBVTT\\n\\n', '', replacement)\n    replacement = re.sub(r'^\\d+\\n', '', replacement)\n    replacement = re.sub(r'\\n\\d+\\n', '\\n', replacement)\n    return replacement\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AObject.py",
    "content": "#AO#labels#AObject\nimport os\nimport json\n\nfrom .AParamDict import *\nfrom . import fileui\n\nclass AObject(object):\n    \"\"\"AObject (class): This is a paarent class used to implement any comon serialization or typing we might want to do later\n        Attributes:\n            labels: dictionary of meta_data\n            save, load, and clear funcs: these are hooks for functions that manage the object's data on disk.\n    \"\"\"\n\n    AOBJECT_BASE_PATH=None;\n\n    def __init__(self, path=None, **kwargs):\n        self.initializeBlank();\n        if(path):\n            self.setPath(file_path=path, **kwargs);\n\n\n    def initializeBlank(self):\n        self.a_info = {'AObjectType': self.AOBJECT_TYPE()};\n        # self.a_data = AParamDict(owner=self, name='a_data');\n        self.save_func = None;\n        self.load_func = None;\n        self.clear_func = None;\n\n    def setPath(self, file_path=None, **kwargs):\n        if(file_path):\n            self.a_info['file_path'] = pathstring(file_path);\n            pparts = os.path.split(self.a_info['file_path']);\n            self.a_info['file_name'] = pparts[1];\n            self.a_info['directory_path']=pparts[0];\n            filename = self.a_info.get('file_name');\n            if(filename):\n                nameparts = os.path.splitext(filename);\n                self.a_info['file_base_name'] = nameparts[0];\n                self.a_info['file_ext'] = nameparts[1];\n            self.a_info['base_path'] = kwargs.get('base_path');\n            if(self.a_info['base_path'] is None):\n                self.a_info['base_path'] = AObject.AOBJECT_BASE_PATH;\n\n    def getPath(self):\n        if('file_path' in self.a_info):\n            return self.a_info['file_path'];\n        else:\n            return None;\n\n    def _showFile(self):\n        if(fileui.Show is not None):\n            fileui.Show(self.getPath());\n\n    def _open(self):\n        if(fileui.Open is not None):\n            fileui.Open(self.getPath());\n\n    def getRelativePath(self, base_path=None):\n        base = base_path;\n        if(base is None):\n            base = self.a_info.get('base_path');\n        if(base is None):\n            AWARN(\"Base path not set!\");\n        return str(self.getPath());\n\n    def getFileName(self):\n        if('file_name' in self.a_info):\n            return self.a_info['file_name'];\n        else:\n            return None;\n\n    def getFileExtension(self):\n        if('file_ext' in self.a_info):\n            return self.a_info['file_ext'];\n        else:\n            return None;\n\n    def getDirectoryPath(self):\n        return self.a_info.get('directory_path')\n\n    def setInfo(self, label, value):\n        self.a_info[label]=value;\n\n    def getInfo(self, label):\n        return self.a_info.get(label);\n\n    def loadFromJSON(self, json_path=None):\n        if(json_path):\n            self.setPath(file_path=json_path);\n        if('file_path' in self.a_info):\n            json_text=open(self.a_info['file_path']).read();\n            d = json.loads(json_text);\n            self.initFromDictionary(d);\n\n    def writeToJSON(self, json_path=None):\n        #with open(jsonpath+self.name+'.json', 'w') as outfile:\n        if(not json_path):\n            json_path = self.a_info.get('file_path');\n        if(json_path):\n            with open(json_path, 'w') as outfile:\n                json.dump(self.toDictionary(), outfile, sort_keys = True, indent = 4, ensure_ascii=False);\n\n    def serializeInfo(self):\n        return self.a_info;\n\n    def save(self, features_to_save='all', overwrite=True, **kwargs):\n        if(self.save_func):\n            self.save_func(self, features_to_save=features_to_save, overwrite=overwrite, **kwargs);\n        else:\n            AWARN(\"SAVE FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.AOBJECT_TYPE()));\n\n    def load(self, features_to_load=None, **kwargs):\n        if(self.load_func):\n            self.load_func(self, features_to_load=features_to_load, **kwargs);\n        else:\n            AWARN(\"LOAD FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.AOBJECT_TYPE()));\n\n    ########### \"VIRTUAL\" FUNCTIONS #############\n    @staticmethod\n    def AOBJECT_TYPE():\n        return 'AObject';\n\n    def toDictionary(self):\n        d = {'a_info': self.serializeInfo()};\n        return d;\n\n    def initFromDictionary(self, d):\n        self.a_info = d.get('a_info');\n\n    # ##Example of how these functions should be written in a  subclass, here we call the subclass 'AssetManager'\n    # def AOBJECT_TYPE(self):\n    #     return 'AssetManager';\n    #\n    # def toDictionary(self):\n    #     d = AObject.toDictionary(self);\n    #     #serialize class specific members\n    #     return d;\n    #\n    # def initFromDictionary(self, d):\n    #     AObject.initFromDictionary(self, d);\n    #     #do class specific inits with d;\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AParamDict.py",
    "content": "from .AImports import *\nclass AParamDict(object):\n    \"\"\"AParamDict (class): Dictionary that stores values and the parameters used to compute those values. I use this\n        class for two things. The first is to store parameters for reproducability. The second is to only recompute\n        values when functions are called with different parameters (some of this latter functionality is tied up in\n        code that isn't part of the Lite release).\n\n        Attributes:\n            data: name -> value, params\n    \"\"\"\n\n    def __init__(self, owner=None, name=None, path=None):\n        self.name=name;\n        self.data = {};\n        self.owner=owner;\n        self.modified=False;\n\n    def getEntry(self, name=None, params=None, force_recompute=False):\n        d = self.data.get(name);\n        if((d is not None) and (not force_recompute)):\n            return d;\n        return None;\n\n    def setEntry(self, name, d):\n        assert(name!='all' and name!='each'),\"Entry named '{}' is reserved in AParamDict\".format(name);\n        self.data[name]=d;\n\n    def removeEntry(self, name, assert_if_absent=True, set_modified = True):\n        if(assert_if_absent):\n            assert(name in self.data),\"Tried to remove entry {} that was not already in {}\".format(name, self.__class__);\n        popentry = self.data.pop(name, None);\n        if(set_modified):\n            self.setModified(set_modified);\n        return popentry;\n\n\n    def hasEntry(self, name=None):\n        return (self.data.get(name) is not None);\n\n    def getValue(self, name=None, params=None, force_recompute=False):\n        d = self.getEntry(name=name, params=params, force_recompute=force_recompute);\n        if(d is not None):\n            return d.get('value');\n        else:\n            return None;\n\n    def getParams(self, name=None):\n        d = self.data.get(name);\n        if(d is not None):\n            return d.get('params');\n        else:\n            return None;\n\n    def setValue(self, name, value=None, params=None, modified=True):\n        self.data[name]['value']=value;\n        self.data[name]['params']=params;\n        self.setEntryModified(name=name, is_modified=modified)\n\n    def saveEntry(self, name, path, force=False):\n        \"\"\"Save one entry to one file.\"\"\"\n        if(self.hasEntry(name=name) is None):\n            return None;\n        if(self.isEntryModified(name=name) or force or (not os.path.isfile(path))):\n            f = open(path, 'wb');\n            pickle.dump(self.getEntry(name=name), f, protocol=2);\n            f.close();\n            self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def setEntryModified(self, name, is_modified=True):\n        self.data[name]['modified']=is_modified;\n        if(is_modified):\n            self.setModified(is_modified=True);\n\n    def isEntryModified(self, name):\n        m=self.data[name].get('modified');\n        if(m is not None):\n            return m;\n        else:\n            return True;\n\n    def isModified(self):\n        return self.modified;\n\n    def setModified(self, is_modified):\n        self.modified=is_modified;\n\n    def save(self, path, force=False):\n        \"\"\"save all entries to one file.\"\"\"\n        if(force or self.isModified()):\n            f = open(path, 'wb');\n            pickle.dump(self.data, f, protocol=2);\n            f.close();\n            self.setModified(is_modified=False);\n        return True;\n\n    def loadEntry(self, name, path):\n        \"\"\"load one entry from one file.\"\"\"\n        f=open(path, 'rb');\n        self.setEntry(name=name, d=pickle.load(f));\n        f.close();\n        self.setEntryModified(name=name, is_modified=False);\n        return True;\n\n    def load(self, path):\n        \"\"\"Load a set of entries all from one file.\"\"\"\n        f=open(path, 'rb');\n        newd = pickle.load(f);\n        self.data.update(newd);\n        f.close();\n        return True;\n\n    def getKeyList(self):\n        return list(self.data.keys());"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Audio.py",
    "content": "from .EventList import *\nfrom .TimeSignal1D import *\nfrom scipy.io.wavfile import write\nimport librosa\nimport librosa.display\n\nfrom scipy import signal, fftpack\n\n\n\nclass Audio(TimeSignal1D):\n    \"\"\"Audio (class): A sound, and a bunch of convenience functions to go with it.\n        Attributes:\n            x: the sound signal\n            sampling_rate: the sampling rate\n    \"\"\"\n\n    FEATURE_FUNCS = TimeSignal1D.FEATURE_FUNCS.copy();\n\n    def __init__(self, path=None, sampling_rate=None, x=None, name=None):\n        #VBObject.__init__(self, path=path);\n        TimeSignal1D.__init__(self, path=path, sampling_rate=sampling_rate, x=x);\n        #self.initializeBlank();\n        if(name is not None):\n            self.name = name;\n        if(path):\n            self.loadFile();\n        if(self.name is None):\n            self.name = self.getInfo('file_name')\n\n\n    # <editor-fold desc=\"Property: 'name'\">\n    @property\n    def name(self):\n        return self.getName();\n    def getName(self):\n        return self._name;\n    @name.setter\n    def name(self, value):\n        self._setName(value);\n    def _setName(self, value):\n        self._name = value;\n    # </editor-fold>\n\n    def initializeBlank(self):\n        self.name = None;\n        TimeSignal1D.initializeBlank(self);\n        self.n_channels = 1;\n\n    def _getFrameRate(self):\n        return self.getOnsetSamplingRate();\n\n    def clone(self):\n        clone = Audio();\n        clone.setPath(self.getPath());\n        clone.x = self.x.copy();\n        clone.sampling_rate = self.sampling_rate;\n        clone.n_channels = self.n_channels;\n        stereo = self.getStereo();\n        if (stereo is not None):\n            clone.setInfo('stereo_signal', stereo);\n            clone.setInfo('stereo_sampling_rate', self.getInfo('stereo_sampling_rate'));\n        return clone;\n\n    def loadFile(self, file_path=None, sampling_rate=None, convert_to_mono=True):\n        if(file_path):\n            self.setPath(file_path=file_path);\n\n        if('file_path' in self.a_info):\n            self.x, self.sampling_rate = librosa.load(self.a_info['file_path'],sr=sampling_rate, mono=convert_to_mono);\n            if(len(self.x.shape)>1):\n                self.a_info['stereo_signal']=self.x;\n                self.setInfo('stereo_sampling_rate', self.sampling_rate);\n                self.x = np.mean(self.x, axis = 0)\n                print(\"averaged stereo channels\");\n\n    def getStereo(self):\n        return self.a_info.get('stereo_signal');\n\n    def getStereoSamplingRate(self):\n        return self.getInfo('stereo_sampling_rate');\n\n\n\n    def getStringForHTMLStreamingBase64(self):\n        encoded = self.getStereoEncodedBase64WAV();\n        return \"data:audio/wav;base64,{0}\".format(encoded.decode('ascii'));\n\n    def getStereoEncodedBase64WAV(self):\n        sig = self.getStereo();\n        sr = self.getStereoSamplingRate();\n        if (sig is None):\n            sig = self.getSignal();\n            sr = self.sampling_rate;\n        saudio = _make_wav(sig, sr);\n        encoded = base64.b64encode(saudio);\n        return encoded;\n\n    def getMonoEncodedBase64WAV(self):\n        sig = self.getSignal();\n        sr = self.sampling_rate;\n        saudio = _make_wav(sig, sr);\n        encoded = base64.b64encode(saudio);\n        return encoded;\n\n    def getLocalRhythmicSaliency(self, **kwargs):\n        return self.getOnsetEnvelope(**kwargs);\n\n\n    def play(self, autoplay = None):\n        \"\"\"\n         Play audio. Works in Jupyter. if notebook, audio will play normalized -- this is something html5 audio seems to do by default.\n        :param autoplay:\n        :return:\n        \"\"\"\n        if(ISNOTEBOOK):\n            # if(normalize):\n            audiodisp = vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=autoplay);\n            vb_get_ipython().display.display(audiodisp);\n            # vb_get_ipython().display.display(vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=False))\n            # else:\n            # audiodisp = vb_get_ipython().display.Audio(data=self.getMonoEncodedBase64WAV(), rate=self.sampling_rate,\n            #                                            autoplay=autoplay);\n            # vb_get_ipython().display.display(audiodisp);\n            # print(\"html render\")\n            # htmlstr = self.getStringForHTMLStreamingBase64()\n            # ahtml = HTML(data='''<audio alt=\"{}\" controls>\n            #             <source src=\"{}\" type=\"audio/wav\" />\n            #          </audio>'''.format(self.name, htmlstr));\n            # IPython.display.display(ahtml);\n\n        else:\n            p = pyaudio.PyAudio()\n            stream = p.open(format=pyaudio.paFloat32,\n                             channels=self.n_channels,\n                             rate=self.sampling_rate,\n                             output=True,\n                             output_device_index=1\n                             )\n            stream.write(self.getSignal())\n            stream.stop_stream();\n            stream.close()\n            p.terminate()\n\n    def playBeats(self, indices=None, beats=None):\n        beat_inds = indices;\n        if(beats is None):\n            beats = self.getBeatEvents();\n        if(beat_inds is None):\n            beat_inds = [0, len(beats)-1];\n        if(not isinstance(beat_inds, list)):\n            beat_inds=[beat_inds-1, beat_inds, beat_inds+1];\n        if(beat_inds[0]<0):\n            start_time = 0;\n        else:\n            start_time = beats[beat_inds[0]].start;\n        if(beat_inds[-1]>len(beats)):\n            end_time = self.getDuration();\n        else:\n            end_time = beats[beat_inds[-1]].start;\n        self.playSegment(time_range = [start_time, end_time]);\n\n    def AudioClipFromBeatRange(self, beat_range, beats=None):\n        if(beats is None):\n            beats = self.getBeatEvents();\n        if(beat_range is None):\n            beat_range = [0, len(beats)-1];\n        if(beat_range[1] is None):\n            beat_range[1]=len(beats)-1;\n\n        return self.AudioClip(start=beats[beat_range[0]].start, end=beats[beat_range[1]].start);\n\n\n\n\n    def playSegment(self, time_range, autoplay=None):\n        start_time = time_range[0];\n        end_time = time_range[1];\n        if(isinstance(start_time, Event)):\n            start_time = start_time.start;\n        if(isinstance(end_time, Event)):\n            end_time = end_time.start;\n        if(ISNOTEBOOK):\n            audiodisp = vb_get_ipython().display.Audio(data=self.getSignalSegment(time_range=[start_time, end_time]), rate=self.sampling_rate, autoplay=autoplay);\n            vb_get_ipython().display.display(audiodisp);\n            # vb_get_ipython().display.display(vb_get_ipython().display.Audio(data=self.getSignal(), rate=self.sampling_rate, autoplay=False))\n        else:\n            p = pyaudio.PyAudio()\n            stream = p.open(format=pyaudio.paFloat32,\n                             channels=self.n_channels,\n                             rate=self.sampling_rate,\n                             output=True,\n                             output_device_index=1\n                             )\n            stream.write(self.getSignalSegment(time_range=[start_time, end_time]))\n            stream.stop_stream();\n            stream.close()\n            p.terminate()\n\n    def writeToFile(self, output_path=None, output_sampling_rate=None):\n        assert(output_path), \"must provide path to save audio.\"\n        data = self.getSignal();\n        scaled = np.int16(data/np.max(np.abs(data)) * 32767)\n        if(output_sampling_rate is None):\n            output_sampling_rate=44100\n        write(output_path, output_sampling_rate, scaled)\n\n    def setValueRange(self, value_range=None):\n        if(value_range is None):\n            value_range = [-1,1];\n        TimeSignal1D.setValueRange(self, value_range=value_range);\n\n    def resample(self, sampling_rate):\n        new_n_samples = sampling_rate*self.getDuration();\n        self.x = sp.signal.resample(self.x, int(new_n_samples));\n        self.sampling_rate = sampling_rate;\n\n    def GetResampled(self, sampling_rate):\n        new_a = self.clone();\n        new_a.resample(sampling_rate=sampling_rate);\n        return new_a;\n\n\n\n    def AlignedTo(self, B):\n        assert(False),'Abe needs to fix -- broke when messing with alignment code for video';\n\n        A = self.clone();\n        if(A.sampling_rate !=B.sampling_rate):\n            A.resample(B.sampling_rate);\n\n        a_signal = A.getSignal();\n        b_signal = B.getSignal();\n        a_duration = self.getDuration();\n\n        if(len(a_signal) < len(b_signal)):\n            siglen = spotgt_shift_bit_length(len(b_signal));\n        else:\n            siglen = spotgt_shift_bit_length(len(a_signal));\n\n        npada = siglen-len(a_signal);\n        if(npada>0):\n            a_signal = np.pad(a_signal, (0,npada), 'constant', constant_values=(0, 0));\n\n        npadb = siglen-len(b_signal);\n        if(npadb>0):\n            b_signal = np.pad(b_signal, (0,npadb), 'constant', constant_values=(0, 0));\n\n        Af = fftpack.fft(a_signal);\n        Bf = fftpack.fft(b_signal);\n        Ar = Af.conjugate();\n        Br = Bf.conjugate();\n        # Ar = -Af.conjugate();\n        # Br = -Bf.conjugate();\n\n        ashift = np.argmax(np.abs(fftpack.ifft(Ar * Bf)));\n        print(ashift);\n        print((np.argmax(np.abs(fftpack.ifft(Af * Br)))));\n\n        a_return = Audio();\n        a_return.n_channels = 1;\n        a_return.sampling_rate = B.sampling_rate;\n        a_return.x = np.roll(a_signal, ashift);\n\n        return a_return;\n\n    def getOffsetFrom(self, B):\n        return -self.getShiftAmountTo(B);\n\n    def getShiftAmountTo(self, B):\n        \"\"\"\n        Get amount to shift by in seconds (to shift this to alignment with B)\n        \"\"\"\n        a_signal = self.getSignal();\n        b_signal = B.getSignal();\n        a_duration = self.getDuration();\n        if(self.sampling_rate !=B.sampling_rate):\n            ansamps = a_duration*B.sampling_rate;\n            a_signal = sp.signal.resample(a_signal, int(ansamps));\n            # a_signal = librosa.resample(a_signal, self.sampling_rate, B.sampling_rate, res_type='kaiser_fast');\n        if(len(a_signal) < len(b_signal)):\n            siglen = spotgt_shift_bit_length(len(b_signal));\n        else:\n            siglen = spotgt_shift_bit_length(len(a_signal));\n        npada = siglen-len(a_signal);\n        if(npada>0):\n            a_signal = np.pad(a_signal, (0,npada), 'constant', constant_values=(0, 0));\n        npadb = siglen-len(b_signal);\n        if(npadb>0):\n            b_signal = np.pad(b_signal, (0,npadb), 'constant', constant_values=(0, 0));\n\n        # if(len(a_signal) < len(b_signal)):\n        #     npad = len(b_signal)-len(a_signal);\n        #     a_signal = np.pad(a_signal, (0,npad), 'constant', constant_values=(0, 0));\n        #     print('pad1');\n        #\n        # if (len(b_signal) < len(a_signal)):\n        #     npad = len(a_signal) - len(b_signal);\n        #     b_signal = np.pad(b_signal, (0, npad), 'constant', constant_values=(0, 0));\n        #     print('pad2');\n\n        # print('point0')\n\n        Af = fftpack.fft(a_signal);\n        Bf = fftpack.fft(b_signal);\n        Ar = Af.conjugate();\n        Br = Bf.conjugate();\n        # Ar = -Af.conjugate();\n        # Br = -Bf.conjugate();\n        ashiftab = np.argmax(np.abs(fftpack.ifft(Ar * Bf)));\n        durationsamples = self.getDuration()*B.sampling_rate;\n        # if(ashiftab>(durationsamples*0.5)):\n        #     ashiftab = ashiftab-durationsamples;\n        return truediv(ashiftab, B.sampling_rate);\n\n    def getBeatEventList(self, time_range = None):\n        beats = self.getBeats();\n        if(time_range is None):\n            return EventList.FromStartTimes(beats, type='beats');\n\n        start_beat = 0;\n        end_beat = len(beats) - 1;\n        if(time_range[0] is not None):\n            while((start_beat<len(beats)) and (beats[start_beat]<time_range[0])):\n                start_beat=start_beat+1;\n        if(time_range[1] is not None):\n            while(end_beat>0 and (beats[end_beat]>time_range[1])):\n                end_beat = end_beat-1;\n        if(end_beat>start_beat):\n            return EventList.FromStartTimes(beats[start_beat:end_beat], type='beats');\n        else:\n            return None;\n\n\n    def getBeatEvents(self, start_time=None, end_time=None):\n        beat_eventlist = self.getBeatEventList();\n        return beat_eventlist.events;\n\n    def AudioClip(self, start, end):\n        from . import AudioClip\n        clip = AudioClip.AudioClip(path=self.getPath(), start=start, end=end);\n        return clip;\n\n\n    def getWithSoundAdded(self, add_times, sound=None, mute_original=None, gain_original = None):\n        if(sound is None):\n            sound = Audio.PingSound(sampling_rate=self.sampling_rate);\n        if(sound.sampling_rate==self.sampling_rate):\n            s_toadd = sound.getSignal();\n        else:\n            new_n_samples = self.sampling_rate * sound.getDuration();\n            s_toadd = sp.signal.resample(sound.getSignal(), int(new_n_samples));\n\n        result = self.clone();\n        if(mute_original):\n            result.x = np.zeros(result.x.shape);\n        if(gain_original is not None):\n            result.x = result.x*gain_original;\n\n\n        sl = len(s_toadd);\n        for t in add_times:\n            if(t<self.getDuration()):\n                ti = int(t*self.sampling_rate);\n                te = min(len(result.x), ti+sl);\n                result.x[ti:te]=result.x[ti:te]+s_toadd[0:te-ti];\n        result.setValueRange();\n        # result.setMaxAbsValue(1.0);\n        return result;\n\n\n    def showSpectrogram(self, time_range = None, **kwargs):\n        if(hop_length is None):\n            hop_length=AUDIO_DEFAULT_HOP_LENGTH;\n\n        fig = plt.figure();\n\n        S = self.getSpectrogram(hop_length=hop_length, **kwargs);\n        hop_length = self.getFeatureParams('spectrogram').get('hop_length');\n        print((\"hop length: {}\".format(hop_length)));\n        # S = librosa.stft(self.getSignal(), hop_length=hop_length);\n\n        librosa.display.specshow(librosa.amplitude_to_db(S,ref = np.max),sr=self.sampling_rate, hop_length=hop_length, y_axis = 'linear', x_axis = 'time')\n        plt.title('Power Spectrogram')\n        plt.colorbar(format='%+2.0f dB')\n        plt.ylim([0,8000]);\n        plt.xlabel('Time (s)')\n        if (time_range is not None):\n            plt.xlim(time_range);\n        plt.tight_layout()\n        return fig;\n\n    def showMelSpectrogram(self, force_recompute=False, **kwargs):\n        mel_spec = self.getMelSpectrogram(force_recompute=force_recompute, **kwargs);\n        # Make a new figure\n        plt.figure();\n        plt.figure(figsize=(12,4))\n        # Display the spectrogram on a mel scale\n        # sample rate and hop length parameters are used to render the time axis\n        librosa.display.specshow(mel_spec, sr=self.sampling_rate, x_axis='time', y_axis='mel')\n        # Put a descriptive title on the plot\n        plt.title('Mel Power Spectrogram')\n        # draw a color bar\n        plt.colorbar(format='%+02.0f dB')\n        # Make the figure layout compact\n        plt.tight_layout()\n\n\n    @staticmethod\n    def Silence(n_seconds, sampling_rate, name=None):\n        x = np.zeros(int(np.ceil(n_seconds*sampling_rate)));\n        s = Audio(x=x, sampling_rate = sampling_rate, name = name);\n        if(s.name is None):\n            s.name = 'silence';\n        return s;\n\n\n    @staticmethod\n    def _getDampedSin(freq, n_seconds=None, sampling_rate=16000, damping=0.1, noise_floor=0.001):\n        \"\"\"\n\n        :param freq:\n        :param n_seconds: if None, will set length necessary to damp to noise floor, up to 10.0s.\n        :param sampling_rate:\n        :param damping: Every period the amplitude is multiplied by 0.5^damping\n        :param noise_floor:\n        :return:\n        \"\"\"\n        if(n_seconds is None):\n            if(damping>0.005):\n                nosc = truediv(math.log(noise_floor,0.5),damping);\n                n_seconds = truediv(nosc, freq);\n            else:\n                n_seconds = 10.0;\n\n        x = np.sin(np.linspace(0, n_seconds * freq * 2 * np.pi, np.round(n_seconds * sampling_rate)));\n        dmp = np.linspace(0, n_seconds * freq, np.round(n_seconds * sampling_rate))\n        dmp = np.power(0.5, dmp * damping);\n        return np.multiply(x, dmp);\n\n\n\n    @staticmethod\n    def PingSound(n_seconds=None, freqs=None, damping=None, sampling_rate = 16000):\n        if(freqs is None):\n            # freqs = [400,500,600, 700, 800, 900, 1000, 1100, 1200, 1300];\n            # freqs = np.arange(4, 25) * 100\n            freqs = np.arange(5, 25) * 75; # just kind of thought this sounded fine...\n        if(damping is None):\n            damping = [0.05]*len(freqs);\n        if(not isinstance(damping,list)):\n            damping = [damping]*len(freqs);\n        s = Audio._getDampedSin(freq=freqs[0], n_seconds = n_seconds, sampling_rate = sampling_rate, damping=damping[0]);\n        for h in range(1,len(freqs)):\n            new_s = Audio._getDampedSin(freq=freqs[h], n_seconds = n_seconds, sampling_rate = sampling_rate, damping=damping[h]);\n            if(len(new_s)>len(s)):\n                new_s[:len(s)]=new_s[:len(s)]+s;\n                s = new_s;\n            else:\n                s[:len(new_s)] = s[:len(new_s)]+new_s;\n        sa = Audio(x=s, sampling_rate=sampling_rate, name = 'ping');\n        # sa.setValueRange(value_range=[-1,1]);\n        sa.setMaxAbsValue(1.0);\n        return sa;\n\n\n    ##### --- FEATURES --- #####\n\n    def getBeats(self, use_full_signal=True, tightness = None, force_recompute=False):\n        \"\"\"\n\n        :param use_full_signal: If called from AudioClip class, this will determine whether the full signal is used or\n            just the clip. This is important because the tempo is a global property. More evidence for a constant tempo\n            is good, but if the tempo changes over the audio you probably don't want to use the full signal.\n        :param tightness: How tightly to the tempo are beats picked. Must be positive. 0 would not care about tempo.\n            100 is default. This is actually part of the penalty used in the dynamic programming objective from\n            Ellis 2007. In librosa: txwt = -tightness * (np.log(-window / period) ** 2)\n        :param force_recompute:\n        :return:\n        \"\"\"\n        if ((not self.hasFeature(name='beats')) or force_recompute):\n            beat_args = dict(sr = self.sampling_rate, units = 'time');\n\n            if (use_full_signal):\n                beat_args.update(dict(y = self.getFullSignal()));\n            else:\n                beat_args.update(dict(y=self.getSignal()))\n            if (tightness is not None):\n                beat_args.update(dict(tightness=tightness));\n\n            # print(beat_args)\n            tempo, beats = librosa.beat.beat_track(**beat_args);\n            self.setFeature(name='tempo', value=tempo);\n            self.setFeature(name='beats', value=beats);\n        return self.getFeature(name='beats');\n\n    def getBeatVector(self, vector_length=None, force_recompute=False):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        if ((not self.hasFeature(name='beatvector')) or force_recompute):\n            D = self.getDuration();\n            if (vector_length is None):\n                vector_length = int(math.ceil(D * 240));\n            rvec = np.zeros(vector_length);\n            beats = self.getFeature('beats');\n            step = truediv(D, vector_length);\n            for i in range(len(beats)):\n                b = beats[i];\n                id = int(truediv(b, step));\n                rvec[id] = 1;\n            self.setFeature(name='beatvector', value=rvec);\n        return self.getFeature(name='beatvector');\n\n    def getOnsets(self, use_full_signal=True, force_recompute=False, **kwargs):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        if ((not self.hasFeature(name='onsets')) or force_recompute):\n            if (use_full_signal):\n                onsets = librosa.onset.onset_detect(y=self.getFullSignal(), sr=self.sampling_rate, units='time',\n                                                    **kwargs);\n                self.setFeature(name='onsets', value=onsets);\n            else:\n                onsets = librosa.onset.onset_detect(y=self.getSignal(), sr=self.sampling_rate, units='time',\n                                                    **kwargs);\n                self.setFeature(name='onsets', value=onsets);\n        return self.getFeature(name='onsets');\n\n    def getOnsetSamplingRate(self):\n        return np.true_divide(self.sampling_rate, AUDIO_DEFAULT_HOP_LENGTH);\n\n    def pickOnsets(self, pre_max_time=0.03,\n                   post_max_time=0.0,\n                   pre_avg_time=0.1,\n                   post_avg_time=0.1,\n                   wait_time=0.03,\n                   delta=0.07,\n                   force_recompute=True, **kwargs):\n        \"\"\"\n\n        :param pre_max_time:\n        :param post_max_time:\n        :param pre_avg_time:\n        :param post_avg_time:\n        :param wait_time:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        # kwargs.setdefault('pre_max', 0.03 * sr // hop_length)  # 30ms\n        # kwargs.setdefault('post_max', 0.00 * sr // hop_length + 1)  # 0ms\n        # kwargs.setdefault('pre_avg', 0.10 * sr // hop_length)  # 100ms\n        # kwargs.setdefault('post_avg', 0.10 * sr // hop_length + 1)  # 100ms\n        # kwargs.setdefault('wait', 0.03 * sr // hop_length)  # 30ms\n        # kwargs.setdefault('delta', 0.07)\n\n        pick_params = dict(\n            pre_max_time=pre_max_time,\n            post_max_time=post_max_time,\n            pre_avg_time=pre_avg_time,\n            post_avg_time=post_avg_time,\n            wait_time=wait_time,\n            delta=delta,\n        )\n\n        tp_keys = list(pick_params.keys());\n        for p in tp_keys:\n            pick_params[p] = int(round(self.getOnsetSamplingRate() * pick_params[p]));\n\n        dparams = dict(\n            pre_max=pick_params['pre_max_time'],\n            post_max=pick_params['post_max_time'] + 1,\n            pre_avg=pick_params['pre_avg_time'],\n            post_avg=pick_params['post_avg_time'] + 1,\n            wait=pick_params['wait_time'],\n            delta=delta\n        )\n\n        return self.getOnsets(force_recompute=force_recompute, **dparams);\n\n    def getEvents(self):\n        return self.getBeatEvents();\n\n    def getEventList(self):\n        return EventList(self.getBeatEvents());\n\n    def getOnsetEvents(self):\n        onsets = self.getOnsets();\n        events = Event.FromStartTimes(onsets, type='onsets');\n        return events;\n\n    def getBeatEvents(self, start_time=None, end_time=None, **kwargs):\n        beats = self.getBeats(**kwargs);\n        start_beat = 0;\n        end_beat = len(beats) - 1;\n        if(start_time is not None):\n            while((start_beat<len(beats)) and (beats[start_beat]<start_time)):\n                start_beat=start_beat+1;\n        if(end_time is not None):\n            while(end_beat>0 and (beats[end_beat]>end_time)):\n                end_beat = end_beat-1;\n        if(end_beat>start_beat):\n            return Event.FromStartTimes(beats[start_beat:end_beat], type='beats');\n        else:\n            return None;\n\n    def getOnsetEnvelope(self, use_full_signal=True, force_recompute=False, centering=True, **kwargs):\n        \"\"\"use_full_signal only makes a difference in AudioClip subclass.\"\"\"\n        feature_name = 'onset_envelope';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            if(use_full_signal):\n                eval_sig = self.getFullSignal();\n            else:\n                eval_sig = self.getSignal();\n            onsets = librosa.onset.onset_strength(y=eval_sig, sr=self.sampling_rate, centering=centering, hop_length=AUDIO_DEFAULT_HOP_LENGTH, **kwargs);\n\n            self.setFeature(name=feature_name, value=onsets);\n        return self.getFeature(name=feature_name);\n\n\n    def getMelSpectrogram(self, n_mels = 128, force_recompute=False):\n        feature_name = 'melspectrogram';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            params = dict( sr = self.sampling_rate,\n                                n_mels = n_mels);\n            Spec = librosa.feature.melspectrogram(self.getSignal(), **params);\n            self.setFeature(name=feature_name, value=librosa.power_to_db(Spec, ref=np.max), params=params);\n        return self.getFeature(feature_name);\n\n    def getSpectrogram(self, hop_length=None, force_recompute=False, **kwargs):\n        feature_name = 'spectrogram';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            # params = dict( sr = self.sampling_rate);\n            # params.update(kwargs);\n            params = dict(kwargs);\n\n            if(hop_length is None):\n                hop_length = AUDIO_DEFAULT_HOP_LENGTH;\n            params['hop_length'] = hop_length;\n\n            center = kwargs.get('center');\n            if(center is None):\n                center = True;\n            params['center'] = center;\n            # print('recomputing {}'.format(hop_length))\n\n            S = np.abs(librosa.stft(self.getSignal(), **params));\n            self.setFeature(name=feature_name, value=S, params=params);\n        return self.getFeature(feature_name);\n\n    def getRMSE(self, force_recompute=False, hop_length=None, frame_length=None):\n        feature_name = 'rmse';\n        if((not self.hasFeature(name=feature_name)) or force_recompute):\n            if(frame_length is None):\n                frac_of_second = 0.05;\n                frame_length=max(1, int(self.sampling_rate*frac_of_second));\n            if(hop_length is None):\n                hop_length=int(math.floor(frame_length*0.5));\n            params = dict( hop_length = hop_length,\n                                center = True,\n                                frame_length = frame_length);\n            rmse = librosa.feature.rmse(y=self.getSignal(), **params);\n            self.setFeature(name=feature_name, value=np.ndarray.flatten(rmse), params=params);\n        return self.getFeature(feature_name);\n\n\n    def getBeatTimeBefore(self, t):\n        return self.getBeatBefore(t=t).start;\n\n    def getBeatBefore(self, t):\n        beats = self.getBeatEvents();\n        bi = self.getBeatIndexBefore(t=t);\n        return beats[bi].start;\n\n    def getBeatIndexBefore(self, t):\n        beats = self.getBeatEvents();\n        for i, b in enumerate(beats):\n            if(b.start>t):\n                return i-1;\n        return len(beats)-1;\n\n\n    def getTempogram(self, window_length=None, force_recompute=None, frame_rate=None, resample_rate = None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param window_length: in seconds\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'tempogram';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            if (window_length is None):\n                window_length = DEFAULT_TEMPOGRAM_WINDOW_SECONDS;\n            tpgparams = {};\n            tpgparams.update(kwargs);\n\n            sr = self.sampling_rate;\n            y=self.getSignal();\n            if(resample_rate is None):\n                resample_rate = 22050;\n            if(sr>resample_rate):\n                print((\"resampling {}Hz to {}Hz\".format(sr, resample_rate)));\n                y = librosa.core.resample(y, orig_sr=sr, target_sr=resample_rate);\n                sr = resample_rate;\n                print(\"resampled\")\n\n            if(frame_rate is None):\n                frame_rate = 30;\n            hop_length = int(round(truediv(sr,frame_rate)));\n            win_length = int(round(window_length * frame_rate));\n\n            tparams = dict(y=y,\n                           sr=sr,\n                           hop_length=hop_length,\n                           win_length=win_length,\n                           **kwargs);\n            tpgparams.update(dict(sr=sr,hop_length=hop_length, win_length=win_length));\n            result = librosa.feature.tempogram(**tparams);\n            ###########\n            tempo_bpms = librosa.tempo_frequencies(result.shape[0], hop_length=hop_length, sr=sr)\n            self.setFeature(name='tempogram_bpms', value=tempo_bpms);\n            self.setFeature(name=feature_name, value=result, params=tpgparams);\n            self.setInfo(label='tempogram_params',value=tpgparams);\n\n        return self.getFeature(feature_name);\n\n    def plotTempogram(self, window=None, time_range=None, **kwargs):\n        tempogram = self.getFeature('tempogram', force_recompute=True);\n        tparams = self.getInfo('tempogram_params')\n        toshow = tempogram;\n        if(window is not None):\n            wstart=int(round(window[0]*self.sampling_rate));\n            wend = int(round(window[1]*self.sampling_rate));\n            toshow = tempogram[:,wstart:wend];\n\n        mplt = librosa.display.specshow(toshow, sr=tparams['sr'], hop_length=tparams['hop_length'], x_axis = 'time', y_axis = 'tempo')\n        plt.legend(frameon=True, framealpha=0.75)\n        plt.set_cmap('coolwarm')\n        plt.colorbar(format='%+2.0f dB')\n        if (time_range is not None):\n            plt.xlim(time_range);\n        plt.xlabel('Time (s)')\n        plt.title('Audio Tempogram');\n        plt.tight_layout()\n        return mplt;\n\n    def plotOnsets(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = self.getOnsetEvents();\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotBeats(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = self.getBeatEvents();\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.title('Onset Envelope and Beats');\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotOnsetEnvelope(self, **kwargs):\n        signal = self.getFeature('onset_envelope');\n        events = None;\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        plt.title('Onset Envelope');\n        plt.xlabel('Time (s)')\n        plt.ylabel('Onset Strength')\n        return mplt;\n\n    def plotSignal(self, time_range=None, ylim=None, **kwargs):\n        signal = self.getSignal();\n        # Event.PlotSignalAndEvents(signal, sampling_rate=self.getOnsetSamplingRate(), events=events, **kwargs);\n        times = np.arange(len(signal));\n        times = times * truediv(1.0, self.sampling_rate);\n        mplt = plt.plot(times, signal);\n        if (time_range is not None):\n            plt.xlim(time_range[0], time_range[1])\n        if (ylim is not None):\n            plt.ylim(ylim);\n        plt.title('Time Signal');\n        return mplt;\n\n\n    FEATURE_FUNCS['melspectrogram'] = getMelSpectrogram;\n    FEATURE_FUNCS['spectrogram'] = getSpectrogram;\n    FEATURE_FUNCS['rmse'] = getRMSE;\n    FEATURE_FUNCS['beats'] = getBeats;\n    FEATURE_FUNCS['onsets'] = getOnsets;\n    FEATURE_FUNCS['beatvector'] = getBeatVector;\n    FEATURE_FUNCS['tempogram'] = getTempogram;\n    FEATURE_FUNCS['onset_envelope'] = getOnsetEnvelope;\n\n\ndef _make_wav(data, rate):\n    \"\"\" Transform a numpy array to a PCM bytestring \"\"\"\n    import struct\n    from io import BytesIO\n    import wave\n\n    try:\n        import numpy as np\n\n        data = np.array(data, dtype=float)\n        if len(data.shape) == 1:\n            nchan = 1\n        elif len(data.shape) == 2:\n            # In wave files,channels are interleaved. E.g.,\n            # \"L1R1L2R2...\" for stereo. See\n            # http://msdn.microsoft.com/en-us/library/windows/hardware/dn653308(v=vs.85).aspx\n            # for channel ordering\n            nchan = data.shape[0]\n            data = data.T.ravel()\n        else:\n            raise ValueError('Array audio input must be a 1D or 2D array')\n        scaled = np.int16(data / np.max(np.abs(data)) * 32767).tolist()\n    except ImportError:\n        # check that it is a \"1D\" list\n        idata = iter(data)  # fails if not an iterable\n        try:\n            iter(next(idata))\n            raise TypeError('Only lists of mono audio are '\n                            'supported if numpy is not installed')\n        except TypeError:\n            # this means it's not a nested list, which is what we want\n            pass\n        maxabsvalue = float(max([abs(x) for x in data]))\n        scaled = [int(x / maxabsvalue * 32767) for x in data]\n        nchan = 1\n\n    fp = BytesIO()\n    waveobj = wave.open(fp, mode='wb')\n    waveobj.setnchannels(nchan)\n    waveobj.setframerate(rate)\n    waveobj.setsampwidth(2)\n    waveobj.setcomptype('NONE', 'NONE')\n    waveobj.writeframes(b''.join([struct.pack('<h', x) for x in scaled]))\n    val = fp.getvalue()\n    waveobj.close()\n\n    return val"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/AudioClip.py",
    "content": "from .Audio import *\n\nclass AudioClip(Audio):\n    \"\"\"AudioClip (class): A segment of a video, and a bunch of convenience functions to go with it.\n        Attributes:\n            start: The name of the video\n            end: The framerate of the video\n    \"\"\"\n\n    def VBOBJECT_TYPE(self):\n        return 'AudioClip';\n\n    def __init__(self, audio=None, start=None, end=None, path=None):\n        assert(not (audio and path)), \"provided both video object and path to VideoClip constructor.\"\n        # assert((start is not None) and (end is not None)), \"must provide start time and end time to AudioClip constructor\"\n        Audio.__init__(self, path=path);\n        #self.initializeBlank();#gets called by parent\n        if(start is None):\n            start = 0;\n        if(end is None):\n            if(audio is not None):\n                end = audio.getDuration();\n            else:\n                end = truediv(len(self.x), self.sampling_rate);\n\n        self.start = start;\n        self.end = end;\n\n\n        if(audio):\n            self.setPath(audio.getPath());\n            self.x = audio.x;\n            self.sampling_rate=audio.sampling_rate;\n            self.n_channels=audio.n_channels;\n            stereo = audio.getStereo();\n            if(stereo):\n                self.a_info['stereo_signal']=stereo;\n        if(self.sampling_rate):\n            self._pull_clip_potion();\n\n\n    def _pull_clip_potion(self):\n        startsample = math.floor(self.sampling_rate * self.start);\n        endsample = math.ceil(self.sampling_rate * self.end);\n        startinsample = max(startsample, 0);\n        endinsample = min(endsample, len(self.x));\n        self.clipped = self.x[int(startinsample):int(endinsample)];\n        if (startsample < 0):\n            self.clipped = np.concatenate((np.zeros(int(-startsample)), self.clipped));\n        if (endsample > len(self.x)):\n            self.clipped = np.concatenate((np.zeros(int(endsample - len(self.x))), self.clipped));\n\n\n    def resample(self, sampling_rate):\n        Audio.resample(self, sampling_rate);\n        self._pull_clip_potion();\n\n    def initializeBlank(self):\n        Audio.initializeBlank(self);\n        self.start = None;\n        self.end = None;\n        self.resampled = None;\n        self.clipped = None;\n\n    def getSignal(self, resample=False):\n        if(self.resampled):\n            return self.resampled;\n        if(resample):\n            assert(False), \"haven't implemented audio clip resampling yet.\";\n        return self.clipped\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Event.py",
    "content": "from .VisBeatImports import *\n\nclass Event(AObject):\n    \"\"\"Event (class): An event in time, either in video or audio\n        Attributes:\n            start: when the event starts\n    \"\"\"\n\n    DIRECTION_FORWARD = 1;\n    DIRECTION_BACKWARD = -1;\n    DIRECTION_BOTH = 0;\n    _EVENT_PHASE_BASE_RES = 8;\n\n    def AOBJECT_TYPE(self):\n        return 'Event';\n\n    def __str__(self):\n        return str(self.getAttributeDict());\n\n    def __init__(self, start=None, type=None, weight=None, index=None, is_active=1, unrolled_start = None, direction=0, **kwargs):\n        AObject.__init__(self, path=None);\n        self.start = start;\n        self.type=type;\n        self.weight=weight;\n        self.index = index;\n        self.unrolled_start = unrolled_start;\n        self.is_active = is_active;\n        self.direction = direction;\n        self.a_info.update(kwargs);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.start = None;\n        self.type = None;\n        self.weight = None;\n        self.index = None;\n        self.unrolled_start = None;\n        self.is_active = None;\n        self.direction = None;\n\n\n    def getAttributeDict(self):\n        d = dict();\n        d['start'] = self.start;\n        d['type'] = self.type;\n        d['weight'] = self.weight;\n        d['index'] = self.index;\n        d['unrolled_start'] = self.unrolled_start;\n        d['is_active'] = self.is_active;\n        d['direction'] = self.direction;\n        return d;\n\n    def toDictionary(self):\n        d=AObject.toDictionary(self);\n        d.update(self.getAttributeDict());\n        return d;\n\n\n    def initAttributesFromDictionary(self, d):\n        self.start = d['start'];\n        self.type = d.get('type');\n        self.weight = d.get('weight');\n        self.index = d['index'];\n        self.unrolled_start = d.get('unrolled_start');\n        self.is_active = d['is_active'];\n        if (d.get('direction') is None):\n            self.direction = 0;\n        else:\n            self.direction = d['direction'];\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        self.initAttributesFromDictionary(d);\n\n    def clone(self, start=None):\n        newe = Event();\n        newe.initFromDictionary(self.toDictionary());\n        if (start):\n            newe.start = start;\n        return newe;\n\n\n    def _getIsSelected(self):\n        return self.getInfo('is_selected');\n    def _setIsSelected(self, is_selected):\n        self.setInfo('is_selected', is_selected);\n\n    def _getPhase(self, phase_resolution=None):\n        if (self.getInfo('phase') is None):\n            return -1;\n        if (phase_resolution is None):\n            return self.getInfo('phase');\n        else:\n            return self.getInfo('phase') * (phase_resolution / Event._EVENT_PHASE_BASE_RES);\n\n    def _setPhase(self, phase, phase_resolution):\n        if (phase_resolution is None):\n            self.setInfo('phase', phase);\n        else:\n            self.setInfo('phase', phase * (Event._EVENT_PHASE_BASE_RES / phase_resolution));\n\n    def _getBoundaryType(self):\n        return self.getInfo('boundary_type');\n    def _setBoundaryType(self, boundary_type):\n        self.setInfo('boundary_type', boundary_type);\n\n    @classmethod\n    def _FromGUIDict(cls, gd, phase_resolution=None):\n        e = cls();\n        e.initAttributesFromDictionary(gd);\n        e._setPhase(gd['phase'], phase_resolution=phase_resolution);\n        e._setBoundaryType(gd.get('boundary_type'));\n        e._setIsSelected(gd.get('is_selected'));\n        return e;\n\n    @classmethod\n    def _FromGUIDicts(cls, gds, type=None):\n        events = [];\n        for gd in gds:\n            ne = cls._FromGUIDict(gd);\n            if (type is not None):\n                ne.type = type;\n            events.append(ne);\n        return events;\n\n    def _toGUIDict(self):\n        '''\n        note that is_active is switched to 0 or 1 for javascript/json\n        :return:\n        '''\n        d = self.getAttributeDict();\n        if(self.is_active):\n            d['is_active'] = 1;\n        else:\n            d['is_active'] = 0;\n        d['phase'] = self._getPhase();\n        d['boundary_type'] = self._getBoundaryType();\n        d['is_selected'] = self._getIsSelected();\n        return d;\n\n    @staticmethod\n    def _ToGUIDicts(events, active=None):\n        '''\n        convert to dicts for javascript GUI\n        :param events:\n        :param active: if not none, all of the is_active flags will be set to this\n        :return:\n        '''\n        startind = int(round(time.time() * 1000));\n        starts = [];\n        for e in range(len(events)):\n            de = events[e]._toGUIDict();\n            if (active is not None):\n                assert (active is 0 or active is 1), \"is_active must be 0 or 1\";\n                de['is_active'] = active;\n            if (de.get('index') is None):\n                de['index'] = startind + e;\n            starts.append(de);\n        return starts;\n\n\n    def getUnrolledStartTime(self):\n        if(self.unrolled_start is not None):\n            return self.unrolled_start;\n        else:\n            return self.start;\n\n\n    def getStartTime(self):\n        return self.start;\n\n\n\n    def getShifted(self, new_start_time):\n        return Event(self.start-new_start_time, type=self.type, weight=self.weight, index=self.index);\n\n\n\n\n    @staticmethod\n    def GetUnrolledList(event_list, assert_on_folds=None):\n        out_list = [];\n        event0 = event_list[0].clone();\n        event0.unrolled_start = event0.start;\n        event0.index = 0;\n        out_list.append(event0);\n        for e in range(1,len(event_list)):\n            newe = event_list[e].clone();\n            if(assert_on_folds):\n                assert(newe.start>=out_list[-1].start), 'FOLD (non-monotonic event list) DETECTED WHEN NOT ALLOWED!!!\\n see Event.GetUnrolledList'\n            newe.unrolled_start = out_list[-1].unrolled_start+np.fabs(newe.start-out_list[-1].start);\n            newe.index = e;\n            out_list.append(newe);\n        return out_list;\n\n    @staticmethod\n    def NewFromIndices(event_list, inds):\n        out_list = [];\n        for ei in inds:\n            out_list.append(event_list[ei].clone());\n        return out_list;\n\n    @staticmethod\n    def RollToNOld(events, n_out, momentum = 0.25):\n        inds = [0];\n        step = 1;\n        n_events = len(events);\n        for b in range(1,n_out):\n            lastind = inds[-1];\n            if ((n_out-b)<(n_events-lastind) or lastind==0):\n                inds.append(lastind+1);\n                step = 1;\n            elif(lastind==(len(events)-1)):\n                inds.append(len(events)-2);\n                step = -1;\n            else:\n                foreward_p = 0.5+momentum;\n                roll = np.random.rand();\n                if(roll<foreward_p):\n                    inds.append(lastind+step);\n                else:\n                    inds.append(lastind-step);\n                    step = -step;\n        print(inds);\n        return Event.GetUnrolledList(Event.NewFromIndices(events, inds));\n\n    @staticmethod\n    def UnfoldToN(events, n_out, momentum=0.25):\n        # This weird way of implementing is the result of stripping non-visbeat stuff out of the original code...\n        return Event.RollToN(events=events, n_out=n_out, momentum=momentum);\n\n\n\n    @staticmethod\n    def GetDirectedLinks(events):\n        links = [{}]\n        links[0]['prev_f']=None;\n        links[0]['prev_b'] = None;\n        lastf = None;\n        lastb = None;\n        if(events[0].direction<1):\n            lastb = 0;\n        if(events[0].direction>-1):\n            lastf = 0;\n\n        for ei in range(1,len(events)):\n            links.append({});\n            links[ei]['prev_f']=lastf;\n            links[ei]['prev_b']=lastb;\n\n            lastbu = lastb;\n            lastfu = lastf;\n            if(lastbu is None):\n                lastbu = 0;\n            if(lastfu is None):\n                lastfu = 0;\n\n\n            if(events[ei].direction<1):\n                for lb in range(lastbu,ei):\n                    links[lb]['next_b']=ei;\n                    # print(\"ei is {} and lastbu is {}, lastb is {}\".format(ei, lastbu, lastb));\n                lastb = ei;\n            if (events[ei].direction>-1):\n                for lf in range(lastfu, ei):\n                    links[lf]['next_f'] = ei;\n                    # print(\"ei is {} and lastfu is {}, lastf is {}\".format(ei, lastfu, lastf));\n                lastf = ei;\n\n        return links;\n\n\n    @staticmethod\n    def RollToN(events, n_out, start_index = 0, momentum=0.1):\n        links = Event.GetDirectedLinks(events);\n        inds = [start_index];\n        step = 1;\n        n_events = len(events);\n        for b in range(1, n_out):\n            lastind = inds[-1];\n            foreward_p = 0.5 + momentum;\n            roll = np.random.rand();\n\n            if (roll < foreward_p):\n                step = step;\n            else:\n                step = -step;\n\n            if(links[lastind].get('prev_b') is None):\n                step = 1;\n            if(links[lastind].get('next_f') is None):\n                step = -1;\n\n            if(step>0):\n                inds.append(links[lastind]['next_f']);\n            else:\n                inds.append(links[lastind]['prev_b']);\n        # print(inds);\n        return Event.GetUnrolledList(Event.NewFromIndices(events, inds));\n\n\n\n    @staticmethod\n    def Clone(event_list):\n        out_list = [];\n        for ei in event_list:\n            out_list.append(ei.clone());\n        return out_list;\n\n    @staticmethod\n    def SetDirections(event_list, direction):\n        for e in range(len(event_list)):\n            event_list[e].direction = direction;\n        return event_list;\n\n\n\n    @classmethod\n    def FromStartTimes(cls, starts, type=None):\n        events = [];\n        for s in starts:\n            events.append(cls(start=s, type=type));\n        return events;\n\n    @classmethod\n    def FromStartsAndWeights(cls, starts, weights, type=None):\n        events = [];\n        assert(len(starts)==len(weights)), 'Event.FromStartsAndWeights got {} starts and {} weights'.format(len(starts), len(weights));\n        for s in range(len(starts)):\n            events.append(cls(start=starts[s], weight=weights[s],type=type));\n        return events;\n\n    @staticmethod\n    def ToStartTimes(events):\n        starts = np.zeros(len(events));\n        for e in range(len(events)):\n            starts[e]=events[e].start;\n        return starts;\n\n    @staticmethod\n    def ToWeights(events):\n        weights = np.zeros(len(events));\n        for e in range(len(events)):\n            weights[e] = events[e].weight;\n        return weights;\n\n    #endpoint is false if events are already placed at beginning and end\n    @staticmethod\n    def RepeatToLength(events, n, endpoints=False):\n        if(n<len(events)):\n            return events[:n];\n        if(n==len(events)):\n            return events;\n\n        if(endpoints):\n            print(\"HAVE NOT IMPLEMENTED ENDPOINTS VERSION OF REPEAT\")\n\n        dup_index = 1;\n        while(len(events)<n):\n            interval = events[dup_index].start-events[dup_index-1].start;\n            last_time = events[-1].start;\n            newevent = events[dup_index].clone(start=last_time+interval);\n            events.append(newevent);\n            dup_index=dup_index+1;\n        return events;\n\n    @staticmethod\n    def Double(events):\n        doubled = [];\n        for e in range(1,len(events)):\n            halfstart = 0.5*(events[e].start+events[e-1].start);\n            doubled.append(events[e].clone(start=halfstart));\n            doubled.append(events[e]);\n        return doubled;\n\n    @staticmethod\n    def Half(events, offset=0):\n        if(offset is None):\n            offset=0;\n\n        halved = [];\n        for e in range(1,len(events)):\n            if((e%2)==offset):\n                halved.append(events[e]);\n        return halved;\n\n    @staticmethod\n    def SubdivideIntervals(events, extra_samples_per_interval=1):\n        newe = [];\n        samples = np.linspace(0,1,extra_samples_per_interval+2)[1:-1];\n        newe.append(events[0]);\n        for e in range(1, len(events)):\n            for s in samples:\n                newstart = events[e].start*s+events[e-1].start*(1.0-s);\n                newe.append(events[e].clone(start=newstart));\n            newe.append(events[e].clone())\n        return newe;\n\n    @staticmethod\n    def Third(events, offset=0):\n        if (offset is None):\n            offset = 0;\n        third = [];\n        for e in range(len(events)):\n            if (not ((e+offset) % 3)):\n                third.append(events[e]);\n        return third;\n\n    @staticmethod\n    def SubsampleEveryN(events, n, offset=0):\n        if (offset is None):\n            offset = 0;\n        newe = [];\n        for e in range(len(events)):\n            if (not ((e + offset) % n)):\n                newe.append(events[e]);\n        return newe;\n\n    # @staticmethod\n    # def FromSignalBeats(signal, sampling_rate, event_type=None, **kwargs):\n    #     # seg = [0,100]\n    #     # xvals = range(seg[1]-seg[0])\n    #     xvals = np.arange(len(signal));\n    #     xvals = xvals*truediv(1.0, sampling_rate);\n    #\n    #     vis_tempo, beatinds = librosa.beat.beat_track(y=None, sr=sampling_rate, onset_envelope=signal, hop_length=1, start_bpm=100.0, tightness=80,\n    #                                                   trim=True, bpm=None, units='frames');\n    #     peaktimes = xvals[beatinds.astype(int)];\n    #     peakvals = signal[beatinds.astype(int)];\n    #     return Event.FromStartsAndWeights(starts=peaktimes, weights=peakvals, type=event_type);\n\n\n    @staticmethod\n    def FromSignalPeaks(signal, sampling_rate, event_type=None, index_offset=None, **kwargs):\n        xvals = np.arange(len(signal));\n        xvals = xvals*truediv(1.0, sampling_rate);\n\n        time_params = dict(\n            pre_max_time=0.2,\n            post_max_time=0.2,\n            pre_avg_time=0.2,\n            post_avg_time=0.2,\n            wait_time=0.1,\n        )\n        tp_keys = list(time_params.keys());\n        time_params.update(kwargs);\n\n        delta = kwargs.get('delta');\n        if (delta is None):\n            delta = 0.2;\n\n        print(delta)\n\n        for p in tp_keys:\n            time_params[p] = int(round(sampling_rate * time_params[p]));\n\n        dparams = dict(\n            pre_max=time_params['pre_max_time'],\n            post_max=time_params['post_max_time'],\n            pre_avg=time_params['pre_avg_time'],\n            post_avg=time_params['post_avg_time'],\n            wait=time_params['wait_time'],\n            delta=delta\n        )\n\n        # print(dparams)\n        peakinds = librosa.util.peak_pick(x=signal, **dparams);\n        # print(peakinds)\n        if(not len(peakinds)):\n            return [];\n        if(index_offset is not None):\n            print(('index offset {}'.format(index_offset)))\n            for pi in range(len(peakinds)):\n                newi = peakinds[pi]+index_offset;\n                if(newi>=0 and newi<len(xvals)):\n                    print(('{} to {}'.format(peakinds[pi], newi)))\n                    peakinds[pi]=newi;\n\n\n        peaktimes = xvals[peakinds];\n        peakvals = signal[peakinds];\n        return Event.FromStartsAndWeights(starts=peaktimes, weights=peakvals, type=event_type);\n\n\n    @staticmethod\n    def PlotEventMatches(source_events, target_events, source_in=None, target_in=None):\n        t_height = 0.75;\n        s_height = 0.25;\n        if ((source_in is not None) and (target_in is not None)):\n            n_in = min(len(source_in), len(target_in));\n            evt = Event.ToStartTimes(target_in[:n_in]);\n            evs = Event.ToStartTimes(source_in[:n_in]);\n            plt.plot(evt, np.ones(len(evt)) * t_height, 'o');\n            plt.plot(evs, np.ones(len(evs)) * s_height, 'o');\n\n        s_et = Event.ToStartTimes(source_events);\n        t_et = Event.ToStartTimes(target_events);\n\n        for ev in range(len(target_events)):\n            plt.plot([s_et[ev], t_et[ev]], [s_height, t_height], '-');\n\n    @staticmethod\n    def GetWithFirstEventAt(events, first_event_time):\n        oute = [];\n        shift_time = events[0].start-first_event_time;\n        for e in events:\n            oute.append(e.getShifted(new_start_time=shift_time));\n        return oute;\n\n    @staticmethod\n    def GetWithStartTimesShifted(events, new_start_time):\n        oute = [];\n        for e in events:\n            oute.append(e.getShifted(new_start_time=new_start_time));\n        return oute;\n\n    @staticmethod\n    def GetScaled(events, scale):\n        oute = [];\n        for e in events:\n            oute.append(Event(e.start*scale, weight=e.weight, type=e.type, index=e.index));\n        return oute;\n\n    @staticmethod\n    def GetScaledAndStartingAt(events, scale, starting_at):\n        ev = Event.GetScaled(events, scale);\n        ev = Event.GetWithFirstEventAt(ev, starting_at);\n        return ev;\n\n    @staticmethod\n    def ClosestToTargetMatch(source_events, target_events):\n        def _closest_e(target_e):\n            def sortfunc_e(source_e):\n                return math.fabs(source_e[1].start-target_e.start);\n            return sortfunc_e;\n        def _getinds(s_sort):\n            inds = [];\n            for s in s_sort:\n                inds.append(s[0]);\n            return inds;\n        def _getevents(s_sorted):\n            evnts = [];\n            for s in s_sort:\n                evnts.append(s[1]);\n            return evnts;\n\n        S = [];\n        T = [];\n        for s in range(len(source_events)):\n            S.append([s, source_events[s]]);\n        for t in range(len(target_events)):\n            T.append([t, target_events[t]]);\n\n        S_sorted = [];\n        for t in T:\n            S_sorted.append(sorted(S, key=_closest_e(t[1])));\n\n        s_out_inds = [-1]*len(T);\n        match_map = {};\n        for ti in range(len(S_sorted)):\n            # print(S_sorted[ti][0][0]);\n            matched_source_event_i = S_sorted[ti][0][0];#sorted lists, first element, index value for index\n            existing_match = match_map.get(matched_source_event_i);\n            matchdist = math.fabs(source_events[matched_source_event_i].start - target_events[ti].start);\n            if(existing_match is not None):\n                if(matchdist<existing_match[1]):\n                    # print('overrule')\n                    s_out_inds[existing_match[0]]=-1;\n                    s_out_inds[ti]=matched_source_event_i;\n                    # print(\"ti {}\\nmatched {}\\n\".format(ti, matched_source_event_i));\n                    match_map[matched_source_event_i]=[ti, matchdist];\n            else:\n                match_map[matched_source_event_i] = [ti, matchdist];\n                s_out_inds[ti]=matched_source_event_i;\n\n        S_out = [];\n        T_out = [];\n        # print(\"s_out_inds: {}\".format(s_out_inds))\n        for e in range(len(s_out_inds)):\n            if(s_out_inds[e]>=0):\n                T_out.append(target_events[e]);\n                S_out.append(source_events[s_out_inds[e]]);\n\n        return S_out, T_out;\n\n    @staticmethod\n    def Sort(event_list, func=None):\n        assert(func is None or func=='start' or func=='time'), \"have not implemented sort by {}\".format(func);\n        event_list.sort(key=lambda x: x.start);\n        return event_list;\n\n    @staticmethod\n    def GetSorted(event_list, func=None):\n        clone = Event.Clone(event_list);\n        Event.Sort(clone, func=func);\n        return clone;\n\n    @staticmethod\n    def GetWithTwoWayMerged(event_list, merge_window = 0.1):\n        event_list_sorted = Event.GetSorted(event_list);\n        new_events = [];\n        new_events.append(event_list_sorted[0].clone());\n        for ei in range(1,len(event_list_sorted)):\n            thise = event_list_sorted[ei];\n            if((thise.start-new_events[-1].start)<merge_window):\n                if((thise.direction+new_events[-1].direction)==0):\n                    new_events[-1].start = 0.5*(thise.start+new_events[-1].start);\n                    new_events[-1].direction = 0;\n            else:\n                new_events.append(thise.clone());\n        return new_events\n\n\n    @staticmethod\n    def ApplyIndices(event_list):\n        for e in range(len(event_list)):\n            event_list[e].index = e;\n\n    @staticmethod\n    def PlotSignalAndEvents(signal, sampling_rate, events, time_range = None, ylim=None, **kwargs):\n        times = np.arange(len(signal));\n        times = times*truediv(1.0,sampling_rate);\n\n        if (kwargs.get('other_events')):\n            oet, oev = eventsToTimes(kwargs.get('other_events'), time_range);\n            plt.plot(oet, oev, 'x');\n\n        if(events is not None):\n            btimes = Event.ToStartTimes(events);\n            binds = np.round(btimes*sampling_rate).astype(int);\n            bvals = signal[binds];\n\n            mplt = plt.plot(times, signal, '-', btimes, bvals, 'o');\n        else:\n            mplt = plt.plot(times, signal, '-');\n\n        if(time_range is not None):\n            plt.xlim(time_range[0], time_range[1])\n        if(ylim is not None):\n            plt.ylim(ylim);\n        # plt.show()\n        return mplt;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/EventList.py",
    "content": "from .Event import *\n\nclass EventList(AObject):\n    \"\"\"Event (class): An event in time, either in video or audio\n        Attributes:\n            start: when the event starts\n    \"\"\"\n\n    def AOBJECT_TYPE(self):\n        return 'EventList';\n\n    def __init__(self, events=None):\n        AObject.__init__(self, path=None);\n        if(events is not None):\n            self.events = events;\n\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.events = [];\n\n    def list(self):\n        return self.events;\n\n    def Clone(self):\n        return EventList(Event.Clone(self.events));\n\n    def toDictionary(self):\n        d=AObject.toDictionary(self);\n        d['events']=self.serializeEvents();\n        return d;\n\n    def serializeEvents(self):\n        re = [];\n        for e in self.events:\n            re.append(e.toDictionary());\n        return re;\n\n    def getActiveEvents(self):\n        active_events = [];\n        for e in self.events:\n            if(e.is_active):\n                active_events.append(e);\n        return active_events;\n\n    def initFromDictionary(self, d):\n        AObject.initFromDictionary(self, d);\n        events = d['events'];\n        for e in events:\n            newe = Event();\n            newe.initFromDictionary(e);\n            self.events.append(newe);\n\n    def unroll(self, assert_on_folds=None):\n        newlist = Event.GetUnrolledList(event_list=self.events, assert_on_folds=assert_on_folds);\n        self.events = newlist;\n\n    def getUnrolled(self, assert_on_folds=None):\n        return EventList(Event.GetUnrolledList(event_list=self.events, assert_on_folds=assert_on_folds));\n\n    def getFromIndices(self, inds):\n        return EventList(Event.NewFromIndices(event_list=self.events, inds=inds));\n\n    def getRolledToN(self, n_out, momentum = 0.1):\n        return EventList(Event.RollToN(self.events, n_out=n_out, momentum=momentum));\n\n\n    def toStartTimes(self):\n        return Event.ToStartTimes(self.events);\n\n    def _toGUIDicts(self):\n        return Event._ToGUIDicts(self.events);\n\n    @staticmethod\n    def _FromGUIDicts(gds, type=None):\n        events = Event._FromGUIDicts(gds, type=type);\n        return EventList(events);\n\n\n    @staticmethod\n    def FromJSON(json_path=None):\n        if (json_path is None):\n            json_path = fileui.GetFilePath();\n        elist = EventList();\n        elist.loadFromJSON(json_path=json_path);\n        return elist;\n\n    @staticmethod\n    def FromStartTimes(starts, type=None, event_class=None):\n        elist = EventList();\n        if(event_class is None):\n            event_class = Event;\n        for s in starts:\n            elist.events.append(event_class(start=s, type=type));\n        return elist;\n\n\n    def toWeights(self):\n        return Event.ToWeights(self.events);\n\n    def getDoubled(self):\n        return EventList(Event.Double(self.Clone().events));\n\n    def getHalved(self, offset=0):\n        return EventList(Event.Half(self.Clone().events, offset=offset));\n\n    def getThirded(self, offset=0):\n        return EventList(Event.Third(self.Clone().events, offset=offset));\n\n    @staticmethod\n    def FromSignalPeaks(**kwargs):\n        return EventList(Event.FromSignalPeaks(**kwargs));\n\n    @staticmethod\n    def PlotEventMatches(source_elist, target_elist, source_in=None, target_in=None):\n        return Event.PlotEventMatches(source_events=source_elist.events, target_events=target_elist.events, source_in=source_in, target_in=target_in);\n\n    def getWithFirstEventAt(self, first_event_time):\n        return EventList(Event.GetWithFirstEventAt(events=self.events, first_event_time=first_event_time));\n\n    def getWithStartTimesShifted(self, new_start_time):\n        return EventList(Event.GetWithStartTimesShifted(events = self.events, new_start_time=new_start_time));"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Image.py",
    "content": "#Image_Base\n#import numpy as np\n#import scipy as sp\nfrom PIL import Image as PIM\nfrom PIL import ImageDraw, ImageFont\n\nfrom .VisBeatImports import *\n# from PlotUtils import *\n\n\nVBMARK_SIZE = 0.135;\nVBMMARGIN = 0.02;\n\ndef imshow(imdata, new_figure = True):\n    if(ISNOTEBOOK):\n        #plt.imshow(self.data*0.0039215686274509);#divided by 255\n        if(new_figure):\n            plt.figure();\n        if(len(imdata.shape)<3):\n            plt.imshow(imdata, cmap='gray');\n        else:\n            plt.imshow(imdata);#divided by 255\n        plt.axis('off');\n\n\nclass Image(AObject):\n    \"\"\"Image\n    \"\"\"\n    IMAGE_TEMP_DIR = None;\n    USING_OPENCV=False;\n    _VBMRK = None;\n\n    def AOBJECT_TYPE(self):\n        return 'Image';\n\n    def __init__(self, data=None, path = None):\n        AObject.__init__(self, path=path);\n        self.data = data;\n        if(path and (not data)):\n            self.loadImageData();\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.data = None;\n\n    def setBlank(self, shape=None):\n        if(not shape):\n            self.data = np.zeros(self.data.shape);\n        else:\n            self.data = np.zeros([shape[0], shape[1], ]);\n\n    def loadImageData(self, path = None, force_reload=True):\n        if(path):\n            self.setPath(path);\n        if(self.a_info.get('file_path')):\n            if(force_reload or (not self.data)):\n                pim = PIM.open(fp=self.a_info['file_path']);\n                self.data = np.array(pim);\n\n    @property\n    def shape(self):\n        return self._getShape();\n\n    def _getShape(self):\n        return np.asarray(self.data.shape)[:];\n\n    @property\n    def dtype(self):\n        return self.data.dtype;\n\n    @property\n    def width(self):\n        return self._getWidth();\n\n    def _getWidth(self):\n        return self.shape[1];\n\n    @property\n    def height(self):\n        return self._getHeight();\n\n    def _getHeight(self):\n        return self.shape[0];\n\n    @property\n    def _is_float(self):\n        return (self.dtype.kind in 'f');\n\n    @property\n    def _is_int(self):\n        return (self.dtype.kind in 'iu');\n\n    @property\n    def _pixels_float(self):\n        if (self._is_float):\n            return self.data;\n        else:\n            return self.data.astype(np.float) * np.true_divide(1.0, 255.0);\n\n    @property\n    def _pixels_uint(self):\n        if (self._is_int):\n            return self.data;\n        else:\n            return (self.data * 255).astype(np.uint8);\n\n    @property\n    def n_channels(self):\n        return self._getNChannels();\n\n    def _getNChannels(self):\n        if(len(self.data.shape)<3):\n            return 1;\n        else:\n            return self.data.shape[2];\n\n    @staticmethod\n    def FromGrayScale(gray_data, color_map = None, format=None, **kwargs):\n        if(not color_map):\n            newim = Image(data=np.dstack((gray_data,gray_data,gray_data)));\n        else:\n            cmap=matplotlib.cm.get_cmap(name=color_map);\n            #norm = mpl.colors.Normalize(vmin=-20, vmax=10)\n            #cmapf = cm.ScalarMappable(norm=norm, cmap=cmap)\n            cmapf = matplotlib.cm.ScalarMappable(cmap=cmap);\n            if(format is None):\n                newim = Image(data=cmapf.to_rgba(gray_data)*255);\n            else:\n                assert(False), \"unrecognized format {}\".format(format);\n\n        newim.a_info['ColorType']='FromGrayScale';\n        return newim;\n\n    @staticmethod\n    def printTempDir():\n        print((Image.IMAGE_TEMP_DIR));\n\n    def scaleToValueRange(self, value_range=None):\n        is_int = self._is_int;\n        if(value_range is None):\n            value_range = [0.0,255.0];\n        data = self.data.ravel();\n        currentmin=np.min(data);\n        currentmax=np.max(data);\n        currentscale = currentmax-currentmin;\n        if(currentscale==0):\n            VBWARN(\"CANNOT SCALE CONSTANT IMAGE\")\n            return;\n        divscale = truediv(1.0,currentscale);\n        newrange=(value_range[1]-value_range[0]);\n        self.data = (self.data*divscale)*newrange;\n        newmin = (currentmin*divscale)*newrange;\n        self.data = self.data-newmin+value_range[0]\n        if(is_int and value_range[1]>254):\n            self.data = self.data.astype(np.int);\n\n\n    def nChannels(self):\n        if(len(self.data.shape)<3):\n            return 1;\n        else:\n            return self.data.shape[2];\n\n    def getClone(self):\n        rimg = Image(path=self.a_info.get('file_path'), data=self.data.copy());\n        return rimg;\n\n    def getGridPixel(self,x,y,repeatEdge=0):\n        xo = x;\n        yo = y;\n\n        blackedge = np.zeros(1);\n        if(len(self.data.shape)==3):\n            blackedge = np.zeros(self.data.shape[2])\n\n        if(y>=self.data.shape[0]):\n            if(repeatEdge==1):\n                yo = self.data.shape[0]-1\n            else:\n                return blackedge\n\n        if(y<0):\n            if(repeatEdge==1):\n                yo = 0\n            else:\n                return blackedge\n\n        if(x>=self.data.shape[1]):\n            if(repeatEdge==1):\n                xo=self.data.shape[1]-1\n            else:\n                return blackedge\n\n        if(x<0):\n            if(repeatEdge==1):\n                xo = 0\n            else:\n                return blackedge\n\n        return self.data[yo,xo]\n\n    def getPixel(self, x, y, repeatEdge=0):\n        if(isinstance(y,int) and isinstance(x,int)):\n            return self.getGridPixel(x,y)\n        else:\n            yf = int(np.floor(y))\n            yc = int(np.ceil(y))\n            xf = int(np.floor(x))\n            xc = int(np.ceil(x))\n\n            print('getting here?')\n            print(xf);\n            print(yf);\n\n            tl = self.getGridPixel(xf,yf,repeatEdge)\n            tr = self.getGridPixel(xc,yf,repeatEdge)\n            bl = self.getGridPixel(xf,yc,repeatEdge)\n            br = self.getGridPixel(xc,yc,repeatEdge)\n\n            yalpha = y-yf\n            xalpha = x-xf\n\n            topL = tr*xalpha+tl*(1.0-xalpha)\n            botL = br*xalpha+bl*(1.0-xalpha)\n\n            retv = botL*yalpha+topL*(1.0-yalpha)\n            return retv\n\n    def getShape(self):\n        return np.asarray(self.data.shape)[:];\n\n    def getScaled(self, shape=None, shape_xy=None):\n        shapeis = (shape is not None);\n        shapexyis = (shape_xy is not None);\n        assert((shapeis or shapexyis) and not (shapeis and shapexyis)), \"Must provide only one of shape or shape_xy for Image.getScaled\"\n        if(shapeis):\n            sz=[shape[0], shape[1], self.data.shape[2]];\n        else:\n            sz=[shape_xy[1],shape_xy[0],self.data.shape[2]];\n        imK = sp.misc.imresize(self.data, size=sz);\n        return Image(data=imK);\n\n    def getRotated(self, theta):\n        imR = sp.misc.imrotate(self.data, theta);\n        return Image(data=imR);\n\n\n    # def splatAtPixCoord(self, im, location=[0,0]):\n    #     self.data[location[0]:(location[0]+im.data.shape[0]), location[1]:(location[1]+im.data.shape[1]),:]=im.data;\n    def _splatAtPixCoord(self, im, location=[0,0], **kwargs):\n        is_int = self._is_int;\n        selftype = self.dtype;\n        region0 = [location[0], (location[0]+im.data.shape[0])];\n        region1 = [location[1], (location[1]+im.data.shape[1])];\n        if(im.n_channels<4):\n            self.data[region0[0]:region0[1], region1[0]:region1[1],:]=im.data;\n            return;\n        if(im.n_channels == 4):\n            alphamap = np.moveaxis(np.tile(im._pixels_float[:, :, 3], (3, 1, 1)), [0], [2]);\n\n            blenda = (im._pixels_float[:, :, :3]) * alphamap + self._pixels_float[region0[0]:region0[1], region1[0]:region1[1],:]*(1.0 - alphamap);\n            if(is_int):\n                blenda = (blenda*255).astype(selftype);\n            self.data[region0[0]:region0[1], region1[0]:region1[1], :] = blenda;\n\n\n\n    def reflectY(self):\n        self.data[:,:,:]=self.data[::-1,:,:];\n\n    def reflectX(self):\n        self.data[:,:,:]=self.data[:,::-1,:];\n\n    def PIL(self):\n        return PIM.fromarray(np.uint8(self.data));\n\n    def getRGBData(self):\n        return self.data[:,:,0:3];\n\n    def normalize(self, scale=1.0):\n        self.data = self.data/np.max(self.data.ravel());\n        self.data = self.data*scale;\n\n    def show(self, new_figure = True):\n        if(ISNOTEBOOK):\n            if(new_figure):\n                plt.figure();\n            if(self.nChannels()==1):\n                plt.imshow(self.PIL(), cmap='gray');\n            else:\n                plt.imshow(self.PIL());#divided by 255\n            plt.axis('off');\n        else:\n            self.PIL().show();\n\n    def writeToFile(self, out_path):\n        self.PIL().save(out_path);\n\n    def getEncodedBase64(self):\n        return base64.b64encode(self.data);\n\n    def getDataAsString(self):\n        return self.data.tostring();\n\n    @staticmethod\n    def FromBase64(encoded_data, shape):\n        d = base64.decodestring(encoded_data);\n        npar = np.frombuffer(d, dtype=np.float64);\n        rIm = Image(data=np.reshape(npar, shape));\n        return rIm;\n\n\n\n\n    @staticmethod\n    def FromDataString(data_string, shape, dtype=None):\n        if(dtype is None):\n            dtype=np.float64;\n        img_1d = np.fromstring(data_string, dtype=dtype);\n        reconstructed_img = img_1d.reshape((height, width, -1))\n\n\n###########################adapted from https://gist.github.com/turicas/1455973##########################\n    def _get_font_size(self, text, font_path, max_width=None, max_height=None):\n        if max_width is None and max_height is None:\n            raise ValueError('You need to pass max_width or max_height')\n        font_size = 1\n        text_size = self.get_text_size(font_path, font_size, text)\n        if (max_width is not None and text_size[0] > max_width) or (max_height is not None and text_size[1] > max_height):\n            raise ValueError(\"Text can't be filled in only (%dpx, %dpx)\" % text_size)\n        while True:\n            if (max_width is not None and text_size[0] >= max_width) or (max_height is not None and text_size[1] >= max_height):\n                return font_size - 1\n            font_size += 1\n            text_size = self.get_text_size(font_path, font_size, text)\n\n    def writeOutlinedText(self, xy, text,\n                   font_size=11,\n                   max_width=None,\n                   max_height=None,\n                   encoding='utf8', draw_context = None):\n        self.writeText(xy=[xy[0]+3, xy[1]+3], text=text, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=font_size,\n                       max_width=max_width,\n                       color=(0, 0, 0),\n                       max_height=max_height,\n                       encoding=encoding, draw_context=draw_context);\n        self.writeText(xy=xy, text=text, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=font_size,\n                       max_width=max_width,\n                       color=(255, 255, 255),\n                       max_height=max_height,\n                       encoding=encoding, draw_context=draw_context);\n\n\n    def writeText(self, xy, text, font_filename='RobotoCondensed-Regular.ttf',\n                   font_size=11,\n                   color=(0, 0, 0),\n                   max_width=None,\n                   max_height=None,\n                   encoding='utf8', draw_context = None):\n\n        x=xy[0];\n        y=xy[1];\n\n        font_paths = find_all_files_with_name_under_path(name=font_filename,\n                                                         path=os.path.dirname(os.path.abspath(__file__)));\n        font_path = font_paths[0];\n\n        if isinstance(text, str):\n            text = text.decode(encoding)\n        if font_size == 'fill' and (max_width is not None or max_height is not None):\n            font_size = self._get_font_size(text, font_path, max_width,\n                                           max_height)\n        text_size = self._get_text_size(font_path, font_size, text)\n\n\n        font = ImageFont.truetype(font=font_path, size=font_size);\n\n        # font = ImageFont.truetype(font_filename, font_size)\n        if x == 'center':\n            x = (self.data.shape[1] - text_size[0]) / 2\n        if y == 'center':\n            y = (self.data.shape[0] - text_size[1]) / 2\n\n        if(draw_context is None):\n            ipil = self.PIL();\n            draw = ImageDraw.Draw(ipil)\n            draw.text((x, y), text, font=font, fill=color)\n            datashape = self.data.shape;\n            self.data = np.array(ipil.getdata());\n            self.data.shape = datashape;\n        else:\n            draw_context.text((x, y), text, font=font, fill=color);\n        return text_size\n\n    def _get_text_size(self, font_path, font_size, text):\n        font = ImageFont.truetype(font_path, font_size)\n        return font.getsize(text)\n\n    @staticmethod\n    def _VBMark():\n        if(Image._VBMRK is None):\n            Image._VBMRK = Image(path=GetVBMarkPath());\n        return Image._VBMRK;\n\n    def _vbmark(self):\n        self._splatAtPixCoord(**self._vbmarker());\n\n    def _vbmarker(self):\n        vbm = Image._VBMark();\n        wmfrac = min(VBMARK_SIZE * self.width, VBMARK_SIZE * self.height);\n        scaleval = min(1.0, np.true_divide(wmfrac, vbm.width));\n        if (scaleval < 1.0):\n            vbms = vbm.getScaled(shape=[int(vbm.shape[0] * scaleval), int(vbm.shape[1] * scaleval), vbm.shape[2]]);\n        else:\n            vbms = vbm.clone();\n        margin = min(vbm.width, vbm.height, int(VBMMARGIN * self.width), int(VBMMARGIN * self.height));\n\n        return dict(im=vbms, location=[self.height - vbms.height - margin, self.width - vbms.width - margin]);\n\n    def writeTextBox(self, xy, text, box_width, font_filename='RobotoCondensed-Regular.ttf',\n                       font_size=11, color=(0, 0, 0), place='left',\n                       justify_last_line=False):\n\n        x = xy[0];\n        y = xy[1];\n\n        font_paths = find_all_files_with_name_under_path(name=font_filename,\n                                                         path=os.path.dirname(os.path.abspath(__file__)));\n        font_path = font_paths[0];\n\n        lines = []\n        line = []\n        words = text.split()\n        for word in words:\n            new_line = ' '.join(line + [word])\n            size = self._get_text_size(font_path, font_size, new_line)\n            text_height = size[1]\n            if size[0] <= box_width:\n                line.append(word)\n            else:\n                lines.append(line)\n                line = [word]\n        if line:\n            lines.append(line)\n        lines = [' '.join(line) for line in lines if line]\n        height = y\n        for index, line in enumerate(lines):\n            height += text_height\n            if place == 'left':\n                self.writeText((x, height), line,\n                                font_filename,\n                                font_size,\n                                color)\n            elif place == 'right':\n                total_size = self._get_text_size(font_path, font_size, line)\n                x_left = x + box_width - total_size[0]\n                self.writeText((x_left, height), line, font_filename,\n                                font_size, color)\n            elif place == 'center':\n                total_size = self._get_text_size(font_path, font_size, line)\n                x_left = int(x + ((box_width - total_size[0]) / 2))\n                self.writeText((x_left, height), line,\n                                font_filename,\n                                font_size, color)\n            elif place == 'justify':\n                words = line.split()\n                if (index == len(lines) - 1 and not justify_last_line) or len(words) == 1:\n                    self.writeText((x, height), line,\n                                    font_filename,\n                                    font_size,\n                                    color)\n                    continue\n                line_without_spaces = ''.join(words)\n                total_size = self._get_text_size(font_path, font_size,\n                                                line_without_spaces)\n                space_width = (box_width - total_size[0]) / (len(words) - 1.0)\n                start_x = x\n                for word in words[:-1]:\n                    self.writeText((start_x, height), word,\n                                    font_filename,\n                                    font_size, color)\n                    word_size = self._get_text_size(font_path, font_size,\n                                                   word)\n                    start_x += word_size[0] + space_width\n                last_word_size = self._get_text_size(font_path, font_size,\n                                                    words[-1])\n                last_word_x = x + box_width - last_word_size[0]\n                self.writeText((last_word_x, height), words[-1],\n                                font_filename,\n                                font_size, color)\n        return (box_width, height - y)\n#####################################################\n\nfrom . import Image_CV\nif(Image_CV.USING_OPENCV):\n    Image.USING_OPENCV = Image_CV.USING_OPENCV;\n    Image.RGB2Gray=Image_CV.RGB2Gray;\n    Image.GrayToRGB=Image_CV.Gray2RGB;\n    Image.cvGoodFeaturesToTrack=Image_CV.cvGoodFeaturesToTrack;\n    Image.withFlow=Image_CV.withFlow;\n    cvDenseFlowFarneback = Image_CV.cvDenseFlowFarneback;\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    # Image. = Image_CV.\n    ocv = Image_CV.ocv;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Image_CV.py",
    "content": "\n\n#CVFunctions\nfrom .VisBeatImports import *\nimport numpy as np\nimport scipy as sp\nfrom PIL import Image as PIM\n#from VBObject import *\nfrom . import Image as vbImage\nimport math\n\nDEFAULT_FLOW_HISTOGRAM_BINS = 8;\n\n\nUSING_OPENCV=True\ntry:\n    import cv2 as ocv\nexcept ImportError:\n    USING_OPENCV=False;\n    AWARN('OpenCV not installed; not importing Image_CV')\n\n\n#these are functions that use OpenCV that aren't class functions\nif(USING_OPENCV):\n    def flow2rgb(flow):\n        h, w = flow.shape[:2]\n        fx, fy = flow[:,:,0], flow[:,:,1]\n        ang = np.arctan2(fy, fx) + np.pi\n        v = np.sqrt(fx*fx+fy*fy)\n        hsv = np.zeros((h, w, 3), np.uint8)\n        hsv[...,0] = ang*(180/np.pi/2)\n        hsv[...,1] = 255\n        #v=np.minimum(v*4, 255);\n        v = np.log(v+1);\n        vmax = np.max(v[:]);\n        vf=v/vmax;\n        v=vf*255;\n        hsv[...,2] = v;#np.minimum(v*4, 255)\n        rgb = ocv.cvtColor(hsv, ocv.COLOR_HSV2BGR)\n        return rgb\n\n    def showFlowHSV(flow, new_figure = True):\n        if(ISNOTEBOOK):\n            #plt.imshow(self.data*0.0039215686274509);#divided by 255\n            if(new_figure):\n                plt.figure();\n            plt.imshow(PIM.fromarray(flow2rgb(flow)));\n            plt.axis('off');\n        else:\n            self.PIL().show();\n\n    def cornerHarris(im, blockSize=None, ksize=None, k=None):\n        if (blockSize is None):\n            blockSize = 2;\n        if (ksize is None):\n            ksize = 3;\n        if (k is None):\n            k = 0.04;\n        return ocv.cornerHarris(im, 2, 3, 0.04);\n\n    def cvDenseFlowFarneback(from_image, to_image, pyr_scale=None, levels=None, winsize=None, iterations=None, poly_n=None, poly_sigma=None, flags=None):\n        \"\"\"Can provide numpy arrays or Image objects as input. Returns the flow from->to.\"\"\"\n        # params for Farneback's method\n        from_im=from_image;\n        to_im=to_image;\n        from_is_ob = isinstance(from_image, vbImage.Image);\n        to_is_ob = isinstance(to_image, vbImage.Image)\n\n        if(from_is_ob):\n            if(from_image.nChannels()>1):\n                from_im=from_image.getClone();\n                from_im.RGB2Gray();\n            from_im=from_im.data;\n        if(to_is_ob):\n            if(to_image.nChannels()>1):\n                to_im=to_image.getClone();\n                to_im.RGB2Gray();\n            to_im=to_im.data;\n\n\n\n        inputs = dict( flow = None,\n                            pyr_scale = pyr_scale,\n                            levels = levels,\n                            winsize = winsize,\n                            iterations = iterations,\n                            poly_n = poly_n,\n                            poly_sigma = poly_sigma,\n                            flags=flags);\n\n        default_flow=None;\n        default_pyr_scale=0.5;\n        default_levels=int(math.log(float(min(to_im.shape)), 2))-4;\n        default_winsize = 15;\n        default_iterations=3;\n        default_poly_n=5;\n        default_poly_sigma=1.25;\n\n        use_params = dict(flow=default_flow,\n                          pyr_scale=default_pyr_scale,\n                          levels=default_levels,\n                          winsize=default_winsize,\n                          iterations=default_iterations,\n                          poly_n=default_poly_n,\n                          poly_sigma=default_poly_sigma,\n                          flags=0);\n\n        for key in inputs:\n            if(inputs[key] is not None):\n                use_params[key]=inputs[key];\n\n        return ocv.calcOpticalFlowFarneback(prev=from_im, next=to_im, **use_params);\n\n\n\n# These functions are to add to Image class\nif(USING_OPENCV):\n    def RGB2Gray(self):\n        if(self.nChannels()==1):\n            return;\n        else:\n            self.data = ocv.cvtColor(self.data, ocv.COLOR_RGB2GRAY);\n\n    def Gray2RGB(self):\n        if(self.nChannels()==1):\n            self.data = ocv.cvtColor(self.data, ocv.COLOR_GRAY2RGB)\n\n    def cvGoodFeaturesToTrack(self, maxCorners=None, qualityLevel=None, minDistance=None, corners=None, mask=None, blockSize=None, useHarrisDetector=None):\n        assert(self.data is not None), \"must provide image to find features\";\n\n        if(self.nChannels()==1):\n            gray_image=self.data.copy();\n        else:\n            gray_image=ocv.cvtColor(self.data, cv2.COLOR_RGB2GRAY);\n\n        argd={};\n        if(maxCorners is not None):\n            d['maxCorners']=maxCorners;\n        if(qualityLevel is not None):\n            d['qualityLevel']=qualityLevel;\n        if(minDistance is not None):\n            d['minDistance']=minDistance;\n        if(corners is not None):\n            d['corners']=corners;\n        if(mask is not None):\n            d['mask']=mask;\n        if(blockSize is not None):\n            d['blockSize']=blockSize;\n        if(useHarrisDetector is not None):\n            d['useHarrisDetector']=useHarrisDetector;\n        return ocv.goodFeaturesToTrack(gray_image, **argd);\n\n\n\n    def withFlow(self, flow, step=16):\n        clone = self.getClone();\n        if(clone.nChannels()<3):\n            clone.convertToRGB();\n        img = clone.data;\n        h, w = img.shape[:2]\n        y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)\n        # flow[y, x] is fx, fy\n        fx, fy = flow[y,x].T\n        # After vstack, each column: x, y, x+fx, y+fy\n        # After transpose: each row: x, y, x+fx, y+fy\n        # After reshape: each row: [[x, y], [x+fx, y+fy]]\n        lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)\n        lines = np.int32(lines + 0.5)\n        ocv.polylines(img, lines, 0, (0, 255, 0), thickness=3)\n        for (x1, y1), (x2, y2) in lines:\n            cv2.circle(img, (x1, y1), 1, (0, 255, 0), -1)\n        return clone\n\n    \n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/SourceLocationParser.py",
    "content": "\"\"\"\nThis code was a last minute hack. It works fine enough for parsing youtube urls, but I would use it for any kind of reference.\nBased loosely on video backends from django embed video.\n\"\"\"\n\nimport re\nimport requests\nimport os\nimport sys\nif sys.version_info.major == 3:\n    import urllib.parse as urlparse\nelse:\n    import urllib.parse\n\nclass SourceURL(object):\n    \"\"\"\n    Modified from django embed video\n    \"\"\"\n\n\n    allow_https = True\n    is_secure = False\n\n    @classmethod\n    def SourceLocationType(cls):\n        return cls.__name__;\n\n    def __init__(self, source_location):\n        self.source_location_type = self.SourceLocationType()\n        self._source_location = source_location\n\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        \"\"\"\n        unique string to identify file\n        :return:\n        \"\"\"\n        return self._getCode();\n\n    def _getCode(self):\n        raise NotImplementedError;\n\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        raise NotImplementedError;\n    # </editor-fold>\n\n\n    @property\n    def url(self):\n        \"\"\"\n        URL of video.\n        \"\"\"\n        return self.get_url()\n    def get_url(self):\n        raise NotImplementedError\n\n    @property\n    def protocol(self):\n        \"\"\"\n        Protocol used to generate URL.\n        \"\"\"\n        return 'https' if self.allow_https and self.is_secure else 'http'\n\n    @property\n    def thumbnail(self):\n        \"\"\"\n        URL of video thumbnail.\n        \"\"\"\n        return self.get_thumbnail_url()\n\n    @classmethod\n    def is_valid(cls, url):\n        return True if cls.re_detect.match(url) else False\n\nclass WebSourceException(Exception):\n    \"\"\" Parental class for all embed_media exceptions \"\"\"\n    pass\n\n\nclass VideoDoesntExistException(WebSourceException):\n    \"\"\" Exception thrown if video doesn't exist \"\"\"\n    pass\n\n\nclass UnknownBackendException(WebSourceException):\n    \"\"\" Exception thrown if video backend is not recognized. \"\"\"\n    pass\n\n\nclass UnknownIdException(VideoDoesntExistException):\n    \"\"\"\n    Exception thrown if backend is detected, but video ID cannot be parsed.\n    \"\"\"\n    pass\n\n\nclass YoutubeURL(SourceURL):\n    \"\"\"\n    for YouTube URLs.\n    \"\"\"\n\n    @classmethod\n    def SourceLocationType(cls):\n        return 'youtube';\n\n    # Compiled regex (:py:func:`re.compile`) to search code in URL.\n    # Example: ``re.compile(r'myvideo\\.com/\\?code=(?P<code>\\w+)')``\n    re_code = None\n\n    # Compilede regec (:py:func:`re.compile`) to detect, if input URL is valid for current backend.\n    # Example: ``re.compile(r'^http://myvideo\\.com/.*')``\n    re_detect = None\n\n    # Pattern in which the code is inserted.\n    # Example: ``http://myvideo.com?code=%s``\n    # :type: str\n    pattern_url = None\n\n    pattern_thumbnail_url = None\n\n    re_detect = re.compile(\n        r'^(http(s)?://)?(www\\.|m\\.)?youtu(\\.?)be(\\.com)?/.*', re.I\n    )\n\n    re_code = re.compile(\n        r'''youtu(\\.?)be(\\.com)?/  # match youtube's domains\n            (\\#/)? # for mobile urls\n            (embed/)?  # match the embed url syntax\n            (v/)?\n            (watch\\?v=)?  # match the youtube page url\n            (ytscreeningroom\\?v=)?\n            (feeds/api/videos/)?\n            (user\\S*[^\\w\\-\\s])?\n            (?P<code>[\\w\\-]{11})[a-z0-9;:@?&%=+/\\$_.-]*  # match and extract\n        ''',\n        re.I | re.X\n    )\n\n    pattern_url = '{protocol}://www.youtube.com/embed/{code}'\n    pattern_thumbnail_url = '{protocol}://img.youtube.com/vi/{code}/{resolution}'\n\n    resolutions = [\n        'maxresdefault.jpg',\n        'sddefault.jpg',\n        'hqdefault.jpg',\n        'mqdefault.jpg',\n    ]\n\n\n    def get_url(self):\n        \"\"\"\n        Returns URL folded from :py:data:`pattern_url` and parsed code.\n        \"\"\"\n        url = self.pattern_url.format(code=self.code, protocol=self.protocol)\n        url += '?' + self.query.urlencode() if self.query else ''\n        return url\n\n    def get_thumbnail_url(self):\n        \"\"\"\n        Returns thumbnail URL folded from :py:data:`pattern_thumbnail_url` and\n        parsed code.\n\n        :rtype: str\n        \"\"\"\n        return self.pattern_thumbnail_url.format(code=self.code,\n                                                 protocol=self.protocol)\n\n    def _getCode(self):\n\n        match = self.re_code.search(self._source_location)\n        if match:\n            return match.group('code')\n\n        parsed_url = urllib.parse.urlparse(self._source_location)\n        parsed_qs = urllib.parse.parse_qs(parsed_url.query)\n\n        if 'v' in parsed_qs:\n            code = parsed_qs['v'][0]\n        elif 'video_id' in parsed_qs:\n            code = parsed_qs['video_id'][0]\n        else:\n            raise UnknownIdException('Cannot get ID from `{0}`'.format(self._source_location))\n\n        return code\n\n    def get_thumbnail_url(self):\n        \"\"\"\n        Returns thumbnail URL folded from :py:data:`pattern_thumbnail_url` and\n        parsed code.\n\n        :rtype: str\n        \"\"\"\n        for resolution in self.resolutions:\n            temp_thumbnail_url = self.pattern_thumbnail_url.format(\n                code=self.code, protocol=self.protocol, resolution=resolution)\n            if int(requests.head(temp_thumbnail_url).status_code) < 400:\n                return temp_thumbnail_url\n        return None\n\n\n\nclass FilePathURL(SourceURL):\n    @classmethod\n    def SourceLocationType(cls):\n        return 'file_path';\n\n    def __init__(self, source_location):\n        self.source_location_type = self.SourceLocationType()\n        self._source_location = source_location;\n\n    @classmethod\n    def is_valid(cls, source_location):\n        return os.path.isfile(source_location);\n\n    def _getCode(self):\n        name_parts = os.path.splitext(os.path.basename(self._source_location));\n        return name_parts[0];\n\n\n\nSOURCE_LOCATION_TYPES = (\n    YoutubeURL,\n    FilePathURL,\n)\n\ndef ParseSourseLocation(url):\n    \"\"\"\n\n    :param url:\n    :return:\n    \"\"\"\n    for backend in SOURCE_LOCATION_TYPES:\n        if backend.is_valid(url):\n            return backend(url)\n\n    raise UnknownBackendException"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/TimeSignal.py",
    "content": "from .VBObject import *\nfrom .Event import *\nimport math\nfrom operator import truediv\nfrom .VisBeatImports import *\n\nclass TimeSignal(VBObject):\n    \"\"\"TimeSignal (class): A time signal, and a bunch of convenience functions to go with it.\n        Attributes:\n            sampling_rate: the sampling rate\n            visualizations dictionary of visualizations. (removed - too many dependencies)\n    \"\"\"\n\n    def VBBJECT_TYPE(self):\n        return 'TimeSignal';\n\n    def __init__(self, path=None, sampling_rate = None):\n        VBObject.__init__(self, path=path);\n        # self.initializeBlank();\n        # self.visualizations = AFuncDict(owner=self, name='visualizations');\n        # self.visualizations.functions.update(self.VIS_FUNCS);\n        if(sampling_rate):\n            self.sampling_rate=sampling_rate;\n\n    def initializeBlank(self):\n        VBObject.initializeBlank(self);\n        self.sampling_rate = None;\n\n\n    # <editor-fold desc=\"Property: 'frame_rate'\">\n    @property\n    def frame_rate(self):\n        return self._getFrameRate();\n    def _getFrameRate(self):\n        raise NotImplementedError;\n    # </editor-fold>\n\n\n    def getSampleAtTime(self, f):\n        prev_sample = self.getSampleAtIndex(math.floor(f));\n        next_sample = self.getSampleAtIndex(math.ceil(f));\n        sample_progress = f-np.floor(f);\n        return (next_sample*sample_progress)+(prev_sample*(1.0-sample_progress));\n\n    def getSampleAtIndex(self, i):\n        return self.getTimeForIndex();\n\n    def getDuration(self):\n        assert(False), \"getDuration must be implemented for subclass of TimeSignal\"\n\n    def getSampleDuration(self):\n        return 1.0/self.sampling_rate;\n\n    def getTimeForIndex(self, i):\n        return i*self.getSampleDuration();\n\n    # def toDictionary(self):\n    #     d = VBObject.toDictionary(self);\n    #     assert(False), \"haven't implemented toDictionary for {} yet\".format(self.VBOBJECT_TYPE())\n    #     #serialize class specific members\n    #     return d;\n\n    # def initFromDictionary(self, d):\n    #     VBObject.initFromDictionary(self, d);\n    #     assert(False), \"haven't implemented initFromDictionary for {} yet\".format(self.VBOBJECT_TYPE())\n    #     #do class specific inits with d;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/TimeSignal1D.py",
    "content": "from .TimeSignal import *\nimport math\n\nclass TimeSignal1D(TimeSignal):\n    \"\"\"TimeSignal1D (class): A time signal, and a bunch of convenience functions to go with it.\n        Attributes:\n            sampling_rate: the sampling rate\n            x:  the time signal\n    \"\"\"\n\n    def VBOJECT_TYPE(self):\n        return 'TimeSignal1D';\n\n    def __init__(self, path=None, sampling_rate = None, x=None):\n        TimeSignal.__init__(self, path=path, sampling_rate=sampling_rate);\n        if(x is not None):\n            self.x = x;\n        #self.initializeBlank(); # will be called by parent\n\n    def initializeBlank(self):\n        TimeSignal.initializeBlank(self);#YES KEEP call through weird loops\n        self.x = None;\n\n    def getSignal(self, resampled=False):\n        return self.x;\n\n    def getSignalSegment(self, time_range):\n        signal = self.getSignal();\n        seg_start = int(time_range[0]*self.sampling_rate);\n        seg_end = int(time_range[1]*self.sampling_rate);\n        return signal[seg_start:seg_end];\n\n    def getFullSignal(self):\n        return self.x;\n\n    def getSampleAtTime(self, f):\n        prev_sample = self.x[int(math.floor(f))];\n        next_sample = self.x[int(math.ceil(f))];\n        sample_progress = f-np.floor(f);\n        return (next_sample*sample_progress)+(prev_sample*(1.0-sample_progress));\n\n    def getSampleAtIndex(self, i):\n        return self.x[i];\n\n    def getDuration(self):\n        return truediv(len(self.getSignal()), self.sampling_rate);\n\n    def setValueRange(self, value_range=None):\n        if(value_range is None):\n            value_range = [0,1];\n        data = self.x[:];\n        currentscale = np.max(data)-np.min(data);\n        data = (data/currentscale)*(value_range[1]-value_range[0]);\n        data = data-np.min(data)+value_range[0]\n        self.x = data;\n\n    def setMaxAbsValue(self, max_abs_val=1.0):\n        data = self.x[:];\n        currentscale = np.max(np.fabs(data));\n        data = (data/currentscale)*max_abs_val;\n        self.x = data;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VBMIDI.py",
    "content": "# %load VisBeat/MidiParse.py\nimport mido\nimport numpy as np\nimport os\n# from TimeSignal1D import *\nfrom .Audio import *\nfrom .Event import *\n\nclass VBMIDITrack(object):\n    def __init__(self, track, ticks_per_beat):\n        self.mido_track = track;\n        self.name = track.name;\n        # print('Track {}: {}'.format(i, track.name));\n        self.tempo = next((msg.tempo for msg in track if msg.type == 'set_tempo'), None);\n        self.ticks_per_beat = ticks_per_beat;\n        # self._get_note_on_times();\n        self.note_on_times = None;\n\n\n    def getBPM(self):\n        return mido.tempo2bpm(self.tempo);\n\n    def getNoteOnTimes(self, include_negative=None):\n        if(self.note_on_times is None or (include_negative)):\n            self._get_note_on_times(include_negative = include_negative);\n        return self.note_on_times;\n\n\n    def _get_note_on_times(self, include_negative = None):\n        \"\"\"\n        Gets the starting time of each note.\n        \"\"\"\n        note_times = []\n        current_time = 0;\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                if msg.type == 'note_on' and msg.velocity > 0:\n                    if (include_negative or current_time>=0):\n                        note_times.append(current_time);\n\n\n        self.note_on_times = np.array(note_times);\n\n\n    def get_note_durations(self, track_num):\n        note_durations = []\n        currently_played_notes = {}\n        current_time = 0\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                if msg.type == 'note_on' and msg.velocity > 0 and msg.note not in currently_played_notes:\n                    currently_played_notes[msg.note] = current_time\n                    #if len(currently_played_notes) > 1:\n                    #    print \"Number of played notes have reached: \", len(currently_played_notes)\n                elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0):\n                    duration = current_time - currently_played_notes[msg.note]\n                    note_durations.append((currently_played_notes[msg.note], duration))\n                    currently_played_notes.pop(msg.note)\n        assert not bool(currently_played_notes), \"Finished looping through all messages. There should not be any notes playing at this point.\"\n        #print \"before sorting: \", note_durations\n        note_durations.sort(key=lambda x : x[0])\n        #print \"after sorting: \", note_durations\n        return np.array([ x[1] for x in note_durations ])\n\n    def get_mouth_events(self):\n        # note_times = []\n        current_time = 0;\n        number_on = 0;\n        events = [];\n        open_buffer = 0.1;\n        close_buffer = 0.1\n        last_type = 0;\n        events.append(Event(start=0, type='mouth_close', weight=1));\n        for msg in self.mido_track:\n            if not msg.is_meta:\n                delta_time = mido.tick2second(msg.time, self.ticks_per_beat, self.tempo)\n                current_time += delta_time\n                last_time = events[-1].start;\n                passed = current_time-last_time;\n\n                if msg.type == 'note_on' and msg.velocity > 0:\n                    if(last_type==0):\n                        if(passed>open_buffer):\n                            events.append(Event(start=current_time-open_buffer, type='mouth_closed', weight=0));\n                    events.append(Event(start=current_time, type='mouth_open', weight = truediv(msg.velocity,127)));\n                    number_on = number_on + 1;\n                    last_type=1;\n                if(msg.type == 'note_off' or (msg.type=='note_on' and msg.velocity == 0)):\n                    if (last_type == 1):\n                        if (passed > close_buffer):\n                            events.append(Event(start=current_time - close_buffer, type='mouth_opened', weight=0));\n                    events.append(Event(start=current_time, type='mouth_close', weight = truediv(msg.velocity,127)));\n                    number_on = number_on-1;\n                    last_type=0;\n                    # assert(number_on>-1);\n                    # if(number_on==0):\n        return events;\n        # self.note_on_times = np.array(note_times);\n\n    def getNoteOnTimesAsAudio(self, sampling_rate = None, note_sound=None, n_seconds=None):\n        assert(n_seconds is not None), \"must provide n seconds\"\n        if(sampling_rate is None):\n            sampling_rate = 16000;\n        if(note_sound is None):\n            note_sound = Audio.getPing();\n        s = Audio.Silence(n_seconds=n_seconds, sampling_rate=sampling_rate, name=self.name)\n        s = s.getWithSoundAdded(note_sound, self.getNoteOnTimes());\n        return s;\n\n\n\nclass VBMIDI(TimeSignal1D):\n    def __init__(self, path=None):\n        TimeSignal1D.__init__(self, path=path);\n        self.midi_file = mido.MidiFile(path)\n        self.tracks = [];\n        for i, track in enumerate(self.midi_file.tracks):\n            self.tracks.append(VBMIDITrack(track, self.midi_file.ticks_per_beat));\n\n    def getNoteOnTimes(self, include_negative=None):\n        return self.tracks[-1].getNoteOnTimes(include_negative=include_negative);\n\n    def getMouthEvents(self):\n        return self.tracks[-1].get_mouth_events();\n\n    def getNoteOnTimesAsAudio(self, sampling_rate=None, note_sound=None):\n        s = self.tracks[-1].getNoteOnTimesAsAudio(sampling_rate = sampling_rate, note_sound = note_sound, n_seconds = self.midi_file.length);\n        if (s.name is None):\n            s.name = self.getInfo('file_name')\n        return s;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VBObject.py",
    "content": "import os\nimport json\nfrom .VisBeatImports import *\nfrom .AFuncDict import *\nfrom .AObject import AObject\n\nclass VBObject(AObject):\n    \"\"\"VBObject (class): This is a paarent class used to implement common serialization and other functions. There ends\n        up being three different dictionaries of data.\n        a_info - for small labels and such. Part of AObject.\n        a_data - for data to be computed in experiments. I generally use this for things I don't want to automatically\n                save out to file.\n        features - these are features tied to the results of functions, and manager classes (e.g. VideoSource) will save\n                these to disk for future use.\n\n        FEATURE_FUNCS is a dictionary mapping the names of features to their corresponding functions.\n    \"\"\"\n    FEATURE_FUNCS={};\n\n    def __init__(self, path=None):\n        AObject.__init__(self, path=path);\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.a_info.update({'VBObjectType': self.VBOBJECT_TYPE()});\n        self.features = AFuncDict(owner=self, name='features');\n        self.features.functions.update(self.FEATURE_FUNCS);\n\n    def saveFeature(self, name, path):\n        \"\"\"Subclasses can implement version of this that will check members for features if those features arent found here.\"\"\"\n        return self.features.saveEntry(name=name, path=path);\n\n    def saveFeatures(self, path):\n        return self.features.save(path=path);\n\n    def loadFeature(self, name, path):\n        \"\"\"Subclasses can implement version of this that will check whether feature is registered before loading.\"\"\"\n        return self.features.loadEntry(name=name, path=path);\n\n    def loadFeatures(self, path):\n        return self.features.load(path=path);\n\n    def getFeature(self,name, force_recompute=False, **kwargs):\n        \"\"\"Understood to get the value of a feature. can automatically recompute if feature has registered function.\"\"\"\n        params = kwargs;\n        assert (not kwargs.get('params')), \"STILL TRYING TO USE PARAMS INSTEAD OF KWARGS. FIX THIS\";\n        return self.features.getValue(name=name, params=kwargs, force_recompute=force_recompute);\n\n    def getFeatureEntry(self, name, params=None, force_recompute=False):\n        return self.features.getEntry(name=name, params=params, force_recompute=force_recompute);\n\n    def getFeatureParams(self, name):\n        return self.features.getParams(name=name);\n\n    def setFeature(self, name, value, params=None):\n        rval = self.features.setEntry(name=name, d=dict(value=value, params=params));\n        self.features.setEntryModified(name=name, is_modified=True);\n        return rval;\n\n    def removeFeature(self, name, assert_if_absent=True, set_modified=True):\n        self.features.removeEntry(name=name, assert_if_absent=assert_if_absent, set_modified=set_modified);\n\n\n\n    def hasFeature(self, name):\n        \"\"\"Just checks to see if it's there.\"\"\"\n        return self.features.hasEntry(name=name);\n\n    def getFeatureFunction(self, feature_name):\n        return self.features.getFunction(name=feature_name);\n\n    def getFeaturesList(self):\n        return self.features.getKeyList();\n\n    def getFeatureFunctionsList(self):\n        return self.features.getFunctionList();\n\n    def clearFeatureFiles(self, features_to_clear=None, **kwargs):\n        if(self.clear_feature_files_func):\n            self.clear_feature_files_func(self, features_to_clear=features_to_clear, **kwargs);\n        else:\n            VBWARN(\"CLEAR FEATURE FILES FUNCTION HAS NOT BEEN PROVIDED FOR {} INSTANCE\".format(self.VBOBJECT_TYPE()));\n\n\n    ########### VIRTUAL FUNCTIONS #############\n\n    def AOBJECT_TYPE(self):\n        return 'VBObject';\n\n    def VBOBJECT_TYPE(self):\n        return self.AOBJECT_TYPE();\n\n\n    # ##Example of how these functions should be written ina  subclass, for 'AssetManager' class\n    # def VBOBJECT_TYPE(self):\n    #     return 'AssetManager';\n    #\n    # def toDictionary(self):\n    #     d = VBObject.toDictionary(self);\n    #     #serialize class specific members\n    #     return d;\n    #\n    # def initFromDictionary(self, d):\n    #     VBObject.initFromDictionary(self, d);\n    #     #do class specific inits with d;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Video.py",
    "content": "#VideoVersion#from VisBeatImports import *\nfrom .AObject import *\nfrom .TimeSignal import *\nfrom .Audio import *\nfrom .Warp import *\nfrom .Image import *\nimport moviepy.editor as mpy\nfrom moviepy.audio.AudioClip import AudioArrayClip as MPYAudioArrayClip\n\nimport sys\n\nimport math\nfrom operator import truediv\n\n\ndef MPYWriteVideoFile(mpyclip, filename, **kwargs):\n    temp_audio_filename = get_temp_file_path(final_file_path='TEMP_'+filename+'.m4a', temp_dir_path=Video.VIDEO_TEMP_DIR);\n    return mpyclip.write_videofile(filename=filename, temp_audiofile= temp_audio_filename, audio_codec='aac', **kwargs);\n\n\n\nclass Video(TimeSignal):\n    \"\"\"Video (class): A video, and a bunch of convenience functions to go with it.\n        Attributes:\n    \"\"\"\n\n    VIDEO_TEMP_DIR = './'\n    FEATURE_FUNCS = TimeSignal.FEATURE_FUNCS.copy();\n\n    def AOBJECT_TYPE(self):\n        return 'Video';\n\n    def __init__(self, path=None, name=None, num_frames_total=None):\n        TimeSignal.__init__(self, path=path);\n        if(name):\n            self.name = name;\n        if(path):\n            self.loadFile(num_frames_total=num_frames_total);\n\n    def initializeBlank(self):\n        TimeSignal.initializeBlank(self);#YES KEEP\n        self.name = None;\n        self.sampling_rate = None;\n        self.audio=None;\n        self.reader = None;\n        self.writer = None;\n        self.num_frames_total=None;\n        self.reshape=None;\n        self.meta_data = None;\n        self.sampling_rate = None;\n        self.source = None;\n\n        # _gui is not saved\n        self._gui = None;\n\n    def _getFrameRate(self):\n        return self.sampling_rate;\n\n    # _gui is from TimeSignal\n    # <editor-fold desc=\"Property: 'gui'\">\n    @property\n    def gui(self):\n        return self._getGui();\n\n    def _getGui(self):\n        return self._gui;\n\n    @gui.setter\n    def gui(self, value):\n        self._setGui(value);\n\n    def _setGui(self, value):\n        self._gui = value;\n    # </editor-fold>\n\n\n    def getVersionInfo(self):\n        \"\"\"This is the info to be saved in asset version dictionary\"\"\"\n        d={};\n        d['name']=self.name;\n        d['sampling_rate']=self.sampling_rate;\n        d['num_frames_total']=self.num_frames_total;\n        d['duration']=self.getDuration();\n        d['start_time']=self.getStartTime();\n        d['end_time']=self.getEndTime();\n        d['meta_data']=self.meta_data;\n        return d;\n\n    def getName(self):\n        if(self.name is None):\n            return self.getInfo('file_name');\n        else:\n            return self.name;\n\n    def getTempDir(self):\n        if(self.source is not None):\n            return self.source.getDir('temp');\n        else:\n            return Video.VIDEO_TEMP_DIR;\n\n    def getStringForHTMLStreamingBase64(self):\n        svideo = io.open(self.getPath(), 'r+b').read()\n        encoded = base64.b64encode(svideo)\n        return \"data:video/mp4;base64,{0}\".format(encoded.decode('ascii'));\n\n\n    def n_frames(self):\n        if(not self.num_frames_total):\n            self.num_frames_total = self.calcNumFramesTotal();\n        return self.num_frames_total;\n\n    def getDuration(self):\n        return truediv(self.n_frames(), self.sampling_rate);\n\n    def getStartTime(self):\n        return 0;\n\n    def getEndTime(self):\n        return self.getDuration();\n\n    def getMPYClip(self, get_audio=True):\n        return mpy.VideoFileClip(self.getPath(), audio=get_audio);\n\n    def getAudio(self):\n        return self.audio;\n\n    def loadFile(self, file_path=None, num_frames_total=None):\n        if (file_path):\n            self.setPath(file_path=file_path);\n        if ('file_path' in self.a_info):\n            self.reader = imageio.get_reader(self.a_info['file_path'], 'ffmpeg');\n            self.meta_data = self.reader.get_meta_data();\n            self.sampling_rate = self.meta_data['fps'];\n            if (num_frames_total is not None):\n                self.num_frames_total = num_frames_total;\n            else:\n                self.num_frames_total = self.calcNumFramesTotal();\n\n            try:\n                self.audio = Audio(self.a_info['file_path']);\n                self.audio.name =self.name;\n            #except RuntimeError:\n            except Exception:\n                print((\"Issue loading audio for {}\".format(self.a_info['file_path'].encode('utf-8'))));\n                self.audio = Audio(sampling_rate=16000);\n                self.audio.x = np.zeros(int(np.ceil(self.audio.sampling_rate*self.getDuration())));\n\n    def openVideoWriter(self, output_file_path, fps=None):\n        if('outputs' not in self.a_info):\n            self.a_info['outputs'] = [];\n        out_fps = fps;\n        if(not out_fps):\n            out_fps=self.sampling_rate;\n        make_sure_dir_exists(output_file_path);\n        self.writer = imageio.get_writer(output_file_path, 'ffmpeg', macro_block_size = None, fps = out_fps);\n        self.a_info['outputs'].append(output_file_path);\n\n    def closeVideoWriter(self):\n        self.writer.close();\n        self.writer = None;\n\n    def getFrameShape(self):\n        fs=self.getInfo('frame_shape');\n        if(fs is not None):\n            return fs;\n        else:\n            self.setInfo(label='frame_shape', value=self.reader.get_data(0).shape);\n            return self.getInfo('frame_shape');\n\n    def calcNumFramesTotal(self):\n        #assert(False)\n        print((\"Calculating frames for {}...\".format(self.name)))\n        valid_frames = 0\n        example_frame = self.reader.get_data(0);\n        self.setInfo(label='frame_shape',value=example_frame.shape);\n        \n        # https://stackoverflow.com/questions/54778001/how-to-to-tackle-overflowerror-cannot-convert-float-infinity-to-integer\n        #for i in range(1, self.reader.get_length()):\n        for i in range(1, self.reader.count_frames()):\n            try:\n                self.reader.get_data(i);\n            except imageio.core.format.CannotReadFrameError as e:\n                break\n            valid_frames += 1\n        print(\"Done.\")\n        return valid_frames\n\n    def readFrameBasic(self, i):\n        \"\"\"You should basically never call this\"\"\"\n        fi=i;\n        if(fi<0):\n            fi=0;\n        if(fi>(self.num_frames_total-1)):\n            fi=(self.num_frames_total-1);\n        return np.asarray(self.reader.get_data(int(fi)));\n\n    def getFrame(self, f):\n        return self.readFrameBasic(round(f));\n\n    def getFrameFromTime(self, t):\n        f = t*self.sampling_rate;\n        return self.getFrame(f=f);\n\n    def getFrameLinearInterp(self, f):\n        if(isinstance(f,int) or f.is_integer()):\n            return self.readFrameBasic(int(f));\n        prev_frame = self.readFrameBasic(math.floor(f));\n        next_frame = self.readFrameBasic(math.ceil(f));\n        frame_progress = f-np.floor(f);\n        rframe =  (next_frame*frame_progress)+(prev_frame*(1.0-frame_progress));\n        return rframe.astype(prev_frame.dtype);\n\n    def writeFrame(self, img):\n        if self.writer.closed:\n            print('ERROR: Vid writer object is closed.')\n        else:\n            self.writer.append_data(img.astype(np.uint8))\n\n    def play(self):\n        if(ISNOTEBOOK):\n            print(\"Playing video:\")\n            video = io.open(self.getPath(), 'r+b').read()\n            encoded = base64.b64encode(video)\n            vidhtml=HTML(data='''<video alt=\"test\" controls>\n                <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\" />\n             </video>'''.format(encoded.decode('ascii')));\n            IPython.display.display(vidhtml);\n            # return vidhtml;\n        else:\n             print(\"HOW TO PLAY VIDEO? NOT A NOTEBOOK.\")\n\n    def show(self):\n        self.play();\n\n    def write(self, output_path, output_sampling_rate=None):\n        assert output_path, \"MUST PROVIDE OUTPUT PATH FOR VIDEO\"\n\n        sampling_rate = output_sampling_rate;\n        if(not sampling_rate):\n            sampling_rate=self.sampling_rate;\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=self.getTempDir());\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate);\n\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,self.sampling_rate);\n        frame_start_times = np.linspace(0,self.getDuration(),num=nsamples,endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        for nf in range(len(frame_index_floats)):\n            self.writeFrame(self.getFrame(frame_index_floats[nf]));\n            fcounter+=1;\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n\n\n        self.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=self.audio, output_path=output_path);\n        os.remove(tempfilepath);\n        return rvid;\n\n    def VideoClip(self, start=None, end=None, name=None):\n        from . import VideoClip\n        if(start is None):\n            start = 0;\n        if(end is None):\n            end = self.getDuration();\n        clip = VideoClip.VideoClip(video=self, start=start, end=end);\n        if(name):\n            clip.name=name;\n        return clip;\n\n    def getImageFromFrame(self, i):\n        rimage = Image(data=self.getFrame(i));\n        rimage.setInfo(label='parent_video', value=self.getInfo('file_path'));\n        rimage.setInfo(label='frame_number',value=i);\n        return rimage;\n\n    def getImageFromTime(self, t):\n        rimage = Image(data=self.getFrameFromTime(t));\n        rimage.setInfo(label='parent_video', value=self.getInfo('file_path'));\n        rimage.setInfo(label='frame_time', value=t);\n        return rimage;\n\n\n    # def getFrameShape(self):\n    #     return self.getImageFromFrame(0).getShape();\n\n    def writeResolutionCopyFFMPEG(self, path, max_height=None):\n        if(max_height is None):\n            max_height=self.getFrameShape()[0];\n        mpc = self.getMPYClip();\n        clip_resized = mpc.resize(height=max_height); # make the height 360px ( According to moviePy documenation The width is then computed so that the width/height ratio is conserved.)\n        if((clip_resized.size[0]%2)>0):\n            clip_resized=clip_resized.crop(x1=0,width=clip_resized.size[0]-1);\n\n        # clip_resized.write_videofile(path);\n        MPYWriteVideoFile(clip_resized, path);\n\n        rvid = Video(path);\n        return rvid;\n\n    def writeFFMPEG(self, output_path):\n        mpc = self.getMPYClip();\n        # mpc.write_videofile(output_path, preset='fast', codec='mpeg4');\n        MPYWriteVideoFile(mpc, output_path, preset='fast', codec='mpeg4')\n        rvid = Video(output_path);\n        return rvid;\n\n    def writeResolutionCopy(self, path, max_height=None, reshape=None, input_sampling_rate_factor = None, output_sampling_rate=None):\n        print((self.getPath()))\n        if(input_sampling_rate_factor is not None):\n            original_sampling_rate = self.sampling_rate;\n            self.sampling_rate=input_sampling_rate_factor*self.sampling_rate;\n            original_audio_sampling_rate = self.audio.sampling_rate;\n            self.audio.sampling_rate=self.audio.sampling_rate*input_sampling_rate_factor;\n        output_path = path;\n        inshape = self.getFrameShape();\n        if(reshape==True):\n            imshape = [inshape[1],inshape[0],inshape[2]];\n        outshape = None;\n        if(max_height and (max_height<inshape[0])):\n            outshape = self.getFrameShape();\n            out_w_over_height = truediv(inshape[1],inshape[0]);\n            outshape[0]=(max_height);\n            outshape[1]=max_height*out_w_over_height;\n            if((math.floor(outshape[1])%2)==0):\n                outshape[1]=math.floor(outshape[1])\n            elif((math.ceil(outshape[1])%2)==0):\n                outshape[1]=math.ceil(outshape[1])\n            if((outshape[1]%2)!=0):\n                outshape[1]=outshape[1]-1;\n        sampling_rate = output_sampling_rate;\n        if(not sampling_rate):\n            sampling_rate=self.sampling_rate;\n\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=self.getTempDir());\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate);\n\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,self.sampling_rate);\n        frame_start_times = np.linspace(0,self.getDuration(),num=nsamples,endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        for nf in range(len(frame_index_floats)):\n            fim = self.getImageFromFrame(frame_index_floats[nf]);\n            if(reshape==True):\n                fim.data = np.reshape(fim.data, (fim.data.shape[1],fim.data.shape[0],fim.data.shape[2]));\n            if(outshape is not None):\n                fim = fim.getScaled(shape=outshape);\n            self.writeFrame(fim.data);\n\n            fcounter+=1;\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n        self.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=self.audio, output_path=output_path);\n        os.remove(tempfilepath);\n        if(input_sampling_rate_factor is not None):\n            #return original_sampling_rate\n            self.sampling_rate=original_sampling_rate;\n            self.audio.sampling_rate = original_audio_sampling_rate;\n        return rvid;\n\n    def writeWarped(self, output_path, warp, output_sampling_rate=None, output_audio=None, bitrate=None, vbmark = True, max_time = None, **kwargs):\n        sampling_rate = output_sampling_rate;\n        if (not sampling_rate):\n            sampling_rate = self.sampling_rate;\n\n        duration = self.getDuration();\n        old_frame_time = truediv(1.0, self.sampling_rate);\n\n        target_start = warp.getTargetStart();\n        target_end = warp.getTargetEnd();\n\n        target_duration = target_end - target_start;\n\n        if(max_time is not None and target_duration>max_time):\n            target_duration = max_time;\n            target_end = target_start+max_time;\n\n        print((\n            \"target start: {}\\ntarget end: {}\\ntarget duration: {}\".format(target_start, target_end, target_duration)));\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=False);\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(warp.warpTargetTime(st));\n        frame_index_floats = np.true_divide(np.array(unwarped_target_times), old_frame_time);\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=Video.VIDEO_TEMP_DIR);\n        self.openVideoWriter(output_file_path=tempfilepath, fps=output_sampling_rate, **kwargs);\n        start_timer = time.time();\n        last_timer = start_timer;\n        fcounter = 0;\n        if(vbmark):\n            vbmarker = self.getImageFromFrame(0)._vbmarker();\n\n        for nf in range(len(frame_index_floats)):\n            try:\n                nwfr = self.getFrame(frame_index_floats[nf]);\n                if(vbmark):\n                    nwfrm = Image(data=nwfr);\n                    nwfrm._splatAtPixCoord(**vbmarker);\n                    nwfr = nwfrm._pixels_uint;\n                self.writeFrame(nwfr);\n            except ValueError:\n                print((\"VALUE ERROR ON WRITEFRAME {}\".format(frame_index_floats[nf])));\n                self.writeFrame(self.getFrame(math.floor(frame_index_floats[nf])));\n            fcounter += 1;\n            if (not (fcounter % 50)):\n                if ((time.time() - last_timer) > 10):\n                    last_timer = time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0 * truediv(fcounter, len(frame_index_floats)),\n                                                                 last_timer - start_timer)));\n        self.closeVideoWriter();\n\n        silent_warped_vid = Video(tempfilepath);\n        if (not output_audio):\n            output_audio = self.getAudio();\n\n        cropped_output_audio = output_audio.AudioClip(start=target_start, end=target_end);\n\n        if ((self.getInfo('max_height') is None) and (bitrate is None)):\n            use_bitrate = \"20000k\";\n            print(('Using bitrate of {}'.format(use_bitrate)));\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path, bitrate=use_bitrate);\n        elif (bitrate is 'regular'):\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path);\n        else:\n            rvid = Video.CreateFromVideoAndAudioObjects(video=silent_warped_vid, audio=cropped_output_audio,\n                                                        output_path=output_path, bitrate=bitrate);\n\n        os.remove(tempfilepath);\n        rvid.setInfo(label='warp_used', value=warp);\n        return rvid;\n\n\n\n    def getVersionLabel(self):\n        return self.getInfo('version_label');\n\n    def getWarpsDir(self):\n        if(self.source is None):\n            return self.getTempDir();\n        version_label = self.getVersionLabel()\n        return self.source.getWarpsDir(version_label=version_label);\n\n    def getWithBeginningCroppedToAudio(self, target):\n        if(isinstance(target, Audio)):\n            B=target;\n        else:\n            B=target.getAudio();\n\n        A = self.getAudio();\n\n        AB = A.getShiftAmountTo(B);\n        BA = B.getShiftAmountTo(A);\n\n        if(AB<BA):\n            return self.VideoClip(name=self.name+'clipped_to_'+B.name);\n        else:\n            return self.VideoClip(start=BA, end=None, name=self.name+'clipped_to_'+B.name);\n\n    def getWarped(self, target,\n                  source_events=None, target_events=None,\n                  warp_type=None,\n                  max_time = None,\n                  source_time_range = None, target_time_range=None,\n                  output_sampling_rate=None, output_path=None,\n                  force_recompute=None, name_tag = None, vbmark = True, **kwargs):\n        \"\"\"\n\n        :param target_audio:\n        :param source_eventlist:\n        :param target_eventlist:\n        :param warp_type:\n        :param source_time_range:\n        :param target_time_range:\n        :param output_sampling_rate:\n        :param output_path:\n        :param force_recompute:\n        :param name_tag:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n\n        if(isinstance(target, Video)):\n            target_audio = target.audio;\n        else:\n            target_audio = target;\n\n        if(source_events is None):\n            source_events = self.audio.getBeatEvents();\n        if(target_events is None):\n            target_events = target_audio.getBeatEvents();\n\n        warp = Warp.FromEvents(source_events, target_events);\n\n        if(warp_type is None):\n            warp_type = 'quad';\n        warp.setWarpFunc(warp_type, **kwargs);\n\n        if(output_sampling_rate is None):\n            output_sampling_rate = self.sampling_rate;\n\n        if(hasattr(target, 'name')):\n            warpname=self.name+'_TO_'+target.name;\n        else:\n            warpname = self.name+ '_TO_TARGETAUDIO' + '_' + str(target.getInfo('name'));\n\n        if(name_tag is not None):\n            warpname = warpname+name_tag;\n\n        warpname = warpname+'.mp4';\n\n        if(output_path is None):\n            output_path = self.getWarpsDir()+os.sep+warpname;\n            make_sure_dir_exists(output_path);\n\n        if(not os.path.isfile(output_path) or force_recompute):\n            rvid = self.writeWarped(output_path=output_path, warp=warp, output_sampling_rate=output_sampling_rate, output_audio=target_audio, vbmark = vbmark, max_time = max_time);\n        else:\n            rvid = Video(path=output_path, name=warpname);\n        rvid.setFeature(name='warp_used', value=warp);\n        return rvid;\n\n\n    def getWithSoundsOnEvents(self, events, output_path=None, name_tag = None, mute_original=True,\n                              event_sound=None, force_recompute=None, **kwargs):\n        \"\"\"\n\n        :param events: Can be EventList, a list of events, or a list of numbers representing the times of the events.\n        :param output_path: if None, will try to get from Video.source\n        :param name_tag: what to label this output with in its name.\n        :param mute_original: whether to leave the original sound from the video in the output.\n        :param event_sound: Sound to play at each event.\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        assert(events is not None), 'must provide events or list of times to put sounds'\n\n        output_name = self.getName()+'_eventsounds';\n        if (name_tag):\n            output_name = output_name + '_' + name_tag;\n        if(output_path is None):\n            if(self.source is not None):\n                output_dir = self.source.getDirForVersion(version_label=self.getInfo('version_label'), version_group='sound_on_events');\n            else:\n                output_dir = self.getTempDir();\n            output_path=os.path.join(output_dir, output_name+'.mp4');\n            make_sure_dir_exists(output_dir);\n        if(not os.path.isfile(output_path) or force_recompute):\n            if(isinstance(events, EventList)):\n                etimes = events.toStartTimes();\n            elif(isinstance(events[0], Event)):\n                etimes = Event.ToStartTimes(events);\n            else:\n                etimes = events;\n            new_audio = self.getAudio().getWithSoundAdded(sound=event_sound, add_times=etimes,\n                                                          mute_original=mute_original, **kwargs);\n            audio_sig = new_audio.getSignal();\n            reshapex = audio_sig.reshape(len(audio_sig), 1);\n            reshapex = np.concatenate((reshapex, reshapex), axis=1);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=new_audio.sampling_rate);  # from a numeric arra\n            video_clip = self.getMPYClip();\n            video_clip = video_clip.set_audio(audio_clip);\n            # video_clip.write_videofile(output_path, codec='libx264', write_logfile=False);\n            MPYWriteVideoFile(video_clip, output_path, codec='libx264', write_logfile=False);\n\n        rvid = Video(path=output_path, name=output_name);\n        return rvid;\n\n\n    @staticmethod\n    def CreateFromVideoAndAudio(video_path=None, audio_path=None, video_object=None, audio_object=None,\n                                output_path=None, clip_to_video_length=True, return_vid=True, codec='libx264',\n                                bitrate=None, **kwargs):\n        assert (not (video_path and video_object)), \"provided both video path and object to CreateFromVideoAndAudio\"\n        assert (not (audio_path and audio_object)), \"provided both audio path and object to CreateFromVideoAndAudio\"\n        assert (output_path), \"Must provide output path for CreateFromVideoAndAudio\"\n\n        if (video_path):\n            video_object = Video(video_path);\n        if (audio_path):\n            audio_object = Audio(path=audio_path);\n\n        output_path = output_path.encode(sys.getfilesystemencoding()).strip();\n        make_sure_dir_exists(output_path);\n\n        # audio_sig = audio_object.getSignal();\n        audio_sig = audio_object.getStereo();\n        audio_sampling_rate = audio_object.getStereoSamplingRate();\n        is_stereo = True;\n\n        if (audio_sig is None):\n            is_stereo = False;\n            audio_sig = audio_object.getSignal();\n            audio_sampling_rate = audio_object.sampling_rate;\n            n_audio_samples_sig = len(audio_sig);\n        else:\n            n_audio_samples_sig = audio_sig.shape[1];\n\n        print((\"stereo is {}\".format(is_stereo)));\n\n        audio_duration = audio_object.getDuration();\n        video_duration = video_object.getDuration();\n\n        if (clip_to_video_length):\n            n_audio_samples_in_vid = int(math.ceil(video_duration * audio_sampling_rate));\n\n            if (n_audio_samples_in_vid < n_audio_samples_sig):\n                if (is_stereo):\n                    audio_sig = audio_sig[:, :int(n_audio_samples_in_vid)];\n                else:\n                    audio_sig = audio_sig[:int(n_audio_samples_in_vid)];\n            else:\n                if (n_audio_samples_in_vid > n_audio_samples_sig):\n                    nreps = math.ceil(truediv(n_audio_samples_in_vid, n_audio_samples_sig));\n                    if (is_stereo):\n                        audio_sig = np.concatenate(\n                            (audio_sig, np.zeros((2, n_audio_samples_in_vid - n_audio_samples_sig))),\n                            axis=1);\n                    else:\n                        audio_sig = np.tile(audio_sig, (int(nreps)));\n                        audio_sig = audio_sig[:int(n_audio_samples_in_vid)];\n\n        if (is_stereo):\n            # reshapex = np.reshape(audio_sig, (audio_sig.shape[1], audio_sig.shape[0]), order='F');\n            reshapex = np.transpose(audio_sig);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=audio_sampling_rate);  # from a numeric arra\n        else:\n            reshapex = audio_sig.reshape(len(audio_sig), 1);\n            reshapex = np.concatenate((reshapex, reshapex), axis=1);\n            audio_clip = MPYAudioArrayClip(reshapex, fps=audio_sampling_rate);  # from a numeric arra\n\n        video_clip = video_object.getMPYClip();\n        video_clip = video_clip.set_audio(audio_clip);\n        # video_clip.write_videofile(output_path,codec='libx264', write_logfile=False);\n        if (bitrate is None):\n            # video_clip.write_videofile(output_path, codec=codec, write_logfile=False);\n            MPYWriteVideoFile(video_clip, output_path, codec=codec, write_logfile=False);\n        else:\n            MPYWriteVideoFile(video_clip, output_path, codec=codec, write_logfile=False, bitrate=bitrate);\n            # video_clip.write_videofile(output_path, codec=codec, write_logfile=False, bitrate=bitrate);\n        if (return_vid):\n            return Video(output_path);\n        else:\n            return True;\n\n    @staticmethod\n    def CreateByStackingVideos(video_objects=None, video_paths=None, output_path=None, audio = None, concatdim = 0, force_recompute=True, **kwargs):\n        assert output_path, \"MUST PROVIDE OUTPUT PATH FOR VIDEO\"\n        if(not force_recompute):\n            if(os.path.isfile(output_path)):\n                return Video(path=output_path);\n        matchdim = (concatdim+1)%2;\n        vids=[];\n        if(video_objects is not None):\n            vids=video_objects;\n\n        if(video_paths is not None):\n            for vp in video_paths:\n                vids.append(Video(path=video_paths));\n\n        output_path=output_path.encode(sys.getfilesystemencoding()).strip();\n        make_sure_dir_exists(output_path);\n        basevid = vids[0];\n        if(audio is None):\n            audio = basevid.audio;\n        sampling_rate = basevid.sampling_rate;\n        tempfilepath = get_temp_file_path(final_file_path=output_path, temp_dir_path=vids[0].getTempDir());\n        basevid.openVideoWriter(output_file_path=tempfilepath, fps=sampling_rate);\n        duration = basevid.getDuration();\n        nsamples = sampling_rate*duration;\n        old_frame_time = truediv(1.0,sampling_rate);\n        #frame_start_times = np.linspace(self.getStartTime(),self.getEndTime(),num=nsamples,endpoint=False);\n        frame_start_times = np.linspace(0,duration,num=nsamples,endpoint=False);\n        #frame_index_floats = frame_start_times/old_frame_time;\n        frame_index_floats = frame_start_times*sampling_rate;\n        for nf in range(len(frame_index_floats)):\n            frameind = frame_index_floats[nf];\n            newframe = basevid.getFrame(frameind);\n            for vn in range(1,len(vids)):\n                addpart = vids[vn].getFrame(frameind);\n                partsize = np.asarray(addpart.shape)[:];\n                cumulsize = np.asarray(newframe.shape)[:];\n                if(partsize[matchdim]!=cumulsize[matchdim]):\n                    sz = partsize[:];\n                    sz[matchdim]=cumulsize[matchdim];\n                    addpart = sp.misc.imresize(addpart, size=sz);\n                newframe = np.concatenate((newframe, addpart), concatdim);\n            basevid.writeFrame(newframe);\n        basevid.closeVideoWriter();\n        rvid = Video.CreateFromVideoAndAudio(video_path=tempfilepath, audio_object=audio, output_path=output_path, **kwargs);\n        os.remove(tempfilepath);\n        return rvid;\n\n    @staticmethod\n    def CreateFromVideoAndAudioPaths(video_path, audio_path, output_path, return_vid = True, **kwargs):\n        return Video.CreateFromVideoAndAudio(video_path=video_path, audio_path=audio_path, output_path=output_path,return_vid=return_vid, **kwargs);\n\n    @staticmethod\n    def CreateFromVideoAndAudioObjects(video, audio, output_path, clip_to_video_length=True, return_vid = True, **kwargs):\n        return Video.CreateFromVideoAndAudio(video_object=video, audio_object=audio, output_path=output_path, clip_to_video_length=clip_to_video_length, return_vid = return_vid, **kwargs);\n\n\n    def _getDefaultPeakPickingTimeParams(self, **kwargs):\n        single_frame = np.true_divide(1.0, self._getFrameRate());\n        time_params = dict(\n            pre_max_time=2.0 * single_frame,\n            post_max_time=2.0 * single_frame,\n            pre_avg_time=5.0 * single_frame,\n            post_avg_time=5.0 * single_frame,\n            wait_time=2.0 * single_frame,\n            delta=0.015,\n        )\n        time_params.update(kwargs);\n        return time_params;\n\n#   ###################\n\n    # FEATURE\n    def getFrameIndexes(self, force_recompute=False):\n        feature_name = 'frame_indexes';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = dict();\n            duration = self.getDuration();\n            nsamples = self.sampling_rate * duration;\n            frame_start_times = np.linspace(0, duration, num=nsamples, endpoint=False);\n            value = frame_start_times * self.sampling_rate;\n            self.setFeature(name=feature_name, value=value, params=params);\n        return self.getFeature(feature_name);\n\n\n    def getFeaturesList(self):\n        return super(Video, self).getFeaturesList()+self.audio.getFeaturesList();\n\n    def getVideoFeaturesList(self):\n        return super(Video, self).getFeaturesList();\n\n    def getFeatureFunctionsList(self):\n        return super(Video, self).getFeatureFunctionsList()+self.audio.getFeatureFunctionsList();\n\n    def getFeatureSourceType(self, name):\n        \"\"\"returns whether video or audio feature, instead of parent version which returns true or false\"\"\"\n        vidhas = super(Video, self).hasFeature(name=name);\n        if(vidhas):\n            return 'video';\n        audiohas = self.audio.hasFeature(name=name);\n        if(audiohas):\n            return 'audio';\n        return None;\n\n    def getFeature(self, name, force_recompute=False, **kwargs):\n        \"\"\"Returns None if feature is not already computed, and feature name is not implemented and registered with FEATURE_FUNCS\"\"\"\n        params = kwargs;\n        assert(not kwargs.get('params')), \"STILL TRYING TO USE PARAMS INSTEAD OF KWARGS. FIX THIS\";\n        ftry = super(Video, self).getFeature(name=name, force_recompute=force_recompute, **kwargs);\n        if(ftry is not None):\n            return ftry;\n        else:\n            return self.audio.getFeature(name=name, force_recompute=force_recompute, **kwargs);\n\n\nVideo.FEATURE_FUNCS['frame_indexes']=Video.getFrameIndexes;\nfrom . import Video_CV;\nif(Video_CV.USING_OPENCV):\n    Video.FEATURE_FUNCS.update(Video_CV.FEATURE_FUNCS);\n    Video.USING_OPENCV = Video_CV.USING_OPENCV;\n\n    Video.localRhythmicSaliencyFunction = Video_CV.localRhythmicSaliencyFunction\n    Video.visualBeatFunction = Video_CV.visualBeatFunction\n\n    Video.cvGetGrayFrame = Video_CV.cvGetGrayFrame;\n    Video.getImageFromFrameGray = Video_CV.getImageFromFrameGray;\n    Video.plotVisualBeats = Video_CV.plotVisualBeats;\n    Video.loadFlowFeatures = Video_CV.loadFlowFeatures;\n\n    Video.getVisualBeats = Video_CV.getVisualBeats\n    Video.getLocalRhythmicSaliency = Video_CV.getLocalRhythmicSaliency;\n    Video.getDirectogram = Video_CV.getDirectogram;\n    Video.getDirectogramPowers = Video_CV.getDirectogramPowers;\n    Video.getVisibleImpactEnvelope = Video_CV.getVisibleImpactEnvelope;\n    Video.getVisibleImpactEnvelopePowers = Video_CV.getVisibleImpactEnvelopePowers;\n    Video.getVisibleImpacts = Video_CV.getVisibleImpacts;\n    Video.getVisualBeats = Video_CV.getVisualBeats;\n    # Video.getBackwardVisualBeats = Video_CV.getBackwardVisualBeats;\n    # Video.getForwardVisualBeats = Video_CV.getForwardVisualBeats;\n    Video.getBackwardVisibleImpactEnvelope = Video_CV.getBackwardVisibleImpactEnvelope;\n    Video.getBothWayVisibleImpactEnvelope = Video_CV.getBothWayVisibleImpactEnvelope;\n    Video.getForwardVisibleImpactEnvelope = Video_CV.getForwardVisibleImpactEnvelope;\n    Video.getDirectionalFlux = Video_CV.getDirectionalFlux;\n    Video.getVisualTempogram = Video_CV.getVisualTempogram;\n    Video.getCutEvents = Video_CV.getCutEvents;\n    Video.computeImpactEnvelope = Video_CV.computeImpactEnvelope;\n    Video.computeDirectogramPowers = Video_CV.computeDirectogramPowers;\n    Video.visualBeatsFromEvents = Video_CV.visualBeatsFromEvents;\n    Video.plotVisualBeats = Video_CV.plotVisualBeats;\n    Video.plotImpactEnvelope = Video_CV.plotImpactEnvelope;\n    Video.plotVisibleImpacts = Video_CV.plotVisibleImpacts;\n    Video.getVisualBeatSequences = Video_CV.getVisualBeatSequences;\n    Video.printVisualBeatSequences = Video_CV.printVisualBeatSequences;\n    Video.getVisualBeatTimes = Video_CV.getVisualBeatTimes;\n    Video.findAccidentalDanceSequences = Video_CV.findAccidentalDanceSequences;\n    Video.plotEvents = Video_CV.plotEvents;\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n    # Video. = Video_CV.\n\nelse:\n    AWARN(\"Was not able to add functions that use OpenCV! Check OpenCV instalation and try again?\");\n\nfrom .vbgui import BeatGUI\nif(BeatGUI.VIEWER_INSTALLED):\n    def getEvents(self, **kwargs):\n        time_params = self._getDefaultPeakPickingTimeParams();\n        time_params.update(kwargs)\n        vbeats = self.getFeature('visual_beats', force_recompute=True, **time_params);\n        return vbeats;\n    def getEventList(self, **kwargs):\n        events = self.getEvents(**kwargs);\n        return EventList(events=events);\n    def runBeatGUIOnAudio(self):\n        audio = self.getAudio();\n        self.gui.run(local_saliency=audio.getLocalRhythmicSaliency(), frame_rate = audio._getFrameRate(), eventlist = audio.getEventList());\n\n\n    def runGUI(self, local_saliency=None, frame_rate = None, eventlist = 'default', frame_offset=None):\n        self.gui.run(local_saliency=local_saliency, frame_rate=frame_rate, eventlist=eventlist, frame_offset=frame_offset);\n\n    Video._getGui = BeatGUI.media_GUI_func;\n    Video.runGUI = runGUI;\n    Video.getEvents = getEvents;\n    Video.getEventList = getEventList;\n    Video.runBeatGUIOnAudio = runBeatGUIOnAudio;\n\nelse:\n    AWARN(\"BeatGUI not installed\");"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VideoClip.py",
    "content": "\nfrom .Video import *\nfrom .AudioClip import *\n\nclass VideoClip(Video):\n    \"\"\"VideoClip (class): A segment of a video, and a bunch of convenience functions to go with it.\n        Attributes:\n            start: The name of the video\n            end: The framerate of the video\n    \"\"\"\n\n    def AOBJECT_TYPE(self):\n        return 'VideoClip';\n\n    def __init__(self, video=None, start=None, end=None, clip_to_frame=True, path=None):\n        \"\"\"If a video is provided, we don't want to reload the video from disk. If a path is provided, we have no choice.\n        \"\"\"\n        assert(not (video and path)), \"provided both video object and path to VideoClip constructor.\"\n        assert((start is not None) and (end is not None)), \"must provide start time and end time to AudioClip constructor\"\n        Video.__init__(self, path = path);\n        self.initializeBlank();\n        self.start = start;\n        self.end = end;\n\n        if(video):\n            self.setPath(video.getPath());\n            self.reader = video.reader;\n            #self.writer = None; #this only comes up if we write later\n            self.sampling_rate=video.sampling_rate;\n            self.num_frames_total=video.num_frames_total;\n            time_per_frame=truediv(1.0,self.sampling_rate);\n            if(clip_to_frame):\n                self.start=time_per_frame*math.floor(truediv(self.start,time_per_frame));\n                self.end=time_per_frame*math.floor(truediv(self.end,time_per_frame));\n            if(video.name):\n                self.name = video.name+\"_{}_{}\".format(start,end);\n            self.audio = video.audio.AudioClip(start=start, end=end);\n        else:\n            assert(False),\"must provide video to VideoClip init\"\n\n    def initializeBlank(self):\n        Video.initializeBlank(self);\n        self.start = None;\n        self.end = None;\n\n\n    # def readFrameBasic(self, i):\n    #     return Video.getFrame(self, float(i)+self.start);\n\n    def getFrameLinearInterp(self, f):\n        return Video.getFrameLinearInterp(self, float(f)+self.start*self.sampling_rate);\n\n    def getFrame(self, f):\n        return Video.getFrame(self, float(f)+self.start*self.sampling_rate);\n\n    def getDuration(self, round_to_frames=False):\n        if(not round_to_frames):\n            return self.end-self.start;\n        else:\n            return truediv(self.n_frames(), self.sampling_rate);\n\n    def n_frames(self):\n        #return self.getLastFrameIndex()-self.getFirstFrameIndex();\n        return math.ceil((self.end-self.start)*self.sampling_rate);\n\n    # def getFirstFrameIndex(self):\n    #     return math.floor(self.start*self.sampling_rate);\n    #\n    # def getLastFrameIndex(self):\n    #     #I think floor is still right here, because the times mark beginnings of frames\n    #     return math.floor(self.end*self.sampling_rate);\n\n    def getStartTime(self):\n        return self.start;\n\n    def getEndTime(self):\n        return self.end;\n\n    def getMPYClip(self, get_audio=True):\n        return mpy.VideoFileClip(self.getPath(), audio=get_audio).subclip(self.getStartTime(), self.getEndTime());\n\n    def play(self):\n        if(ISNOTEBOOK):\n            print(\"Playing video:\")\n            IPython.display.display(self.getMPYClip().ipython_display(fps=self.sampling_rate, maxduration=self.getDuration()+1));\n        else:\n             print(\"HOW TO PLAY VIDEO? NOT A NOTEBOOK.\")\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VideoSource.py",
    "content": "from .VisBeatImports import *\nfrom .Video import *\nfrom .AFileManager import AFileManager\n\ntry:\n    import youtube_dl\nexcept ImportError:\n    AWARN('You need to install youtube-dl to use parts of VideoSource class that pull from YouTube. Try running:\\npip install youtube-dl')\n\n\n\ndef safe_file_name(input_string):\n    return ''.join([i if ord(i) < 128 else '_' for i in input_string]);\n\nclass VideoSource(AFileManager):\n    \"\"\"Video (class): A video, and a bunch of convenience functions to go with it.\n        Attributes:\n            name: The name of the video\n            sampling_rate: The framerate of the video\n            audio: an Audio object, the audio for the video\n    \"\"\"\n\n    VIDEO_TEMP_DIR = './'\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n    def AOBJECT_TYPE(self):\n        return 'VideoSource';\n\n    def __init__(self, path, name=None, source_location=None, VideoClass = None, **kwargs):\n        \"\"\"\n        :param path: either the path to a json, or the path to a directory containing 'VideoSource.json',\n            or the path to a directory where said json should be created.\n        :param name: name for video\n        :param source_location: can be a path to a video file, or a youtube source from which to pull a video file\n        :param VideoClass: visbeat.Video by default, but can be changed if you are using a custom subclass.\n               Must be a subclass of visbeat.Video, and must be constructable with VideoClass(path)\n        \"\"\"\n        AFileManager.__init__(self, path=path);\n\n        if(VideoClass is not None):\n            self.VideoClass = VideoClass;\n\n        self.setSource(source_location=source_location, assert_valid=None, **kwargs);\n\n        # if (self.name is None):\n            # self.name = os.path.splitext(os.path.basename(path))[0]\n\n\n    @staticmethod\n    def NewVideoSource(destination, name, source_location=None, VideoClass = None, **kwargs):\n        vsdir = os.path.join(destination, name+os.sep);\n        make_sure_dir_exists(vsdir);\n        print((\"Video source at {}\".format(vsdir)));\n        return VideoSource(path=vsdir, name=name, source_location=source_location, **kwargs);\n\n    def initializeBlank(self):\n        AFileManager.initializeBlank(self);\n        self.source_location = None;\n        self.name = None;\n        self.video_file_name = None;\n        self.title_safe = None;\n        self.youtube_info_dict = None;\n        self.versions_info = {};\n\n        #\n        self.VideoClass = Video;\n\n    def toDictionary(self):\n        d = AFileManager.toDictionary(self);\n        d['source_location']=self.source_location;\n        if(self.name):\n            d['name']=self.name;\n        if(self.video_file_name):\n            d['video_file_name']=self.video_file_name;\n        if(self.title_safe):\n            d['title_safe']=self.title_safe;\n        if(self.youtube_info_dict):\n            d['youtube_info_dict']=self.youtube_info_dict;\n        if(self.versions_info):\n            d['versions_info']=self.versions_info;\n        return d;\n\n\n    def initFromDictionary(self, d):\n        AFileManager.initFromDictionary(self, d);\n        self.source_location = d['source_location'];\n        self.name = d.get('name');\n        self.video_file_name = d.get('video_file_name');\n        self.title_safe = d.get('title_safe');\n        self.youtube_info_dict = d.get('youtube_info_dict');\n        self.versions_info=d.get('versions_info');\n        if(self.versions_info is None):\n            self.versions_info = {};\n        #do class specific inits with d;\n\n\n    def initWithPath(self, path=None, clear_temp=None):\n        AFileManager.initWithPath(self, path=path, clear_temp=clear_temp);\n        self.setDir('versions', pathstring(self.getDirectoryPath() + os.sep + \"Versions\" + os.sep));\n        self.setDir('warps', pathstring(self.getDir('versions')+ os.sep + \"Warps\" + os.sep));\n        # self.setDir('midi', pathstring(self.getDirectoryPath() + os.sep + \"MIDI\" + os.sep));\n        # self.setDir('music', pathstring(self.getDirectoryPath() + os.sep + \"Music\" + os.sep));\n        self.setFeaturesDir();\n\n    def setFeaturesDir(self, features_dir=None):\n        if (features_dir is None):\n            self.setDir('features', pathstring(self.getDir('data') + os.sep + \"Features\" + os.sep))\n        else:\n            self.setDir('features', features_dir);\n\n\n\n    def getName(self):\n        \"\"\"\n        Gets name if set. If not set, returns file name without extension.\n        :return:\n        \"\"\"\n        if(self.name is not None):\n            return self.name;\n        elif(self.video_file_name is not None):\n            return os.path.splitext(self.video_file_name)[0];\n        else:\n            return None;\n\n\n###################\n\n\n    @staticmethod\n    def _versionLabelString(version_label=None):\n        if (version_label and version_label != 'Full'):\n            return str(version_label);\n        else:\n            return 'Full';\n\n    @staticmethod\n    def _versionGroupString(version_group=None):\n        if (version_group is None):\n            version_group = 'Original';\n        return version_group;\n\n    @staticmethod\n    def _getVersionLabelDirName(version_label=None):\n        if(isinstance(version_label, int)):\n            return (\"maxheight_{}\".format(version_label));\n        else:\n            return \"Full\";\n\n\n    def getVersionPath(self, version_label=None, version_group=None):\n        \"\"\"\n        Get path to version of video (path to video file). Return None if version has not been added.\n        :param version_label:\n        :return:\n        \"\"\"\n        return self.getVersionInfo(version_label=version_label, version_group=version_group, info_label='path');\n\n    def getDirForVersion(self, version_label=None, version_group=None):\n        vdir = self.getDir('versions') + os.sep + self._versionGroupString(version_group) + os.sep + self._getVersionLabelDirName(version_label)+os.sep;\n        return vdir;\n\n\n    def getVersionInfo(self, version_label, version_group=None, info_label=None):\n        \"\"\"\n        Get info about a version of the video\n        :param version_label:\n        :param info_label:\n        :return:\n        \"\"\"\n        assert(info_label is not None), \"should provide info_label to getVersionInfo()\"\n        d = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(d is not None):\n            return d.get(info_label);\n        else:\n            return None;\n\n    def getVersionDictionary(self, version_label=None, version_group=None):\n        if(version_group is None):\n            version_group='Original';\n        vis_d=self.versions_info.get(version_group);\n        if(vis_d is not None):\n            return vis_d.get(VideoSource._versionLabelString(version_label));\n        else:\n            return None;\n\n    def setVersionDictionary(self, version_label=None, version_group=None, d=None):\n        if(version_group is None):\n            version_group='Original';\n        vis_d=self.versions_info.get(version_group);\n        if(vis_d is None):\n            self.versions_info[version_group]={};\n            vis_d=self.versions_info.get(version_group);\n        vis_d[VideoSource._versionLabelString(version_label)]=d;\n        return;\n\n    def setVersionInfo(self, version_label=None, version_group=None, video_path=None, **kwargs):\n        version_dict = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(version_dict is None):\n            self.setVersionDictionary(version_label=version_label, version_group=version_group, d={});\n            version_dict = self.getVersionDictionary(version_label=version_label, version_group=version_group);\n        if(video_path is not None):\n            version_dict.update({'path':str(pathstring(video_path))});\n        if(kwargs is not None):\n            version_dict.update(kwargs);\n\n\n####################\n\n    def hardSave(self):\n        if (os.path.isfile(self.getJSONPath())):\n            os.rename(self.getJSONPath(), self.getDir('backup') + os.sep + self.AOBJECT_TYPE() + \".json\");\n        self.writeToJSON(self.getJSONPath());\n\n    def save(self):\n        if (self.getInfo('block_writing_to_json')):\n            return;\n        self.hardSave();\n\n####################\n\n\n    # def removeAllVersionFiles(self, asset_manager=None):\n    #     AWARN(\"This should wipe the directory, ya?\")\n    #     # AWARN(\"Remove all version files does not remove features and vis images! This still needs to be implemented!\")\n    #     # for vtype in self.versions_info:\n    #     #     for v in self.versions_info.get(vtype):\n    #     #         # print(self.versions_info.get(vtype).get(v));\n    #     #         vpath = self.versions_info.get(vtype).get(v).get('path');\n    #     #         assert(vpath), \"version {} did not have path\".format(vtype)\n    #     #         print(vpath)\n    #     #         if(os.path.isfile(vpath)):\n    #     #             print(\"REMOVING {}\".format(vpath))\n    #     #             os.remove(vpath);\n    #     #         if(asset_manager is not None and vtype=='Original'):\n    #     #             if(v=='Full'):\n    #     #                 rs=None;\n    #     #             else:\n    #     #                 rs = int(v);\n    #     #             asset_manager.removeFeaturesForLinkRes(link=self, max_height=rs);\n    #     # return True;\n\n    # def removeFeaturesForRes(self, max_height=None):\n    #     v = self.getVersionVideo(name=link.name, max_height = max_height);\n    #     v.clearFeatureFiles(features_to_clear=['all', 'each']);\n    #\n    #\n    # def removeFeatureFilesForVideo(self, video, features_to_remove=None):\n    #     if(features_to_remove is None):\n    #         return;\n    #     if(not isinstance(features_to_remove, list)):\n    #         features_to_remove=[features_to_remove];\n    #     for f in features_to_remove:\n    #         self.removeFeatureFileForVideo(video=video, feature_name=f);\n    #\n    #\n    # def removeFeatureFileForVideo(self, video, feature_name):\n    #     AWARN(\"still need to implement removeFeatureFileForVideo. Should just empty corresponding directory. Also implement 'each' that removes all.\")\n    #     # if(feature_name=='each'):\n    #     #     return self.removeFeatureFilesForVideo(video=video, features_to_remove=video.getFeatureFunctionsList());\n    #     # max_height = video.getInfo(label='max_height');\n    #     # link = self.hasLinkWithName(name=video.name);\n    #     # source_type=video.getFeatureSohahurceType(feature_name);\n    #     # ipath = self.getFeaturePathForLink(feature_name=feature_name, link=link, max_height=max_height, source_type=source_type);\n    #     # if(os.path.isfile(ipath)):\n    #     #     print(\"REMOVING {}\".format(ipath));\n    #     #     os.remove(ipath);\n    #\n    # def removeFeatureFiles(self, video, feature_name):\n    #     if(feature_name=='each'):\n    #         AWARN(\"IMPLEMENT DELETE FEATURE DIR AND CREATE CLEAN\");\n    #     version_label = video.getInfo(label='version_label');\n    #     AWARN(\"IMPLEMENT DELETE {} FOR VERSION_LABEL {}\".format(feature_name, version_label));\n    #     # ipath = self.getFeaturePathForLink(feature_name=feature_name, link=link, max_height=max_height, source_type=source_type);\n    #     # if(os.path.isfile(ipath)):\n    #     #     print(\"REMOVING {}\".format(ipath));\n    #     #     os.remove(ipath);\n    #\n    # def removeVersion(self, version_label=None, remove_files=True):\n    #     AWARN(\"Remove Resolution does not remove features! This still needs to be implemented!\")\n    #     for vtype in self.versions_info:\n    #         v = self.versions_info.get(vtype).get(VideoSource._versionLabelString(version_label));\n    #         if(v is not None):\n    #             vpath = v.get('path');\n    #             if(os.path.isfile(vpath)):\n    #                 print(\"REMOVING {}\".format(vpath))\n    #                 os.remove(vpath);\n    #             self.versions_info.get(vtype).pop(VideoSource._versionLabelString(version_label), None);\n    #     return True;\n    #\n    # def copyResolutionTo(self, version_label=None, output_dir=None):\n    #     assert(output_dir)\n    #     for vtype in self.versions_info:\n    #         v = self.versions_info.get(vtype).get(VideoSource._versionLabelString(version_label));\n    #         if(v is not None):\n    #             vpath = v.get('path');\n    #             if(os.path.isfile(vpath)):\n    #                 opath = os.path.join(output_dir,(vtype+'_'+VideoSource._versionLabelString(version_label)+self.video_file_name));\n    #                 print(\"COPYING {} to {}\".format(vpath,opath));\n    #                 shutil.copy2(vpath, opath);\n    #     return True;\n    #\n    # def copyAssetsTo(self, output_dir=None, asset_manager=None):\n    #     for vtype in self.versions_info:\n    #         output_type_dir=pathstring(output_dir+os.sep+vtype+os.sep);\n    #         make_sure_dir_exists(output_type_dir);\n    #         for v in self.versions_info.get(vtype):\n    #             output_a_dir = pathstring(output_type_dir+os.sep+v+os.sep);\n    #             make_sure_dir_exists(output_a_dir);\n    #             # print(self.versions_info.get(vtype).get(v));\n    #             vpath = self.versions_info.get(vtype).get(v).get('path');\n    #             if(vpath and os.path.isfile(vpath)):\n    #                 print(\"copying {} to {}\".format(vpath, output_a_dir));\n    #                 shutil.copy2(vpath, output_a_dir);\n    #                 if(asset_manager is not None and vtype=='Original'):\n    #                     if(v=='Full'):\n    #                         rs=None;\n    #                     else:\n    #                         rs = int(v);\n    #                     asset_manager.saveFeaturesForVersion(version_label=rs, output_dir = output_a_dir);\n\n    def getWarpsDir(self, version_label=None):\n        warpdir = self.getDir('warps');\n        resdir = self._getVersionLabelDirName(version_label=version_label);\n        rdir = pathstring(warpdir + os.sep + resdir + os.sep);\n        make_sure_path_exists(rdir);\n        return rdir;\n\n    # ############################# FROM ASSETMANAGER #######################\n\n    def getVersion(self, max_height=None, get_if_missing=True, load_features=True, **kwargs):\n        \"\"\"\n        Gets a version of the video with maximum height max_height. This function contains logic to decide whether/when\n            to pull the video. Use pullVersion to force pulling that overwrite's existing assets.\n        :param max_height:\n        :param get_if_missing:\n        :return:\n        \"\"\"\n        vpath = self.getVersionPath(version_label=max_height);\n        if(vpath and os.path.isfile(vpath)):\n            num_frames_total = self.getVersionInfo(version_label=max_height, info_label='num_frames_total');\n            if(num_frames_total):\n                v = self.RegisteredVideo(path=vpath, version_label = max_height, num_frames_total=num_frames_total, load_features=True);\n            else:\n                v = self.RegisteredVideo(path=vpath, version_label = max_height, load_features=True);\n                self.setVersionInfo(version_label=max_height, num_frames_total=v.num_frames_total);\n                self.save();\n            return v;\n        else:\n\n            if(get_if_missing):\n                vpath = self.pullVersion(max_height=max_height, **kwargs);\n                if(vpath):\n                    num_frames_total = self.getVersionInfo(version_label=max_height, info_label='num_frames_total');\n                    if(num_frames_total):\n                        v = self.RegisteredVideo(path=vpath, version_label = max_height, num_frames_total=num_frames_total, load_features=True);\n                    else:\n                        v = self.RegisteredVideo(path=vpath, version_label=max_height, load_features=True);\n                        self.setVersionInfo(version_label=max_height, num_frames_total=v.num_frames_total);\n                        self.save();\n                else:\n                    AWARN(\"COULDNT GET VIDEO FROM {}\".format(self.source_location));\n            else:\n                AWARN(\"COULDNT FIND VIDEO LOCALLY\");\n                return;\n        return v;\n\n    def saveFeaturesForVideo(self, video, features_to_save=None, output_dir=None, overwrite=True):\n        if(features_to_save is None):\n            return;\n        if(not isinstance(features_to_save, list)):\n            features_to_save=[features_to_save];\n        for f in features_to_save:\n            self.saveFeatureForVideo(video=video, feature_name=f, output_dir=output_dir, overwrite=overwrite);\n\n    def saveFeatureForVideo(self, video, feature_name, output_dir=None, overwrite=True):\n        if(feature_name=='each'):\n            return self.saveFeaturesForVideo(video=video, features_to_save=video.getFeaturesList(), output_dir=output_dir, overwrite=overwrite);\n\n        version_label = video.getInfo(label='version_label');\n        source_type = video.getFeatureSourceType(feature_name);\n        opath = self.getFeaturePath(feature_name=feature_name, version_label=version_label, source_type=source_type, output_dir=output_dir);\n        make_sure_dir_exists(opath);\n        if(not os.path.isfile(opath) or overwrite):\n            if(feature_name=='all'):\n                video.saveFeatures(path=opath);\n                return;\n            else:\n                vfeature = video.getFeature(name=feature_name, force_recompute=False);\n                if(vfeature is not None):\n                    video.saveFeature(name=feature_name, path=opath);\n\n    def loadFeaturesForVideo(self, video, features_to_load=None):\n        if(features_to_load is None):\n            return;\n        if(not isinstance(features_to_load, list)):\n            features_to_load=[features_to_load];\n        for f in features_to_load:\n            self.loadFeatureForVideo(video=video, feature_name=f);\n\n    def loadFeatureForVideo(self, video, feature_name):\n        if(feature_name=='each'):\n            return self.loadFeaturesForVideo(video=video, features_to_load=video.getFeatureFunctionsList());\n        version_label = video.getInfo(label='version_label');\n        source_type=video.getFeatureSourceType(feature_name);\n        ipath = self.getFeaturePath(feature_name=feature_name, version_label=version_label, source_type=source_type);\n        if(os.path.isfile(ipath)):\n            if(feature_name=='all'):\n                video.loadFeatures(path=ipath);\n            else:\n                video.loadFeature(name=feature_name, path=ipath);\n\n    def getFeaturePath(self, feature_name=None, source_type=None, version_label=None, output_dir=None):\n        assert(feature_name is not None), 'must provide name of feature VideoSource.getFeaturePath'\n        feature_dir = self.getFeatureDir(feature_name=feature_name, source_type = source_type);\n        fileext = '.pkl';\n        if(output_dir is None):\n            version = self._getVersionLabelDirName(version_label=version_label)+os.sep;\n            output_dir = pathstring(feature_dir);\n        outname = self.getName();\n        if(outname is None):\n            outname = 'version';\n        outname = outname+'_'+self._getVersionLabelDirName(version_label=version_label)+fileext;\n        opath = os.path.join(output_dir, outname);\n        return opath;\n\n    def getFeatureDir(self, feature_name=None, source_type=None):\n        if(source_type is None):\n            source_type='video'; # could be 'audio'\n        # AWARN(\"getDir('features')= {}\\nsource_type= {}\\nfeature_name= {}\".format(self.getDir('features'), source_type, feature_name))\n        ftypedir = pathstring(self.getDir('features') + os.sep + source_type + os.sep + feature_name + os.sep);\n        return ftypedir;\n\n    def saveFeaturesForVersion(self, version_label=None, output_dir=None):\n        assert(output_dir), 'must provide output dir';\n        v = self.getVersion(max_height=version_label);\n        v.save(features_to_save='all', output_dir=output_dir);\n\n\n    def RegisteredVideo(self, path=None, version_label=None, version_group = None, num_frames_total=None, load_features = True):\n        v = self.VideoClass(path=path, name=self.getName()+'_'+self._versionLabelString(version_label=version_label), num_frames_total=num_frames_total);\n        # v = Video(path=path, name=self.getName()+'_'+self._versionLabelString(version_label=version_label), num_frames_total=num_frames_total);\n        self.RegisterVideo(video=v, version_label=version_label, load_features=load_features);\n        return v;\n\n    def RegisterVideo(self, video, version_label = None, version_group = None, load_features=True):\n        def videosave(vidob, features_to_save='all', output_dir=None, overwrite=True):\n            self.saveFeaturesForVideo(video=vidob, features_to_save=features_to_save, output_dir=output_dir, overwrite=overwrite);\n            #self.save\n        def videoload(vidob, features_to_load='all', input_dir=None):\n            self.loadFeaturesForVideo(video=vidob, features_to_load=features_to_load);\n        def videoclear(vidob, features_to_clear='all'):\n            self.removeFeatureFilesForVideo(video=vidob, features_to_remove=features_to_clear);\n\n        video.setInfo(label='version_label', value=version_label);\n        video.setInfo(label='version_group', value=version_group);\n        video.setInfo(label='video_file_name', value=os.path.split(video.getPath())[1]);\n        # if(version_group is None):\n        video.save_func = videosave;\n        video.load_func = videoload;\n        video.clear_feature_files_func = videoclear;\n        video.source=self;\n\n        if(load_features is True and hasattr(video, \"loadFlowFeatures\")):\n            video.loadFlowFeatures();\n        elif(load_features is not None and (isinstance(load_features, list) or isinstance(load_features, str))):\n            video.load(features_to_load = load_features);\n\n        # return video;\n\n    def addVersion(self, path, version_label=None, version_group=None):\n        v = self.RegisteredVideo(path=path, version_label=version_label);\n        video_dict=v.getVersionInfo();\n        video_dict.update(dict(version_group=version_group));\n        self.setVersionInfo(video_path = path, version_label=version_label, **video_dict);\n        self.save();\n\n    def addVersionToVideo(self, video, new_video, version_label=None, version_group=None):\n        version_label = video.getInfo(label='version_label');\n        video_dict = new_video.getVersionInfo();\n        if ((version_group is not None) or (video_dict.get('version_group') is None)):\n            video_dict.update(dict(version_group=version_group));\n        self.setVersionInfo(video_path=new_video.getPath(), version_label=version_label, **video_dict);\n        self.save();\n\n\n    def setSource(self, source_location=None, assert_valid=True, **kwargs):\n        \"\"\"\n        Sets the source of this VideoSource. If file, copies the file to VideoSource directory as \"Original\" version,\n            unless copy argument is set to false.\n        :param source_location: either path to file, or youtube url\n        :param kwargs: see setSourceYoutube or setSourceFile for options\n        :return:\n        \"\"\"\n\n        if(source_location):\n            if(os.path.isfile(source_location)):\n                self.setSourceFile(path = source_location, **kwargs);\n            else:\n                self.setSourceYoutube(url=source_location, **kwargs);\n            return;\n        elif(kwargs.get('video_path')):\n            self.setSourceFile(**kwargs);\n            return;\n        elif(kwargs.get('url')):\n            self.setSourceYoutube(**kwargs);\n            return;\n        else:\n            if(assert_valid):\n                assert(False),'No valid source location provided to setSource.'\n\n\n\n\n    def setSourceYoutube(self, url=None, max_height=None, pull_fullres=True, **kwargs):\n        self.source_location=url;\n        self.setInfo(label='source_type', value='youtube');\n        if(pull_fullres):\n            self.pullYoutubeVideo(max_height=max_height, **kwargs);\n        self.save();\n\n    def setSourceFile(self, path=None, copy=True, **kwargs):\n        # assert(os.path.isfile(path)), 'Tried to set source but no file exists at {}'.format(path);\n        if(not os.path.isfile(path)):\n            return None;\n\n        self.video_file_name = os.path.basename(path);\n        if(not copy):\n            self.source_location = path;\n            self.setInfo(label='source_type', value='file_address');\n            return path;\n        # output_dir = self.getDir('versions') + os.sep + 'Original' + os.sep;\n        output_dir = self.getDirForVersion(version_label=None, version_group='Source');\n        make_sure_dir_exists(output_dir);\n        output_path = os.path.join(output_dir, self.video_file_name);\n        # max_height = kwargs.get('max_height');\n\n        # if(max_height is not None):\n        #     # print('max_height was {}'.format(max_height));\n        #     original = self.VideoClass(path=path);\n        #     original.writeResolutionCopyFFMPEG(path=output_path, max_height=kwargs.get('max_height'));\n        # else:\n        #     shutil.copy2(path, output_path);\n\n        shutil.copy2(path, output_path);\n\n        # self.addVersion(path=output_path, version_label='Original');\n        self.addVersion(path=output_path, version_label='Full');\n        self.setInfo(label='source_type', value='file');\n        self.source_location = output_path;\n        self.save();\n        return output_path;\n\n\n    def pullVersion(self, max_height=None, **kwargs):\n        # assert(self.source_location is not None), \"Could not pull version; source location is None.\"\n        if(self.source_location is None):\n            return None;\n        source_type = self.getInfo('source_type');\n        if(source_type=='youtube'):\n            return self.pullYoutubeVideo(max_height=max_height, **kwargs);\n        else:\n            return self.pullFileVideo(max_height=max_height, **kwargs)\n\n\n    def pullFileVideo(self, max_height=None, force_recompute=None):\n        original_path = self.source_location;\n        assert(os.path.isfile(original_path)), 'SOURCE FILE {} IS MISSING'.format(self.source_location);\n        original = self.VideoClass(path=original_path);\n        output_dir = self.getDirForVersion(version_label=max_height, version_group=None);\n        make_sure_dir_exists(output_dir);\n        output_path = os.path.join(output_dir, self.video_file_name);\n        if(max_height is None):\n            if(os.path.normpath(original_path) != os.path.normpath(output_path)):\n                shutil.copy2(original_path, output_path);\n        else:\n            original.writeResolutionCopyFFMPEG(path=output_path, max_height=max_height);\n        self.addVersion(path=output_path, version_label=max_height);\n        return self.getVersionPath(version_label=max_height);\n\n    def pullYoutubeVideo(self, max_height=None, write_subtitles=False, save_youtube_info=False,\n                  force_redownload=False):\n        \"\"\"\n        Downloads video from youtube with height<=max_height. Returns path to downloaded video.\n        :param max_height: maximum height of video to download\n        :param write_subtitles: whether to save the subtitles\n        :param save_youtube_info: whether to save the info json\n        :param force_redownload: whether to re-download if video exists\n        :return:\n        \"\"\"\n        assert (not self.getInfo('source_is_file')), \"tried to call pullYoutubeVideo on file source {}.\".format(self.getName());\n\n        old_vid_path = self.getVersionPath(version_label=max_height);\n\n        if ((not force_redownload) and old_vid_path and os.path.isfile(old_vid_path)):\n            AWARN(\"Old video version exists with path {}\\nSkipping download...\\n\".format(old_vid_path))\n            return old_vid_path;\n\n        # output_dir = self.getDir('versions') + os.sep + self._getVersionLabelDirName(version_label=max_height) + os.sep;\n        output_dir = self.getDirForVersion(version_label=max_height, version_group=None);\n        make_sure_path_exists(output_dir);\n\n        if ((not force_redownload) and self.video_file_name is not None):\n            path_guess = os.path.join(output_dir, self.video_file_name);\n            if (os.path.isfile(path_guess)):\n                AWARN(\"found existing file {}\\nSkipping download; set force_redownload=True to overwrite old version.\".format(path_guess));\n                self.addVersion(path=path_guess, version_label=max_height);\n                return path_guess;\n\n\n        ########Download From YouTube#########\n        vidpath_template = output_dir + '%(title)s-%(id)s' + '.%(ext)s';\n        ydl_opts = {\n            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',\n            'outtmpl': vidpath_template,\n        }\n        if (write_subtitles):\n            ydl_opts['writesubtitles'] = True;\n            ydl_opts['subtitlesformat'] = '[srt]';\n        if (max_height):\n            ydl_opts['format'] = 'bestvideo[height<={}][ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'.format(\n                max_height);\n        ydl_opts['writeinfojson'] = True;\n        info_dict = None;\n\n        AWARN(\"Downloading {} from {}...\".format(self.getName(), self.source_location));\n\n        with youtube_dl.YoutubeDL(ydl_opts) as ydl:\n            info_dict = ydl.extract_info(self.source_location, download=True)\n            # video_source = info_dict.get(\"source\", None)\n            # video_id = info_dict.get(\"id\", None)\n            # video_title = info_dict.get('title', None)\n        usedtitle = info_dict['title'].replace('\"', \"'\").replace('|', '_').replace(':', ' -').replace('/','_').replace('?', '');\n        usedfilename_withoutext = usedtitle + '-' + info_dict['id'];\n        usedfilename = usedfilename_withoutext + '.' + info_dict['ext'];\n        filepath = output_dir + os.sep + usedfilename;\n        filepathsafe = safe_file_name(filepath);\n        if (os.path.isfile(filepath)):\n            os.rename(filepath, filepathsafe);\n        else:\n            fpath = glob.glob(output_dir + os.sep + '*' + info_dict['id'] + '.mp4');\n            assert (len(fpath) == 1), \"Wrong number of files for {}\\nFound:\\n{}\".format(filepath, fpath);\n            os.rename(fpath[0], filepathsafe);\n            jpath = glob.glob(output_dir + os.sep + '*' + info_dict['id'] + '.info.json');\n            os.rename(jpath[0], safe_file_name(usedfilename_withoutext + '.info.json'));\n\n        print((\"Saved to {}\".format(filepathsafe)));\n\n        self.video_file_name = safe_file_name(usedfilename);\n        self.title_safe = safe_file_name(usedtitle);\n        if (save_youtube_info):\n            self.youtube_info_dict = info_dict;\n\n        # v = Video(path=filepathsafe);\n        # video_dict=v.toDictionary();\n        # self.setVersionInfo(video_path = filepathsafe, version_label=max_height, num_frames_total=v.num_frames_total, **video_dict);\n        # self.save();\n        self.addVersion(path=filepathsafe, version_label=max_height);\n        return self.getVersionPath(version_label=max_height);\n        # return youtube_link;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Video_CV.py",
    "content": "# from Video import *\nfrom .Image import *\nfrom .Event import *\nfrom .VisualBeat import *\nimport librosa\n\nFEATURE_FUNCS = {};\nVIS_FUNCS = {};\nVISVIDEO_FUNCS = {};\n\nFLOW_LOG_EPSILON=1.0;\nFLOW_UNIT_GAIN=10000.0;\n\nHISTOGRAM_FRAMES_PER_BEAT = 2;\nHISTOGRAM_DOWNSAMPLE_LEVELS = 3;\n\n\nVB_UPSAMPLE_FACTOR = 1.0;\nUSING_OPENCV = Image.USING_OPENCV;\n\nif(USING_OPENCV):\n\n    ##########################################################################\n    # ################ THESE ARE THE FUNCTIONS TO OVERRIDE! ################ #\n    # ################     FOR CUSTOM SALIENCY METRICS!     ################ #\n    ##########################################################################\n\n    # You can modify them here. But I would suggest elsewhere in your code\n    # just setting Video.localRhythmicSaliencyFunction and\n    # Video.visualBeatFunction to whatever you want. See how they are assigned\n    # when Video_CV is included in Video.py. -Abe\n\n    def localRhythmicSaliencyFunction(self, **kwargs):\n        \"\"\"\n        Change to use different function for local saliency\n        \"\"\"\n        return self.getVisibleImpactEnvelope(**kwargs);\n\n    def visualBeatFunction(self, **kwargs):\n        \"\"\"\n        Change to use different default strategy for selecting visual beats\n        \"\"\"\n        # beat_params = dict(\n        #     pre_max_time=0.2,\n        #     post_max_time=0.2,\n        #     pre_avg_time=0.2,\n        #     post_avg_time=0.2,\n        #     wait_time=0.1,\n        # )\n        beat_params = self._getDefaultPeakPickingTimeParams();\n        beat_params.update(kwargs);\n        return self.getVisibleImpacts(**beat_params);\n\n    # #################### This is how they are called #################### #\n\n    def getLocalRhythmicSaliency(self, force_recompute=False, **kwargs):\n        feature_name = 'local_rhythmic_saliency';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = dict();\n            params.update(kwargs);\n            params.update({'force_recompute':force_recompute});\n            result = self.localRhythmicSaliencyFunction(**params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getVisualBeats(self, force_recompute=False, **kwargs):\n        feature_name = 'visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            params.update({'force_recompute': force_recompute});\n            result = self.visualBeatFunction(**params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    # ##################################################################### #\n\n    ##########################################################################\n    # ###################################################################### #\n    ##########################################################################\n\n\n\n    def cvGetGrayFrame(self, f):\n        colorframe = self.getFrame(f).astype(np.uint8);\n        return ocv.cvtColor(colorframe, ocv.COLOR_RGB2GRAY);\n\n    def getImageFromFrameGray(self, f):\n        frame = self.getImageFromFrame(f);\n        frame.RGB2Gray();\n        return frame;\n\n    def flow2row(ang, amp, bins, subdivs, n_shifts, density):\n        h, w = ang.shape[:2];\n        ncells = np.power(4, subdivs);\n        nperd = np.power(2, subdivs);\n\n        xw = w-n_shifts[1];\n        yw = h-n_shifts[0];\n\n        xcells = np.arange(nperd + 1, dtype=float);\n        ycells = np.arange(nperd + 1, dtype=float);\n        xcells = np.floor((xcells / (nperd)) * xw);\n        ycells = np.floor((ycells / (nperd)) * yw);\n        # print(n_shifts)\n\n        ahis = np.zeros([ncells * bins, n_shifts[0]*n_shifts[1]]);\n\n        for dy in range(n_shifts[0]):\n            for dx in range(n_shifts[1]):\n                ampwin = amp[dy:dy+yw,dx:dx+xw];\n                angwin = ang[dy:dy+yw,dx:dx+xw];\n                cell_counter = 0;\n                for x in range(nperd):\n                    for y in range(nperd):\n                        ystart=int(ycells[y]);\n                        yend = int(ycells[y+1]);\n                        xstart = int(xcells[x]);\n                        xend = int(xcells[x + 1]);\n                        angcell = angwin[ystart:yend, xstart:xend];\n                        ampcell = ampwin[ystart:yend, xstart:xend];\n                        cahis, cbinbounds = np.histogram(angcell.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                                         weights=ampcell.ravel(), density=density);\n                        # print(\"ahis shape: {}\\ncahis shape: {}\\ndx, dy: {}, {}\\ncell_counter: {}\\nbins: {}\\n\".format(ahis.shape, cahis.shape, dx, dy, cell_counter, bins));\n                        ahis[cell_counter * bins:(cell_counter + 1) * bins, dx+dy*n_shifts[0]] = cahis;\n                        cell_counter = cell_counter + 1;\n        return ahis;\n\n    def getFlowFrame(self, frame_index):\n        prev_frame = self.cvGetGrayFrame(frame_index-1);\n        this_frame = self.vbGetGrayFrame(frame_index);\n        return cvDenseFlowFarneback(from_image=prev_frame, to_image=this_frame);\n\n    def getFlowFramePolar(self, frame_index):\n        \"\"\"\n        :param self:\n        :param frame_index:\n        :return: polar where polar[:,:,0] is amplitude, and polar[:,:,1] is angle\n        \"\"\"\n        flow = self.getFlowFrame(frame_index);\n        fx, fy = flow[:,:,0], flow[:,:,1];\n        polar = np.zeros(size(flow));\n        polar[:,:,0] = np.sqrt(fx * fx + fy * fy);\n        polar[:,:,1] = np.arctan2(fy, fx) + np.pi\n        return polar;\n\n    def computeDirectogramPowers(self, bins=None, dead_zone= 0.05, density=None, save_if_computed=True, noise_floor_percentile=None, **kwargs):\n        if(bins is None):\n            bins = 128;\n        if(noise_floor_percentile is None):\n            noise_floor_percentile = 20;\n\n        print((\"Computing Flow Features with deadzone {}\".format(dead_zone)))\n\n        signal_dim = 128;\n        m_histvals = np.zeros([signal_dim, self.n_frames(), 3]);\n\n        flow_averages = np.zeros([self.n_frames(), 1]);\n        sampling_rate=self.sampling_rate;\n        duration = self.getDuration();\n        nsamples = sampling_rate*duration;\n        # print(sampling_rate, duration)\n        frame_start_times = np.linspace(0,duration,num=int(nsamples),endpoint=False);\n        frame_index_floats = frame_start_times*self.sampling_rate;\n\n        lastframe = self.cvGetGrayFrame(frame_index_floats[0]);\n\n        start_timer=time.time();\n        last_timer=start_timer;\n        fcounter=0;\n        counter = 0;\n\n        for nf in range(len(frame_index_floats)):\n            nextframe= self.cvGetGrayFrame(frame_index_floats[nf]);\n            flow = cvDenseFlowFarneback(from_image=lastframe, to_image=nextframe);\n            h, w = flow.shape[:2];\n            fx, fy = flow[:,:,0], flow[:,:,1];\n\n            # if(filter_median):\n            #     fx = fx-np.median(fx.ravel());\n            #     fy = fy-np.median(fy.ravel());\n            #     assert(False), \"SHOULDNT BE FILTERING MEDIAN! VESTIGIAL CODE\"\n\n            ang = np.arctan2(fy, fx) + np.pi\n            amp = np.sqrt(fx*fx+fy*fy);\n\n            winstarty = int(dead_zone*h);\n            winendy = h-winstarty;\n            winstartx = int(dead_zone*w);\n            winendx = w-winstartx;\n            angw = ang[winstarty:winendy, winstartx:winendx];\n            ampw = amp[winstarty:winendy, winstartx:winendx];\n\n            mask0 = (ampw>np.percentile(ampw,noise_floor_percentile)).astype(float);\n            ahis0, cbinbounds = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=mask0.ravel(), density=density);\n            ahis1, cbinbounds1 = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=ampw.ravel(), density=density);\n            ahis2, cbinbounds2 = np.histogram(angw.ravel(), bins=bins, range=(0, 2 * np.pi),\n                                             weights=np.power(ampw, 2).ravel(), density=density);\n\n            m_histvals[:, counter, 0] = ahis0;\n            m_histvals[:, counter, 1] = ahis1;\n            m_histvals[:, counter, 2] = ahis2;\n\n            lastframe=nextframe;\n            counter+=1;\n            fcounter+=1;\n\n            if(not (fcounter%50)):\n                if((time.time()-last_timer)>10):\n                    last_timer=time.time();\n                    print((\"{}%% done after {} seconds...\".format(100.0*truediv(fcounter,len(frame_index_floats)), last_timer-start_timer)));\n        params = dict( bins = bins,\n                        deadzone=dead_zone,\n                        density=density);\n        params.update(kwargs);\n        self.setFeature(name='directogram_powers', value=m_histvals, params=params);\n        if(save_if_computed):\n            self.save(features_to_save=['directogram_powers']);\n        return m_histvals;\n\n    ######################### Other Features #############################\n\n    def getDirectogramPowers(self, force_recompute=False, **kwargs):\n        feature_name = 'directogram_powers';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            flow_powers = self.computeDirectogramPowers(**kwargs);\n        return self.getFeature(feature_name);\n\n    # def getDirectogram(self, bins = None, weights=None, density=None, force_recompute=False, save_if_computed=True, **kwargs):\n    def getDirectogram(self, **kwargs):\n        feature_name = 'directogram';\n        force_recompute = kwargs.get('force_recompute');\n        if((not self.hasFeature(feature_name)) or force_recompute):\n            flow_powers = self.getFeature('directogram_powers');\n            fh = flow_powers[:,:,1];\n            self.setFeature(name='directogram', value=fh, params=kwargs);\n        return self.getFeature(feature_name);\n\n    def getVisualTempo(self, force_recompute=None, **kwargs):\n        feature_name = 'visual_tempo';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            vbe = self.getFeature('local_rhythmic_saliency');\n            # assert librosa.__version__ == '0.7.1'\n            # result = librosa.beat.beat_track(onset_envelope=vbe, sr=self.sampling_rate, hop_length=1, **kwargs);\n            result = librosa.beat.beat_track(onset_envelope=vbe, sr=self.sampling_rate, hop_length=1, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=kwargs);\n        return self.getFeature(feature_name);\n\n    def getVisualTempogram(self, window_length=None, force_recompute=None, norm_columns = None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param window_length: in seconds\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'visual_tempogram';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            if(window_length is None):\n                window_length = DEFAULT_TEMPOGRAM_WINDOW_SECONDS;\n            params = kwargs;\n            params.update({'force_recompute': force_recompute});\n            vbe = self.computeImpactEnvelope(cut_suppression_seconds = None);\n            onset_envelope = vbe;\n            win_length = int(round(window_length * self.sampling_rate));\n            sr = self.sampling_rate;\n            hop_length = 1;\n\n            center=kwargs.get('center');\n            if(center is None):\n                center=True;\n            window='hann'\n            norm=np.inf;\n            ac_window = librosa.filters.get_window(window, win_length, fftbins=True)\n\n            # Center the autocorrelation windows\n            n = len(onset_envelope)\n\n            if center:\n                onset_envelope = np.pad(onset_envelope, int(win_length // 2),\n                                        mode='linear_ramp', end_values=[0, 0])\n            # Carve onset envelope into frames\n            odf_frame = librosa.util.frame(onset_envelope,\n                                   frame_length=win_length,\n                                   hop_length=hop_length)\n            # Truncate to the length of the original signal\n            if center:\n                odf_frame = odf_frame[:, :n]\n\n            odf_frame = librosa.util.normalize(odf_frame,axis=0,norm=norm)\n            if(norm_columns is None):\n                norm_columns = True;\n\n            if(norm_columns):\n                # Window, autocorrelate, and normalize\n                result = librosa.util.normalize(\n                    librosa.core.audio.autocorrelate(odf_frame * ac_window[:, np.newaxis], axis=0), norm=norm, axis=0);\n            else:\n                result = librosa.core.audio.autocorrelate(odf_frame * ac_window[:, np.newaxis], axis=0);\n                result = np.true_divide(result, np.max(result.ravel()));\n\n            tempo_bpms = librosa.tempo_frequencies(result.shape[0], hop_length=hop_length, sr=sr)\n            self.setFeature(name='tempogram_bpms', value=tempo_bpms);\n            ###########\n            self.setFeature(name=feature_name, value=result, params=params);\n\n        return self.getFeature(feature_name);\n\n    def getVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = False, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getForwardVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        \"\"\"\n        Same as getVisibleImpactEnvelope by default.\n        :param self:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'forward_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = False, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBackwardVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'backward_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=False, backward = True, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBothWayVisibleImpactEnvelope(self, force_recompute=False, **kwargs):\n        feature_name = 'both_way_visual_impact_envelope';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result = self.computeImpactEnvelope(forward=True, backward = True, **kwargs);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getVisibleImpactEnvelopePowers(self, force_recompute=False, **kwargs):\n        feature_name = 'impact_envelope_powers';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            result0 = self.computeImpactEnvelope(power= 0, **params);\n            result = np.zeros([len(result0), 3]);\n            result[:, 0] = result0;\n            result[:, 1] = self.computeImpactEnvelope(power= 1, **params);\n            result[:, 2] = self.computeImpactEnvelope(power=2, **params);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getCutTimes(self):\n        return Event.ToStartTimes(self.getCutEvents());\n\n    def getCutEvents(self, force_recompute=False, **kwargs):\n        \"\"\"\n        Hacky estimate of cuts in a video\n        :param self:\n        :param force_recompute:\n        :param kwargs:\n        :return:\n        \"\"\"\n        feature_name = 'cut_events';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            powers = self.getFeature('directogram_powers');\n            im0 = powers[:, :, 0];\n            im2 = powers[:, :, 2];\n            imc = np.true_divide(im2, 0.05 + im0);\n\n            medsig = np.median(imc, 0);\n            medall = np.median(imc);\n            cutsig = np.true_divide(medsig, medall)\n            cut_detection_ratio = kwargs.get('cut_detection_ratio');\n            if(cut_detection_ratio is None):\n                cut_detection_ratio=CUT_DETECTION_RATIO;\n            clipsig = (cutsig > cut_detection_ratio).astype(float);\n            clip_floorsig = (cutsig > CUT_DETECTION_FLOOR).astype(float);\n            clipsig = np.multiply(clipsig, clip_floorsig);\n\n            einds = np.flatnonzero(clipsig);\n            etimes = einds * truediv(1.0, self.sampling_rate);\n            ev = Event.FromStartTimes(etimes, type='cut');\n            ev = self.visualBeatsFromEvents(ev);\n            evout = []\n            for e in range(len(ev)):\n                ev[e].setInfo('frame', einds[e]);\n            result = ev;\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def visualBeatsFromEvents(self, events):\n        def downsample_hist(sig, levels):\n            nperbin = np.power(2, levels);\n            rshp = sig.reshape(-1, nperbin);\n            return rshp.sum(axis=1);\n        if(self.hasFeature('impact_envelope')):\n            svbe=self.getFeature('impact_envelope');\n        else:\n            svbe=self.computeImpactEnvelope(cut_suppression_seconds = None);\n        flow_powers = self.getFeature('directogram_powers');\n        vis_tempogram = self.getFeature('visual_tempogram');\n\n        vbeats = [];\n        for e in events:\n            b = VisualBeat.FromEvent(e);\n            ei = int(round(b.start*self.sampling_rate*VB_UPSAMPLE_FACTOR));\n            b.weight = svbe[ei];\n\n            histsize = int(128/int(np.power(2,HISTOGRAM_DOWNSAMPLE_LEVELS)))\n            histslice = np.zeros([histsize, HISTOGRAM_FRAMES_PER_BEAT]);\n            histslice = np.squeeze(np.mean(histslice, 1));\n            b.flow_histogram = downsample_hist(sig=histslice, levels=HISTOGRAM_DOWNSAMPLE_LEVELS);\n            b.flow_histogram = np.divide(b.flow_histogram, np.sum(b.flow_histogram));\n            b.local_autocor = vis_tempogram[:,ei];\n            b.local_autocor = b.local_autocor/np.max(b.local_autocor);\n            b.sampling_rate=self.sampling_rate;\n            vbeats.append(b);\n        return vbeats;\n\n    def getVisualBeatTimes(self, **kwargs):\n        return Event.ToStartTimes(self.getVisualBeats(**kwargs));\n\n    def getDirectionalFlux(self,\n                            f_sigma=None,\n                            median_kernel=None,\n                            power=None,\n                            **kwargs):\n        \"\"\"\n        The visual impact complement of a spectral flux matrix\n        :param self:\n        :param f_sigma: sigma for the gaussian used to filter, using sp.ndimage.filters.gaussian_filter\n        :param median_kernel: used in sp.signal.medfilt\n        :param power: Which power of the flow to use. Usually use 1.\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        def d_x(im):\n            d_im = np.zeros(im.shape);\n            d_im[:, 0] = im[:, 0];\n            for c in range(1, im.shape[1]):\n                d_im[:, c] = im[:, c] - im[:, c - 1];\n            return d_im;\n\n        if (f_sigma is None):\n            f_sigma = [5, 3];\n        if (median_kernel is None):\n            median_kernel = [3, 3];\n\n        if(power is None):\n            power = 1;\n\n        powers = self.getFeature('directogram_powers');\n        im = powers[:,:,power].copy();\n        if (f_sigma is not None):\n            im = sp.ndimage.filters.gaussian_filter(input=im, sigma=f_sigma, order=0);\n\n        im = sp.signal.medfilt(im, median_kernel);\n        return d_x(im);\n\n    def computeImpactEnvelope(self,\n                             forward=True,\n                             backward = False,\n                             f_sigma=None,\n                             median_kernel=None,\n                             highpass_window_seconds= 0.8,\n                             cut_percentile=99,\n                             power=None,\n                             crop = None,\n                             normalize = True,\n                             **kwargs):\n        \"\"\"\n\n        :param self:\n        :param forward: include impact going forward in time\n        :param backward: include impact going backward in time\n        :param f_sigma: sigma for the gaussian used to filter, using sp.ndimage.filters.gaussian_filter\n        :param median_kernel: used in sp.signal.medfilt\n        :param highpass_window_seconds: highpass window size in seconds\n        :param cut_percentile: percentile above which to consider cuts and to clip\n        :param power: Which power of the flow to use. Usually use 1.\n        :param crop:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        upsample_factor = kwargs.get('upsample_factor');\n        inputargs = dict(f_sigma=f_sigma,\n                         median_kernel=median_kernel,\n                         power=power,\n                         crop = crop);\n\n        inputargs.update(kwargs);\n        im_d = self.getDirectionalFlux(**inputargs);\n\n        if(forward and backward):\n            im = np.fabs(im_d);\n        elif(forward):\n            im = -im_d;\n            im = np.clip(im, 0, None)\n        elif(backward):\n            im = im_d;\n            im = np.clip(im, 0, None)\n        else:\n            assert(False), \"Must be at least one of either forward or backward.\"\n\n        vimpact = np.squeeze(np.mean(im, 0));\n        sampling_rate = self.sampling_rate;\n        if(upsample_factor is not None and (upsample_factor>1)):\n            newlen = upsample_factor * len(vimpact);\n            sampling_rate = upsample_factor*sampling_rate;\n            vimpact = sp.signal.resample(vimpact, newlen);\n\n        if(highpass_window_seconds):\n            order = kwargs.get('highpass_order');\n            if(order is None):\n                order = 5;\n            cutoff = truediv(1.0, highpass_window_seconds);\n            normal_cutoff = cutoff / (sampling_rate*0.5);\n            b, a = sp.signal.butter(order, normal_cutoff, btype='high', analog=False)\n            vimpact = sp.signal.filtfilt(b, a, vimpact);\n\n\n        normfactor = np.max(np.fabs(vimpact[:]));\n\n        if (cut_percentile is not None):\n            fx = np.fabs(vimpact);\n            pv = np.percentile(fx, cut_percentile);\n            pvlow = np.percentile(fx, cut_percentile-1);\n            normfactor = pv;\n            ptile = (vimpact > pv).astype(float);\n            pntile = (vimpact < -pv).astype(float);\n            pboth = ptile+pntile;\n            einds = np.flatnonzero(pboth);\n            lastind = -2;\n            for j in range(len(einds)):\n                if(einds[j]==(lastind+1)):\n                    vimpact[einds[j]]=0;\n                else:\n                    vimpact[einds[j]]=pvlow;\n\n        if(normalize):\n            vimpact = np.true_divide(vimpact, normfactor);\n        return vimpact;\n\n    # 0.8, cut_suppression_seconds = 0.4,\n    def computeImpactEnvelopeOld(self, f_sigma=None, median_kernel=None, highpass_window_seconds= 0.8, cut_percentile=99, power=None, crop = None, normalize=None, **kwargs):\n        \"\"\"\n        I believe this is the version of the function that I used in the original paper. Keeping it around for record.\n        :param self:\n        :param f_sigma:\n        :param median_kernel:\n        :param highpass_window_seconds:\n        :param cut_percentile:\n        :param power:\n        :param crop:\n        :param normalize:\n        :param kwargs:\n        :return:\n        \"\"\"\n        def d_x(im):\n            # d_im = np.zeros(im.shape, dtype=np.float128);\n            d_im = np.zeros(im.shape);\n            d_im[:, 0] = im[:, 0];\n            for c in range(1, im.shape[1]):\n                d_im[:, c] = im[:, c] - im[:, c - 1];\n            return d_im;\n\n        if (f_sigma is None):\n            f_sigma = [5, 3];\n        if (median_kernel is None):\n            median_kernel = [3, 3];\n\n        if(power is None):\n            power = 1;\n\n        upsample_factor = kwargs.get('upsample_factor');\n\n        powers = self.getFeature('directogram_powers');\n        print((\"computing impact env with power {}\".format(power)));\n        im = powers[:,:,power].copy();\n\n        if (f_sigma is not None):\n            im = sp.ndimage.filters.gaussian_filter(input=im, sigma=f_sigma, order=0);\n\n        im = sp.signal.medfilt(im, median_kernel);\n        im = -d_x(im);\n        im = np.clip(im, 0, None)\n\n        svbe = np.squeeze(np.mean(im, 0));\n        sampling_rate = self.sampling_rate;\n\n        if(upsample_factor is not None and (upsample_factor>1)):\n            newlen = upsample_factor * len(svbe);\n            sampling_rate = upsample_factor*sampling_rate;\n            svbe = sp.signal.resample(svbe, newlen);\n\n        if(highpass_window_seconds):\n            order = kwargs.get('highpass_order');\n            if(order is None):\n                order = 5;\n            cutoff = truediv(1.0, highpass_window_seconds);\n            normal_cutoff = cutoff / (sampling_rate*0.5);\n            b, a = sp.signal.butter(order, normal_cutoff, btype='high', analog=False)\n            svbe = sp.signal.filtfilt(b, a, svbe);\n\n\n        normfactor = np.max(np.fabs(svbe[:]));\n\n        if (cut_percentile is not None):\n            fx = np.fabs(svbe);\n            pv = np.percentile(fx, cut_percentile);\n            pvlow = np.percentile(fx, cut_percentile-1);\n            normfactor = pv;\n            ptile = (svbe > pv).astype(float);\n            pntile = (svbe < -pv).astype(float);\n            pboth = ptile+pntile;\n            einds = np.flatnonzero(pboth);\n            lastind = -2;\n            for j in range(len(einds)):\n                if(einds[j]==(lastind+1)):\n                    svbe[einds[j]]=0;\n                else:\n                    svbe[einds[j]]=pvlow;\n\n        if(normalize is not False):\n            svbe = np.true_divide(svbe, normfactor);\n        return svbe;\n\n    def getVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'visible_impacts';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            svbe = self.getFeature('impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n\n            peak_params = self._getDefaultPeakPickingTimeParams();\n            peak_params.update(kwargs); # if params given in arguments, those will override the defaults here.\n\n            v_events = Event.FromSignalPeaks(signal=svbe, sampling_rate=u_sampling_rate, **peak_params);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            result = self.visualBeatsFromEvents(v_events);\n\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getForwardVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'forward_visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            local_saliency = self.getFeature('forward_visual_impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n            v_events = Event.FromSignalPeaks(signal=local_saliency, sampling_rate=u_sampling_rate, event_type= 'forward', **kwargs);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            result = Event.SetDirections(v_events, direction=Event.DIRECTION_FORWARD);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n    def getBackwardVisibleImpacts(self, force_recompute=False, include_cut_events = None, **kwargs):\n        feature_name = 'backward_visual_beats';\n        if ((not self.hasFeature(feature_name)) or force_recompute):\n            params = kwargs;\n            local_saliency = self.getFeature('backward_visual_impact_envelope', **kwargs);\n            upsample_factor = kwargs.get('upsample_factor');\n            if(upsample_factor is None):\n                upsample_factor = 1;\n            u_sampling_rate = self.sampling_rate*upsample_factor;\n            v_events = Event.FromSignalPeaks(signal=local_saliency, sampling_rate=u_sampling_rate, **kwargs);\n            if(include_cut_events):\n                cut_events = self.getFeature('cut_events');\n                v_events = v_events + cut_events;\n                Event.Sort(v_events);\n            # result = self.visualBeatsFromEvents(v_events);\n            result = Event.SetDirections(v_events, direction=Event.DIRECTION_BACKWARD);\n            self.setFeature(name=feature_name, value=result, params=params);\n        return self.getFeature(feature_name);\n\n\n    def findAccidentalDanceSequences(self, target_n_beats = 7, n_samples=25, delta_range = None):\n        if(delta_range is None):\n            delta_range = [0.02, 0.5];\n\n        deltas = np.linspace(delta_range[0], delta_range[1], num=n_samples, endpoint=True);\n        deltapick = delta_range[0];\n        sequences = [];\n        for i, delta in enumerate(deltas):\n            peak_vars = self._getDefaultPeakPickingTimeParams(delta=delta);\n            sequences = self.getVisualBeatSequences(peak_vars=peak_vars, print_summary=False);\n            # print(\"Delta {} has top sequence with {} beats\".format(delta, len(sequences[0])));\n            if(len(sequences[0])<=target_n_beats):\n                deltapick = delta;\n                break;\n        print((\"Selected delta value {}\".format(deltapick)));\n        return sequences;\n\n\n    def getVisualBeatSequences(self,\n                               search_tempo=None,\n                               target_period=None,\n                               search_window=0.75,\n                               min_beat_limit=None,\n                               max_beat_limit=None,\n                               unary_weight=None,\n                               binary_weight=None,\n                               break_on_cuts=None,\n                               peak_vars=None,\n                               time_range=None,\n                               n_return = None,\n                               unsorted = False,\n                               print_summary = True,\n                               **kwargs):\n        \"\"\"\n\n        :param self:\n        :param search_tempo: optional tempo you would like to find visual beats at\n        :param target_period: optional target period you would like to use for finding beats. Ignored if search tempo is provided.\n        :param search_window: longest amount of time (seconds) allowed between beats before a segment is broken into multiple segments\n        :param min_beat_limit: only consider sequences with\n        :param unary_weight:\n        :param binary_weight:\n        :param break_on_cuts:\n        :param peak_vars:\n        :param kwargs:\n        :return:\n        \"\"\"\n        if (peak_vars is not None):\n            # impacts = self.getFeature('visible_impacts', force_recompute=True, **peak_vars);\n            impacts = self.getVisualBeats(force_recompute = True, **peak_vars);\n        else:\n            # impacts = self.getFeature('visible_impacts');\n            impacts = self.getVisualBeats();\n\n        if(time_range is not None):\n            impactseg = [];\n            for i in impacts:\n                if(i.start>time_range[0] and i.start < time_range[1]):\n                    impactseg.append(i);\n            impacts = impactseg;\n\n\n        if (search_tempo is not None):\n            tempo = search_tempo;\n            beat_time = np.true_divide(60.0, tempo);\n            sequences = VisualBeat.PullOptimalPaths_Basic(impacts, target_period=beat_time, unary_weight=unary_weight,\n                                                      binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                      window_size=search_window);\n\n        elif(target_period is not None):\n            sequences = VisualBeat.PullOptimalPaths_Basic(impacts, target_period=target_period, unary_weight=unary_weight,\n                                                          binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                          window_size=search_window);\n        else:\n            sequences = VisualBeat.PullOptimalPaths_Autocor(impacts, unary_weight=unary_weight, binary_weight=binary_weight,\n                                                        break_on_cuts=break_on_cuts, window_size=search_window);\n\n        r_sequences = [];\n\n        if(min_beat_limit is None):\n            min_beat_limit = 2;\n        if(max_beat_limit is None):\n            max_beat_limit = len(impacts)+1;\n\n        for S in sequences:\n            if ((len(S) > min_beat_limit) and (len(S) < max_beat_limit)):\n                r_sequences.append(S);\n\n        if(not unsorted):\n            r_sequences.sort(key=len, reverse=True);\n            if(n_return is not None):\n                r_sequences = r_sequences[:n_return];\n        if(print_summary):\n            print((\"{} segments\".format(len(r_sequences))));\n            for s in range(len(r_sequences)):\n                print((\"Segment {} has {} beats\".format(s, len(r_sequences[s]))));\n\n        return r_sequences;\n\n\n    def printVisualBeatSequences(self,\n                                 search_tempo=None,\n                                 target_period=None,\n                                 search_window=None,\n                                 min_beat_limit=None,\n                                 max_beat_limit=None,\n                                 unary_weight=None,\n                                 binary_weight=None,\n                                 break_on_cuts=None,\n                                 peak_vars=None,\n                                 n_return = None,\n                                 time_range=None, **kwargs):\n        \"\"\"\n\n        :param self:\n        :param target_period:\n        :param search_tempo:\n        :param search_window:\n        :param beat_limit:\n        :param unary_weight:\n        :param binary_weight:\n        :param break_on_cuts:\n        :param n_return:\n        :param peak_vars:\n        :param time_range:\n        :param kwargs:\n        :return:\n        \"\"\"\n\n        sorted = True;\n\n        sequence_args = dict(\n            search_tempo=search_tempo,\n            target_period=target_period,\n            search_window=search_window,\n            min_beat_limit=min_beat_limit,\n            max_beat_limit=max_beat_limit,\n            unary_weight=unary_weight,\n            binary_weight=binary_weight,\n            break_on_cuts=break_on_cuts,\n            peak_vars=peak_vars,\n            n_return=n_return,\n            time_range=time_range);\n\n        seqs = self.getVisualBeatSequences(**sequence_args)\n        print((\"sequence arguments were:\\n{}\".format(sequence_args)));\n        print((\"There were {} sequences total\".format(len(seqs))));\n        nclips = 0;\n        rsegments = [];\n        for S in seqs:\n            if (len(S) > 1):\n                nclips = nclips + 1;\n                rsegments.append(S);\n\n        # rsegments.sort(key=len, reverse=True);\n        # if (n_return is not None):\n        #     rsegments = rsegments[:n_return];\n\n        Event.PlotSignalAndEvents(self.getFeature('impact_envelope'),  sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=rsegments[0],  time_range=time_range);\n        return rsegments;\n\n    def plotEvents(self, events, time_range = 'default', **kwargs):\n        time_range_use = time_range;\n        if(time_range.lower() == 'default'):\n            time_range_use = [0,0];\n            time_range_use[0] = events[0].start-1;\n            time_range_use[1] = events[-1].start+1;\n\n        signal = self.getFeature('local_rhythmic_saliency');\n        mplt = Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate * VB_UPSAMPLE_FACTOR, events=events, time_range=time_range_use, **kwargs);\n        plt.xlabel('Time (s)')\n        return mplt;\n\n    def plotCutEvents(self, **kwargs):\n        signal = self.getFeature('impact_envelope');\n        events = self.getFeature('cut_events', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n\n    def plotVisibleImpacts(self, **kwargs):\n        signal = self.getFeature('impact_envelope');\n        events = self.getFeature('visible_impacts', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n    def plotImpactEnvelope(self, **kwargs):\n        signal = self.getFeature('local_rhythmic_saliency');\n        # events = self.getFeature('visual_beats', **kwargs);\n        events = None;\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n    def plotVisualBeats(self, **kwargs):\n        signal = self.getFeature('local_rhythmic_saliency');\n        events = self.getFeature('visual_beats', **kwargs);\n        Event.PlotSignalAndEvents(signal, sampling_rate=self.sampling_rate*VB_UPSAMPLE_FACTOR, events=events, **kwargs);\n        plt.title('Impact Envelope & Visual Beats')\n        plt.xlabel('Time (s)')\n        plt.ylabel('Impact Strength')\n\n\n    def loadFlowFeatures(self):\n        self.load(features_to_load=['directogram_powers', 'directogram']);\n\n    FEATURE_FUNCS['local_rhythmic_saliency'] = getLocalRhythmicSaliency;\n    FEATURE_FUNCS['directogram_powers'] = getDirectogramPowers;\n    FEATURE_FUNCS['directogram'] = getDirectogram;\n    FEATURE_FUNCS['impact_envelope'] = getVisibleImpactEnvelope;\n    FEATURE_FUNCS['impact_envelope_powers'] = getVisibleImpactEnvelopePowers;\n    FEATURE_FUNCS['visible_impacts'] = getVisibleImpacts;\n    FEATURE_FUNCS['visual_beats'] = getVisualBeats;\n    # FEATURE_FUNCS['backward_visual_beats'] = getBackwardVisualBeats;\n    # FEATURE_FUNCS['forward_visual_beats'] = getForwardVisualBeats;\n    FEATURE_FUNCS['backward_visual_impact_envelope'] = getBackwardVisibleImpactEnvelope;\n    FEATURE_FUNCS['both_way_visual_impact_envelope'] = getBothWayVisibleImpactEnvelope;\n    FEATURE_FUNCS['forward_visual_impact_envelope'] = getForwardVisibleImpactEnvelope;\n    FEATURE_FUNCS['directional_flux'] = getDirectionalFlux;\n    FEATURE_FUNCS['visual_tempogram'] = getVisualTempogram;\n    FEATURE_FUNCS['cut_events']=getCutEvents;\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VisBeatDefines.py",
    "content": "VB_DEBUG = True;\n\nDEFAULT_TEMPOGRAM_WINDOW_SECONDS = 5;\nAUDIO_DEFAULT_HOP_LENGTH = 512;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VisBeatExampleVideo.py",
    "content": "import os\nfrom visbeat3.SourceLocationParser import ParseSourseLocation\n\nclass VisBeatExampleVideo(object):\n    def __init__(self, name, url, start_beat=None, end_beat = None, display_name = None, code=None, leadin=None, **kwargs):\n        self.name = name;\n        self.url = url;\n        self.start_beat = start_beat;\n        self.end_beat = end_beat;\n        self._display_name = display_name;\n        self._code = code;\n        self.leadin = leadin;\n        for k in kwargs:\n            setattr(self, k, kwargs[k]);\n        if(code is None):\n            sloc = ParseSourseLocation(self.url);\n            self._code = sloc.code;\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        return self._getCode();\n    def _getCode(self):\n        return self._code;\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        self._code = value;\n    # </editor-fold>\n\n    # def _ytEmbedCode(self):\n\n    # <editor-fold desc=\"Property: 'display_name'\">\n    @property\n    def display_name(self):\n        return self._getDisplayName();\n    def _getDisplayName(self):\n        if(self._display_name is None):\n            return self.name;\n        else:\n            return self._display_name;\n    # </editor-fold>\n\n\n    def _ytWatchURL(self):\n        return 'https://www.youtube.com/watch?v={}'.format(self.code);\n\n    def _ytEmbedURL(self, autoplay=None):\n        s = 'https://www.youtube.com/embed/{}'.format(self.code);\n        if(autoplay):\n            s = s+'?autoplay=1';\n        return s;\n\n    def _ytThumbURL(self):\n        return 'https://ytimg.googleusercontent.com/vi/{}/default.jpg'.format(self.code);\n\n    def _fancyBoxCode(self, with_label = None):\n        \"\"\"\"\"\"\n        s = HTMLCode();\n        if(with_label):\n            s.addLine(\"<figure>\")\n        s.addLine('<a class=\"vb_youtube_fancybox\" data-fancybox href=\"{watchurl}\"><img alt=\"{alt_name}\" src=\"{thumburl}\" /></a>'.format(watchurl=self._ytWatchURL(),\n                                                                                                                                        alt_name = self.display_name,\n                                                                                                                                        thumburl = self._ytThumbURL()))\n\n        if(with_label):\n            s.addLine('<figcaption>');\n            # s.addLine('<a href=\"{watchurl}\">{displayname}</a>'.format(self.url, self.display_name));\n            s.addLine('{displayname}'.format(displayname=self.display_name));\n            s.addLine('</figcaption>')\n            s.addLine('</figure>');\n        return s.string;\n\n\nfrom bs4 import BeautifulSoup\nclass HTMLCode(object):\n    def __init__(self, start_string=None):\n        self._code = \"\";\n        self._lines = [];\n        if(start_string is not None):\n            self.add(start_string)\n        self._soup = None;\n\n    # <editor-fold desc=\"Property: 'string'\">\n    @property\n    def string(self):\n        return self._getString();\n    def _getString(self):\n        return BeautifulSoup(self.code).prettify();\n\n    # <editor-fold desc=\"Property: 'code'\">\n    @property\n    def code(self):\n        return self._getCode();\n    def _getCode(self):\n        return self._code;\n    @code.setter\n    def code(self, value):\n        self._setCode(value);\n    def _setCode(self, value):\n        self._code = value;\n    # </editor-fold>\n\n\n    # <editor-fold desc=\"Property: 'soup'\">\n    @property\n    def soup(self):\n        return self._getSoup();\n    def _getSoup(self):\n        if(self._soup is None):\n            self._makeSoup();\n        return self._soup;\n\n    def _makeSoup(self):\n        self._soup = BeautifulSoup(self.code, 'html.parser');\n    # @soup.setter\n    # def soup(self, value):\n    #     self._setSoup(value);\n    # def _setSoup(self, value):\n    #     self._soup = value;\n    # </editor-fold>\n\n    def add(self, s):\n        self.code = self.code+s;\n\n    def addLine(self, s):\n        self.code = self.code+'\\n'+s;\n\n    def startTable(self, id=None, class_ = None, **kwargs):\n        targs = dict(table_width=\"80%\", border=1, cellspacing=1, cellpadding=1)\n        targs.update(kwargs);\n        s = '<table ';\n        if(id is not None):\n            s = s+'id=\"{}\" '.format(id);\n        if(class_ is not None):\n            s = s + 'class=\"{}\" '.format(class_);\n        s = s+'width=\"{table_width}\" border=\"{border}\" cellspacing=\"{cellspacing}\" cellpadding=\"{cellpadding}\">'.format(**targs);\n        self.addLine(s);\n        self.addLine('<tbody>');\n\n    def endTable(self):\n        self.addLine(\"</tbody>\");\n        self.addLine(\"</table>\");\n\n    def startRow(self):\n        self.addLine('<tr>');\n\n    def endRow(self):\n        self.addLine('</tr>');\n\n    def addColumnLabel(self, label):\n        self.addLine('<th scope=\"col\">')\n        self.addLine(label);\n        self.addLine('</th>');\n\n    def addRowLabel(self, label):\n        self.addLine('<th scope=\"row\">')\n        self.addLine(label);\n        self.addLine('</th>');\n\n    def addRowCell(self, content):\n        self.addLine(\"<td>\");\n        self.addLine(\"<div class = 'rowcelldiv'>\")\n        self.addLine(content);\n        self.addLine(\"</div>\")\n        self.addLine(\"</td>\");\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VisBeatImports.py",
    "content": "from .VisBeatDefines import *\nfrom .AImports import *\nfrom .AObject import AObject\nimport numpy as np\nimport scipy as sp\n\nimport os\nimport imageio\n\nimport matplotlib\ntry:\n    import matplotlib.pyplot as plt\nexcept ImportError as e:\n    AWARN(\"matplotlib problem... if you are using conda try installing with 'conda install matplotlib'\")\n    matplotlib.use('agg');\n    import matplotlib.pyplot as plt\nimport matplotlib.style as ms\n\nimport io\nimport base64\nimport math\nfrom operator import truediv\nimport time\nimport shutil\nfrom time import gmtime, strftime, localtime\nimport librosa;\nfrom ._mediafiles import GetVBMarkPath\n\ndef local_time_string():\n    return strftime(\"%Y-%m-%d_%H:%M:%S\", localtime());\n\n\ndef VBWARN(message):\n    print(message)\n    #\n    # def send_warnings_to_print_red(message, category, filename, lineno):\n    #     print(colored('{} WARNING! file: {} Line:{}\\n{}'.format(category, filename, lineno, message), 'red'))\n    # old_showwarning = warnings.showwarning\n    # warnings.showwarning = send_warnings_to_print_red;\n\nVB_MACHINE_ID = None;\n# if(VB_MACHINE_ID):\n    # matplotlib.use('PS');\n\nISNOTEBOOK = False;\nif(runningInNotebook()):\n    ISNOTEBOOK = True;\n    import IPython;\n    import IPython.display\n    ms.use('seaborn-muted')\n    if(not runningInSpyder()):\n        get_ipython().magic('matplotlib inline')\n        from IPython.lib import kernel\n        connection_file_path = kernel.get_connection_file()\n        connection_file = os.path.basename(connection_file_path)\n        kernel_id = connection_file.split('-', 1)[1].split('.')[0]\n        # print(\"Kernel ID:\\n{}\".format(kernel_id));\n    from IPython.display import HTML\n    VBIPY = IPython;\n    #%matplotlib inline\n# else:\n    # matplotlib.use('PS');\n\n\ndef vb_get_ipython():\n    return VBIPY;\n\ndef clipping_params(clip_bins=30, clip_fraction=0.95):\n    return dict(clip_bins=clip_bins, clip_fraction=clip_fraction);\n\ndef get_hist_clipped(signal, clip_bins=30, clip_fraction=0.95):\n    holdshape = signal.shape[:];\n    sigrav = signal.copy().ravel();\n    sigh, sigb = np.histogram(sigrav, bins=clip_bins);\n    maxbini=np.argmax(sigh);\n    totalmass = np.sum(sigh);\n    total_included = truediv(sigh[maxbini],totalmass);\n    prevbini = maxbini;\n    nextbini=maxbini;\n    bins_included = 1;\n    icounter=0;\n    while(total_included<clip_fraction and bins_included<clip_bins):\n        if((prevbini>=0 and sigh[prevbini]==0) and (nextbini<(clip_bins) and sigh[nextbini]==0)):\n            prevbini=prevbini-1;\n            nextbini=nextbini+1;\n        else:\n            if((prevbini>=0 and sigh[prevbini]>0) or nextbini>=clip_bins):\n                prevbini=prevbini-1;\n            if((nextbini<(clip_bins) and sigh[nextbini]>0) or prevbini<0):\n                nextbini=nextbini+1;\n        included_segment=sigh[max(prevbini,0):min(nextbini+1, clip_bins)];\n        total_included = truediv(np.sum(included_segment), totalmass);\n        bins_included=len(included_segment);\n        icounter+=1;\n    clipsig = np.clip(a=sigrav, a_min=sigb[max(prevbini,0)], a_max=sigb[min(nextbini,clip_bins)]);\n    clipsig.shape=signal.shape\n    return clipsig;\n\ndef np_scale_to_range(data, value_range=None):\n    if(value_range is None):\n        value_range = [0.0,255.0];\n    d = data.copy().ravel();\n    currentmin=np.min(d);\n    currentmax=np.max(d);\n    currentscale = currentmax-currentmin;\n    if(currentscale==0):\n        VBWARN(\"CANNOT SCALE CONSTANT ARRAY TO RANGE\")\n        return;\n    divscale = truediv(1.0,currentscale);\n    newrange=(value_range[1]-value_range[0]);\n    d = (d*divscale)*newrange;\n    newmin = (currentmin*divscale)*newrange;\n    d = d-newmin+value_range[0]\n    d.shape=data.shape;\n    return d\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/VisualBeat.py",
    "content": "from .Event import *\n\nclass VisualBeat(Event):\n    def VBOBJECT_TYPE(self):\n        return 'VisualBeat';\n\n    def __init__(self, start=None, type=None, weight=None, index=None, unrolled_start = None, direction=0):\n        Event.__init__(self, start=start, type=type, weight=weight, index=index, unrolled_start=unrolled_start, direction=direction);\n\n    def initializeBlank(self):\n        Event.initializeBlank(self);\n        self.flow_histogram = None;\n        self.local_autocor = None;\n        self.sampling_rate = None;\n\n    def __str__(self):\n        return \"start:{}\\ntype:{}\\nweight:{}\\nindex:{}\\nunrolled_start:{}\\nis_active:{}\\n\".format(self.start, self.type, self.weight, self.index, self.unrolled_start, self.is_active);\n\n    # def toGUIDict(self, is_active=1):\n    #     return dict(start=self.start, index=self.index, is_active=None)\n\n    def toDictionary(self):\n        d=Event.toDictionary(self);\n        # d['start']=self.start;\n        # d['type']=self.type;\n        # d['weight']=self.weight;\n        # d['index']=self.index;\n        # d['unrolled_start']=self.unrolled_start;\n        d['flow_histogram']=self.flow_histogram;\n        d['local_autocor']=self.local_autocor;\n        d['sampling_rate']=self.sampling_rate;\n        return d;\n\n    def initFromDictionary(self, d):\n        Event.initFromDictionary(self, d);\n        self.start = d['start'];\n        self.type = d['type'];\n        self.weight = d['weight'];\n        self.index = d['index'];\n        self.unrolled_start = d['unrolled_start'];\n        self.flow_histogram = d.get('flow_histogram');\n        self.local_autocor = d.get('local_autocor');\n        self.sampling_rate = d.get('sampling_rate');\n\n\n    def clone(self, start=None):\n        if(start):\n            newv = VisualBeat(start = start, type=self.type, weight=self.weight, index=self.index);\n        else:\n            newv = VisualBeat(start = self.start, type=self.type, weight=self.weight, index=self.index);\n        newv.flow_histogram = self.flow_histogram.copy();\n        newv.local_autocor = self.local_autocor.copy();\n        newv.sampling_rate = self.sampling_rate;\n        return newv;\n\n    @staticmethod\n    def FromEvent(e):\n        if(isinstance(e,VisualBeat)):\n            return e.clone();\n        else:\n            return VisualBeat(start=e.start, type=e.type, weight=e.weight, index=e.index);\n\n    @staticmethod\n    def time_window_func(max_separation, break_on_cuts=None):\n        def window_func(a, b):\n            if(break_on_cuts and (a.type=='cut' or b.type=='cut')):\n                return False;\n            if(np.fabs(a.start-b.start)<max_separation):\n                return True;\n            else:\n                return False;\n        return window_func;\n\n    @staticmethod\n    def tempo_binary_objective(target_period, binary_weight=None):\n        if(binary_weight is None):\n            binary_weight = 1.0;\n        def objective_func(a, b):\n            T = np.fabs(a.start-b.start);\n            return -np.power(np.log(truediv(T,target_period)), 2.0)*binary_weight;\n        return objective_func;\n\n    @staticmethod\n    def autocor_binary_objective(binary_weight=None, **kwargs):\n        if (binary_weight is None):\n            binary_weight = 1.0;\n\n        def objective_func(a, b):\n            T = np.fabs(a.start - b.start);\n\n            # assert(a.sampling_rate), \"b has no sampling rate\"\n            # assert(b.sampling_rate), \"a has no sampling rate\"\n            abin = int(round(np.true_divide(T,a.sampling_rate)));\n            score = (a.local_autocor[abin] - 1);\n            if (T < 0.25):\n                score = -1;\n            if(T>3.75):\n                score=-1;\n            return binary_weight*score;\n\n        return objective_func;\n\n    @staticmethod\n    def angle_binary_objective(binary_weight=None, absolute=None):\n        if (binary_weight is None):\n            binary_weight = 1.0;\n        # if (angle_weight is None):\n        #     angle_weight = 0.0;\n\n        def objective_func(a, b):\n            # T = np.fabs(a.start - b.start);\n            # tempo_score = -np.power(np.log(truediv(T, target_period)), 2.0) * binary_weight;\n            # should mask out unary contribution from orthogonal angles\n            if(absolute):\n                return binary_weight * (np.fabs(np.dot(a.flow_histogram, b.flow_histogram)) - 0.70710678118);  # cos 45 degrees\n            else:\n                return binary_weight * (np.dot(a.flow_histogram, b.flow_histogram));  # cos 45 degrees\n        return objective_func;\n\n    @staticmethod\n    def Double(events, type=None):\n        doubled = [];\n        for e in range(1, len(events)):\n            halfstart = 0.5 * (events[e].start + events[e - 1].start);\n            newhevent = events[e].clone(start=halfstart);\n            if(type is not None):\n                newhevent.type = type;\n            doubled.append(newhevent);\n            doubled.append(events[e]);\n        return doubled;\n\n    @staticmethod\n    def weight_unary_objective(unary_weight=None):\n        if(unary_weight is None):\n            unary_weight = 1.0;\n        def getweight_func(b):\n            return unary_weight*b.weight;\n        return getweight_func;\n\n    @staticmethod\n    def PullOptimalPaths_Basic(vis_beats, target_period, unary_weight=None, binary_weight=None, window_size=None, break_on_cuts = None):\n        if(window_size is None):\n            window_size = DEFAULT_WINDOW_FACTOR*target_period;\n        binary_objective = VisualBeat.tempo_binary_objective(target_period=target_period, binary_weight = binary_weight);\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation = window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def PullOptimalPaths(vis_beats, unary_fn=None, binary_fn=None, window_fn=None,  target_period=None, unary_weight=None, binary_weight=None, window_size=None,\n                               break_on_cuts=None):\n        if (window_size is None):\n            window_size = DEFAULT_WINDOW_FACTOR * target_period;\n\n        if(binary_fn == 'autocor'):\n            binary_objective = VisualBeat.autocor_binary_objective(binary_weight=binary_weight);\n        elif(binary_fn == 'angle'):\n            binary_objective = VisualBeat.angle_binary_objective(binary_weight=binary_weight);\n        else:\n            binary_objective = VisualBeat.tempo_binary_objective(target_period=target_period, binary_weight=binary_weight);\n\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation=window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def PullOptimalPaths_Autocor(vis_beats, unary_weight=None, binary_weight=None, window_size=None,\n                               break_on_cuts=None, **kwargs):\n        if (window_size is None):\n            # assert(False), 'no window size provided'\n            # window_size = DEFAULT_WINDOW_FACTOR * target_period;\n            window_size = 200;\n            AWARN('NO WINDOWSIZE PROVIDED! PullOptimalPaths_Autocor');\n        binary_objective = VisualBeat.autocor_binary_objective(binary_weight=binary_weight);\n        unary_objective = VisualBeat.weight_unary_objective(unary_weight=unary_weight);\n        window_function = VisualBeat.time_window_func(max_separation=window_size, break_on_cuts=break_on_cuts);\n        return VisualBeat.DynamicProgramOptimalPaths(vis_beats=vis_beats,\n                                                     unary_objective_func=unary_objective,\n                                                     binary_objective_func=binary_objective,\n                                                     window_func=window_function);\n\n    @staticmethod\n    def DynamicProgramOptimalPaths(vis_beats, unary_objective_func, binary_objective_func, window_func):\n        class Node(object):\n            def __init__(self, object, prev_node=None):\n                self.object = object;\n                self.prev_node = prev_node;\n                self.cum_score=None;\n\n        nodes = [];\n        beats = Event.GetSorted(vis_beats);\n        Event.ApplyIndices(beats);\n\n        for b in beats:\n            nodes.append(Node(object=b));\n\n        nodes[0].prev_node = None;\n        nodes[0].cum_score = unary_objective_func(nodes[0].object);\n        current_segment = [];\n        segments = [];\n        for n in range(1,len(nodes)):\n            current_node = nodes[n];\n            current_segment.append(current_node);\n            options = [];\n            j = n-1;\n            while(j>=0 and window_func(current_node.object,nodes[j].object)):\n                options.append(nodes[j]);\n                j = j-1;\n            if(len(options)==0):\n                current_node.prev_node=None;\n                current_node.cum_score=unary_objective_func(current_node.object);\n                segments.append(current_segment);\n                current_segment = [];\n            else:\n                best_choice = options[0];\n                best_score = options[0].cum_score+binary_objective_func(current_node.object, best_choice.object);\n                for o in range(1,len(options)):\n                    score = options[o].cum_score+binary_objective_func(current_node.object, options[o].object);\n                    if(score>best_score):\n                        best_choice=options[o];\n                        best_score=score;\n                current_node.prev_node = best_choice;\n                current_node.cum_score = best_score+unary_objective_func(current_node.object);\n        if(len(current_segment)>0):\n            segments.append(current_segment);\n        sequences = [];\n        for S in segments:\n            seq = [];\n            max_node = S[0];\n            max_score = max_node.cum_score;\n            for n in range(len(S)):\n                if(S[n].cum_score>max_score):\n                    max_node = S[n];\n                    max_score = max_node.cum_score;\n\n            trace_node = max_node;\n            while(trace_node.prev_node is not None):\n                seq.append(trace_node.object);\n                trace_node=trace_node.prev_node;\n            seq.reverse();\n            sequences.append(seq);\n\n        return sequences;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/Warp.py",
    "content": "\n\nfrom .VisBeatImports import *\nfrom .EventList import *\nimport math\n\nDEFAULT_LEAD_TIME = 0;\nDEFAULT_TAIL_TIME = 0;\n\nclass Warp(AObject):\n    \"\"\"Warp (class): defines how one time signal should be warped to another. Given primarily as source/target events to be matched.\n        Attributes:\n            source_events: source events\n            target_events: target events\n    \"\"\"\n\n    def VBOBJECT_TYPE(self):\n        return 'Warp';\n\n    def __init__(self, path=None):\n        AObject.__init__(self, path=path);\n        if(path):\n            self.loadFile();\n\n\n    @staticmethod\n    def FromEvents(source_events, target_events):\n        w = Warp();\n        sevents = source_events;\n        if(isinstance(source_events, EventList)):\n            sevents = source_events.events;\n\n        tevents = target_events;\n        if(isinstance(target_events, EventList)):\n            tevents = target_events.events;\n\n        w.source_events=sevents;\n        w.target_events=tevents;\n        # w.repeatShorterEvents();\n        return w\n\n    @staticmethod\n    def FromEventLists(source_eventlist, target_eventlist):\n        w = Warp();\n        w.source_events = source_eventlist.events;\n        w.target_events = target_eventlist.events;\n        # w.repeatShorterEvents();\n        return w\n\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self.source_events = [];\n        self.target_events = [];\n        # self.a_info['WarpType'] = 'Linear';\n        self.warp_func = None;  # Warp.LinearInterp;\n        # self.warp_func_st = None;\n        # self.warp_func_ts = None;\n\n\n    def getTargetStart(self, lead=None):\n        target_start = self.target_events[0].getStartTime();\n        if (lead is None):\n            lead = min(target_start, DEFAULT_LEAD_TIME);\n        return target_start - lead;\n\n\n    def getTargetEnd(self, lead=None):\n        lastind = min(len(self.source_events), len(self.target_events)) - 1;\n        return self.target_events[lastind].getStartTime() + DEFAULT_TAIL_TIME;\n\n\n    def getSourceStart(self):\n        source_start = self.source_events[0].getUnrolledStartTime();\n        return source_start;\n\n\n    def getSourceEnd(self):\n        lastind = min(len(self.source_events), len(self.target_events)) - 1;\n        return self.source_events[lastind].getUnrolledStartTime();\n\n\n    def getWarpedSourceStart(self, lead=None):\n        source_start = self.source_events[0].getUnrolledStartTime();\n        if (lead is None):\n            lead = min(source_start, DEFAULT_LEAD_TIME);\n        return self.warpSourceTime(source_start - lead);\n\n\n    def getWarpedSourceEnd(self, tail=None):\n        last_event = min(len(self.source_events), len(self.target_events)) - 1;\n        source_end = self.source_events[last_event].getUnrolledStartTime();\n        if (tail is None):\n            tail = DEFAULT_TAIL_TIME;\n        source_end = source_end + tail;\n        return self.warpSourceTime(source_end);\n\n\n    def setWarpFunc(self, warp_type, **kwargs):\n        if (warp_type == 'square'):\n            self.warp_func = [Warp.SquareInterp, Warp.SquareInterp];\n        elif (warp_type == 'linear'):\n            self.warp_func = [Warp.LinearInterp, Warp.LinearInterp];\n        elif (warp_type == 'cubic'):\n            self.warp_func = [Warp.CubicInterp, Warp.CubicInterp];\n        elif (warp_type == 'quad'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_Quadratic(), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_Quadratic(), **kwargs)];\n        elif (warp_type == 'mouth'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_Mouth(**kwargs), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_Mouth(**kwargs), **kwargs)];\n        elif (warp_type == 'weight'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_Weight(use_to_weights=None, **kwargs), **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_Weight(use_to_weights=True, **kwargs), **kwargs)];\n        elif (warp_type == 'half_accel'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_P(p=0.5),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_P(p=0.5),\n                                      **kwargs)];\n        elif (warp_type == 'p'):\n            p = kwargs.get('p');\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events, Warp.WFunc_P(p=p),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events, Warp.WFunc_P(p=p),\n                                      **kwargs)];\n        elif (warp_type == 'target_time_source_fraction'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_targettime_sourcefraction(**kwargs),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_targettime_sourcefraction(**kwargs),\n                                      **kwargs)];\n        elif (warp_type == 'target_source_fractions'):\n            self.warp_func = [\n                Warp.GetEventWarpFunc(self.source_events, self.target_events,\n                                      Warp.WFunc_target_source_fractions(**kwargs),\n                                      **kwargs),\n                Warp.GetEventWarpFunc(self.target_events, self.source_events,\n                                      Warp.WFunc_target_source_fractions(**kwargs),\n                                      **kwargs)];\n        elif (warp_type is not None):\n            self.warp_func = [warp_type, warp_type];\n\n        self.setInfo('WarpType', warp_type);\n        return;\n\n\n    def warpSourceTime(self, t):\n        return self.warp_func[0](t, a_events=self.source_events, b_events=self.target_events);\n\n\n    def warpSourceTimes(self, t):\n        tw = t.copy();\n        for a in range(len(t)):\n            tw[a] = self.warpSourceTime(t[a]);\n        return tw;\n\n\n    def warpTargetTime(self, t):\n        return self.warp_func[1](t, a_events=self.target_events, b_events=self.source_events);\n\n\n    def warpTargetTimes(self, t):\n        tw = t.copy();\n        for a in range(len(t)):\n            tw[a] = self.warpTargetTime(t[a]);\n        return tw;\n\n\n    def plot(self, xlim=None, sampling_rate=None, new_figure=None, render_control_points=True, render_labels=True,\n             time_range=None, full_source_range=None, **kwargs):\n        if (sampling_rate is None):\n            sampling_rate = 30;\n\n        source_duration = self.getSourceEnd() - self.getSourceStart();\n        old_frame_time = truediv(1.0, sampling_rate);\n        target_start = self.getTargetStart();\n        target_end = self.getTargetEnd();\n\n\n\n        # if(xlim is not None):\n        #     target_start=xlim[0]\n\n        target_duration = target_end - target_start;\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=False);\n\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(self.warpTargetTime(st));\n\n        if (new_figure):\n            fig = plt.figure();\n\n        unwarped_target_times = np.array(unwarped_target_times);\n        # unwarped_target_times = unwarped_target_times-unwarped_target_times[0]+target_start;\n        plt.plot(target_start_times, unwarped_target_times, '-');\n\n        if (render_control_points):\n            lastind = min(len(self.source_events), len(self.target_events)) - 1;\n            targeteventtimes = Event.ToStartTimes(self.target_events[:lastind]);\n            sourceeventtimes = Event.ToStartTimes(self.source_events[:lastind]);\n            plt.plot(targeteventtimes, sourceeventtimes, 'o', label='Control Points');\n        if (xlim is not None):\n            xrng = [xlim[0] + target_start, xlim[1] + target_start];\n            ylim = [self.warpTargetTime(xrng[0]), self.warpTargetTime(xrng[1])];\n            plt.xlim(xrng);\n            plt.ylim(ylim);\n\n        if (time_range is not None):\n            plt.xlim(time_range);\n\n        if (render_labels):\n            plt.ylabel('Source Time');\n            plt.xlabel('Target Time');\n\n        plt.title('Warp Curve')\n\n        if (new_figure is not None):\n            return fig;\n\n\n    def plotImage(self, xlim=None, sampling_rate=None):\n        if (sampling_rate is None):\n            sampling_rate = 30;\n        target_start = self.getTargetStart();\n        target_end = self.getTargetEnd() + 10;\n        target_duration = target_end - target_start;\n\n        new_n_samples = target_duration * sampling_rate;\n        target_start_times = np.linspace(target_start, target_end, num=new_n_samples, endpoint=True);\n\n        unwarped_target_times = [];\n        for st in target_start_times:\n            unwarped_target_times.append(self.warpTargetTime(st));\n\n        unwarped_target_times = np.array(unwarped_target_times);\n        pim = Image.PlotImage(signal=unwarped_target_times, show_axis=True, xvals=target_start_times,\n                              sampling_rate=sampling_rate, events=self.target_events, xlime=[0, 100], ylims=[0, 110]);\n        return pim;\n\n\n    def repeatShorterEvents(self, endpoints=False):\n        n_events = max(len(self.source_events), len(self.target_events));\n        self.source_events = Event.RepeatToLength(self.source_events, n=n_events, endpoints=endpoints);\n        self.target_events = Event.RepeatToLength(self.target_events, n=n_events, endpoints=endpoints);\n\n\n    @staticmethod\n    def FromEvents(source_events, target_events):\n        w = Warp();\n        w.source_events = source_events;\n        w.target_events = target_events;\n        # w.repeatShorterEvents();\n        return w\n\n\n    @staticmethod\n    def LinearInterp(t, a_events, b_events):\n        n_events = min(len(a_events), len(b_events));\n        next_a_event_index = n_events;\n        for s in range(n_events):\n            if (t < a_events[s].start):\n                next_a_event_index = s;\n                break;\n\n        prev_a_event_time = 0;\n        prev_b_event_time = 0;\n        if (next_a_event_index > 0):\n            prev_a_event_time = a_events[next_a_event_index - 1].start;\n            prev_b_event_time = b_events[next_a_event_index - 1].start;\n\n        next_a_event_time = a_events[n_events - 1].start;\n        next_b_event_time = b_events[n_events - 1].start;\n        if (next_a_event_index < n_events):\n            next_a_event_time = a_events[next_a_event_index].start;\n            next_b_event_time = b_events[next_a_event_index].start;\n\n        a_event_gap = next_a_event_time - prev_a_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_a_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (a_event_gap == 0):\n            return prev_b_event_time + t_progress;\n\n        next_weight = t_progress / (1.0 * a_event_gap);\n        return (next_weight * next_b_event_time) + ((1.0 - next_weight) * prev_b_event_time);\n\n\n    # additional_points = [];\n    # for i in range(-10, 11):\n    #     additional_points.append([0.1 * i, 0.51])\n    @staticmethod\n    def plotWarpMethodTest(warp_type, additional_points=None, **kwargs):\n        sev = [];\n        tev = [];\n\n        pts = [[1.0, 1.0],\n               [-1.0, 1.0],\n               [0.5, 1.0],\n               [1.0, 0.5],\n               [-1.0, 0.5],\n               [0.5, 0.5],\n               [1.0, 0.3],\n               [-1.0, 0.3],\n               [0.5, 0.3]];\n\n        if (additional_points is not None):\n            pts = pts + additional_points;\n\n        currentt = [0.0, 0.0];\n        sev.append(Event(start=0.0));\n        tev.append(Event(start=0.0));\n        for p in pts:\n            currentt[0] = currentt[0] + p[0];\n            currentt[1] = currentt[1] + p[1];\n            sev.append(Event(start=currentt[0]));\n            tev.append(Event(start=currentt[1]));\n\n        # warp_type = 'target_time_source_fraction';\n        # other_params['acceleration_target_time'] = 0.5;\n        # other_params['acceleration_source_fraction'] = 0.75;\n        warpf = Warp.FromEvents(sev, tev);\n        warpf.setWarpFunc(warp_type, **kwargs);\n\n        warpf.plot()\n\n\n    @staticmethod\n    def SquareInterp(t, a_events, b_events):\n        n_events = min(len(a_events), len(b_events));\n        next_a_event_index = n_events;\n        for s in range(n_events):\n            if (t < a_events[s].start):\n                next_a_event_index = s;\n                break;\n\n        prev_a_event_time = 0;\n        prev_b_event_time = 0;\n        if (next_a_event_index > 0):\n            prev_a_event_time = a_events[next_a_event_index - 1].start;\n            prev_b_event_time = b_events[next_a_event_index - 1].start;\n\n        next_a_event_time = a_events[n_events - 1].start;\n        next_b_event_time = b_events[n_events - 1].start;\n        if (next_a_event_index < n_events):\n            next_a_event_time = a_events[next_a_event_index].start;\n            next_b_event_time = b_events[next_a_event_index].start;\n\n        a_event_gap = next_a_event_time - prev_a_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_a_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (a_event_gap == 0):\n            return prev_b_event_time + t_progress;\n\n        progress_frac = t_progress / (1.0 * a_event_gap);\n        next_weight = math.pow(progress_frac, 2);\n        # accel = 3;\n        # bweight = math.pow(progress_frac,accel);\n        # aweight = math.pow(1.0-progress_frac,accel);\n        # sumweight = aweight+bweight;\n        # next_weight=bweight/sumweight;\n        return (next_weight * next_b_event_time) + ((1.0 - next_weight) * prev_b_event_time);\n\n\n    @staticmethod\n    def GetEventWarpFunc(from_events, to_events, f, lead_time=None, **kwargs):\n        start_cap_time = min(from_events[0].start, to_events[0].start);\n        if (lead_time is not None):\n            start_cap_time = min(start_cap_time, lead_time);\n        n_events = min(len(from_events), len(to_events));\n        # f_events = Event.GetUnrolledList(from_events[:n_events], assert_on_folds=True);\n        f_events = Event.GetUnrolledList(from_events[:n_events]);\n        t_events = Event.GetUnrolledList(to_events[:n_events]);\n\n        def rfunc(t, **kwargs):\n            next_f_event_index = n_events - 1;\n            for e in range(n_events):\n                if (t < f_events[e].unrolled_start):\n                    next_f_event_index = e;\n                    break;\n\n            if (next_f_event_index == 0):\n                from_cap_event = Event(start=f_events[0].start - start_cap_time, weight=0, type='startcap');\n                to_cap_event = Event(start=t_events[0].start - start_cap_time, weight=0, type='startcap')\n                return f(t, f_neighbors=[from_cap_event, f_events[0]], t_neighbors=[to_cap_event, t_events[0]]);\n\n            else:\n                return f(t,\n                         f_neighbors=[f_events[next_f_event_index - 1], f_events[next_f_event_index]],\n                         t_neighbors=[t_events[next_f_event_index - 1], t_events[next_f_event_index]]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Quadratic():\n        def rfunc(t, f_neighbors, t_neighbors, **kwargs):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            next_weight = math.pow(progress_frac, 2);\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Weight(use_to_weights=None, **kwargs):\n        print(\"USING WEIGHT-BASED WARP\");\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            if (use_to_weights):\n                weight = t_neighbors[1].weight;\n            else:\n                weight = f_neighbors[1].weight;\n\n            p = 1.0 - weight;\n            # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n            a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n            if (progress_frac < p):\n                next_weight = a * progress_frac;\n            else:\n                next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_P(p=None, **kwargs):\n        if (p is None):\n            p = 0.5;\n        print((\"USING P WARP with P={}\".format(p)));\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n            # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n            a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n            if (progress_frac < p):\n                next_weight = a * progress_frac;\n            else:\n                next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_Mouth(p_acceleration_time=0.1, **kwargs):\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            if (f_neighbors[1].type == 'mouth_open' or t_neighbors[1].type == 'mouth_open'):\n                p = 1.0 - truediv(p_acceleration_time, to_event_gap);\n                if (p < 0):\n                    next_weight = math.pow(progress_frac, 2);\n                else:\n                    # a = truediv(1.0, (1.0+p*p-2*p)); # if a=b\n                    a = 1.0 - np.power((1.0 - p), 2.0);  # b=1\n                    if (progress_frac < p):\n                        next_weight = a * progress_frac;\n                    else:\n                        next_weight = (a * progress_frac) + np.power((progress_frac - p), 2.0);\n            else:\n                next_weight = progress_frac;\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_targettime_sourcefraction(acceleration_target_time=0.1, acceleration_source_fraction=0.8, **kwargs):\n        \"\"\"\n        This assumes that you are mapping from the target to the source, as is the most common use case.\n        :param acceleration_target_time: amount of from time to spend accelerating\n        :param acceleration_source_fraction: fraction of source to accelerate through\n        :return:\n        \"\"\"\n        lin_source_fraction = 1.0 - acceleration_source_fraction;\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return to_times[\n                           0] + t_progress;  # is this right? doesnt seem to come up, not sure what behavior should be looking back on it...\n\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            time_left = from_event_gap - t_progress;\n\n            p = 1.0 - truediv(acceleration_target_time, from_event_gap);\n            p2 = p * p;\n            q = 1.0 - acceleration_source_fraction;\n\n            if (acceleration_target_time >= from_event_gap or q > (p2)):\n                next_weight = math.pow(progress_frac, 2);\n            elif (time_left >= acceleration_target_time):\n                lin_t_progress_frac = truediv(t_progress, from_event_gap - acceleration_target_time);\n                next_weight = lin_t_progress_frac * lin_source_fraction;\n            else:\n                pdnom = (p2 - 2.0 * p + 1.0)\n\n                # I just used matlab to symbolic inverse matrix of equations, then simplified by hand\n                a = ((1.0 - q) / pdnom) + (q / (p * (p - 1)));\n                b = ((2 * p * (q - 1)) / pdnom) - ((q * (p + 1)) / (p2 - p))\n                # c = ((p2 - (q * (2 * p - 1))) / pdnom) + (q / (p - 1));\n                c = 1 - a - b;\n\n                next_weight = a * progress_frac * progress_frac + b * progress_frac + c;\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_target_source_fractions(acceleration_target_fraction=0.8, acceleration_source_fraction=0.9, **kwargs):\n        \"\"\"\n        This assumes that you are mapping from the target to the source, as is the most common use case.\n        :param acceleration_target_fraction: fraction of target to spend accelerating\n        :param acceleration_source_fraction: fraction of source to accelerate through\n        :return:\n        \"\"\"\n        lin_source_fraction = 1.0 - acceleration_source_fraction;\n\n\n\n        def rfunc(t, f_neighbors, t_neighbors):\n            print(acceleration_target_fraction)\n            print(acceleration_source_fraction)\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            to_event_gap = to_times[1] - to_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return to_times[\n                           0] + t_progress;  # is this right? doesnt seem to come up, not sure what behavior should be looking back on it...\n\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            time_left = from_event_gap - t_progress;\n\n            p = 1.0 - acceleration_target_fraction;\n            p2 = p * p;\n            q = 1.0 - acceleration_source_fraction;\n\n            if (acceleration_target_fraction >= 1 or q > (p2)):\n                next_weight = math.pow(progress_frac, 2);\n            elif (progress_frac <= p):\n                lin_t_progress_frac = truediv(t_progress, p * from_event_gap);\n                next_weight = lin_t_progress_frac * lin_source_fraction;\n            else:\n                pdnom = (p2 - 2.0 * p + 1.0)\n\n                # I just used matlab to symbolic inverse matrix of equations, then simplified by hand\n                a = ((1.0 - q) / pdnom) + (q / (p * (p - 1)));\n                b = ((2 * p * (q - 1)) / pdnom) - ((q * (p + 1)) / (p2 - p))\n                # c = ((p2 - (q * (2 * p - 1))) / pdnom) + (q / (p - 1));\n                c = 1 - a - b;\n\n                next_weight = a * progress_frac * progress_frac + b * progress_frac + c;\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n        return rfunc;\n\n\n    @staticmethod\n    def WFunc_AB(const_factor, quad_factor, **kwargs):\n        def rfunc(t, f_neighbors, t_neighbors):\n            from_times = Event.ToStartTimes(f_neighbors);\n            to_times = Event.ToStartTimes(t_neighbors);\n            from_event_gap = from_times[1] - from_times[0];\n            t_progress = t - from_times[0];\n            # avoid divide by 0\n            if (from_event_gap == 0):\n                AWARN(\"Event Gap was 0! Check Warp.py\")\n                return prev_to_event_time + t_progress;\n            progress_frac = truediv(t_progress, from_event_gap);\n\n            next_weight = math.pow(progress_frac, 2);\n\n            return (next_weight * to_times[1]) + ((1.0 - next_weight) * to_times[0]);\n\n\n    @staticmethod\n    def ABWarp():\n        next_from_event_time = from_events[n_events - 1].start;\n        next_to_event_time = to_events[n_events - 1].start;\n        if (next_from_event_index < n_events):\n            next_from_event_time = from_events[next_from_event_index].start;\n            next_to_event_time = to_events[next_to_event_index].start;\n\n        from_event_gap = next_from_event_time - prev_from_event_time;\n        # b_event_gap = next_b_event_time - prev_b_event_time;\n        t_progress = t - prev_from_event_time;\n\n        # take care of past-the-end case, by simply letting time proceed normally past the last event\n        if (from_event_gap == 0):\n            return prev_to_event_time + t_progress;\n\n        progress_frac = t_progress / (1.0 * from_event_gap);\n        next_weight = math.pow(progress_frac, 2);\n        return (next_weight * next_to_event_time) + ((1.0 - next_weight) * prev_to_event_time);\n\n\n    @staticmethod\n    def CubicInterp(t, a_events, b_events):\n        # def CubicInterp(a_events, b_events, t):\n        f = Warp.CubicInterpFunc(a_events=a_events, b_events=b_events);\n        return f(t);\n\n\n    @staticmethod\n    def LinearInterpFunc(a_events, b_events):\n        if (a_events[0].start > 0):\n            ae = np.concatenate((np.asarray([0]), Event.ToStartTimes(a_events)));\n        else:\n            ae = Event.ToStartTimes(a_events);\n        be = Event.ToStartTimes(b_events);\n        if (len(be) > len(ae)):\n            be = be[:len(ae)];\n        elif (len(ae) > len(be)):\n            ae = ae[:len(be)];\n        return sp.interpolate.interp1d(ae, be, 'linear', bounds_error=False, fill_value='extrapolate');\n\n\n    @staticmethod\n    def CubicInterpFunc(a_events, b_events):\n        event_times = Event.ToStartTimes(a_events);\n        wevent_times = Event.ToStartTimes(b_events);\n        minlen = min(len(event_times), len(wevent_times));\n        event_times = event_times[:minlen];\n        wevent_times = wevent_times[:minlen];\n        splinecap = np.arange(0, 1, 0.25);\n\n        spline_times = np.concatenate((splinecap + event_times[0] - 1, event_times));\n        wspline_times = np.concatenate((splinecap + wevent_times[0] - 1, wevent_times));\n\n        spline_times = np.append(spline_times, splinecap + 0.5 + spline_times[-1]);\n        wspline_times = np.append(wspline_times, splinecap + 0.5 + wspline_times[-1]);\n\n        # get spline to translate initial times to warped times\n        splineX = sp.interpolate.interp1d(spline_times, wspline_times, kind='cubic', bounds_error=False,\n                                          fill_value='extrapolate');\n        return splineX;\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/__init__.py",
    "content": "\nfrom .VisBeatImports import *\nfrom .Video import *\nfrom .VideoClip import *\nfrom .VideoSource import *\nfrom .VisBeatExampleVideo import VisBeatExampleVideo\nimport re\nimport os;\nimport shutil\n\n\nfrom .SourceLocationParser import ParseSourseLocation\n\nVISBEAT_ASSETS_DIR = './VisBeatAssets/';\n\nfrom . import fileui\nfileui.INITIAL_DIR = VISBEAT_ASSETS_DIR;\n\n\ndef SetAssetsDir(assets_dir):\n    global VISBEAT_ASSETS_DIR;\n    VISBEAT_ASSETS_DIR = assets_dir;\n    make_sure_dir_exists(assets_dir);\n    AINFORM(\"VISBEAT_ASSETS_DIR set to {}\".format(VISBEAT_ASSETS_DIR));\n    make_sure_dir_exists(GetVideoSourcesDir());\n    temp_dir = os.path.join(VISBEAT_ASSETS_DIR, 'TEMP_FILES'+os.sep);\n    make_sure_dir_exists(temp_dir);\n    Video.VIDEO_TEMP_DIR = temp_dir;\n    fileui.INITIAL_DIR = VISBEAT_ASSETS_DIR;\n\ndef GetAssetsDir():\n    return VISBEAT_ASSETS_DIR;\n\ndef GetVideoSourcesDir():\n    video_sources_dir = os.path.join(GetAssetsDir(), 'VideoSources'+os.sep);\n    make_sure_dir_exists(video_sources_dir);\n    return video_sources_dir;\n\ndef PullVideo(name=None, source_location=None, max_height=240, **kwargs):\n    if(isinstance(name, VisBeatExampleVideo)):\n        assert(source_location is None), 'Provided VisBeatExampleVideo and source location? What are you trying to do?';\n        source_location = name.url;\n        vname = name.name;\n    elif(name is None):\n        assert(source_location is not None), \"Must provide an argument to pullvideo\";\n        sloc = ParseSourseLocation(source_location);\n        vname =sloc.code;\n    else:\n        vname = name;\n\n    vs = GetVideoSource(vname);\n    if(vs and vs.source_location==source_location):\n        v = vs.getVersion(max_height=max_height);\n        v.load(features_to_load = 'all');\n        return v;\n    \n    print(\"destination:\", GetVideoSourcesDir(), \"name:\", vname, \"source_location:\", source_location)\n    vs = VideoSource.NewVideoSource(destination=GetVideoSourcesDir(), name=vname, source_location=source_location, max_height=max_height, **kwargs);\n    v = vs.getVersion(max_height=max_height);\n    return v;\n\ndef ClipVideo(video, time_range, max_height=240):\n    video_fullres = video.source.getVersion();\n    vclip = video_fullres.VideoClip(start=time_range[0], end=time_range[1]);\n    vcdir = video.source.getDirForVersion(version_label='{}_{}'.format(str(time_range[0]), str(time_range[1])), version_group='Clips');\n    make_sure_dir_exists(vcdir);\n    vcname = video.getName() + 'clip_{}_{}'.format(str(time_range[0]), str(time_range[1]));\n    vcpath = os.path.join(vcdir, vcname+'.mp4');\n    vclip.write(output_path=vcpath);\n    vs = VideoSource.NewVideoSource(destination=GetVideoSourcesDir(), name=vcname, source_location=vcpath);\n    return vs.getVersion(max_height=max_height);\n\n\ndef GetVideoSource(name):\n    vname = name;\n    if (isinstance(name, VisBeatExampleVideo)):\n        vname = name.name;\n    path = os.path.join(GetVideoSourcesDir(), vname) + os.sep;\n    if (os.path.isdir(path)):\n        return VideoSource(path=path);\n\ndef LoadVideo(name, max_height=240):\n    vname = name;\n    if (isinstance(name, VisBeatExampleVideo)):\n        vname = name.name;\n\n    path = os.path.join(GetVideoSourcesDir(), vname)+os.sep;\n    if(os.path.isdir(path)):\n        vs = VideoSource(path=path);\n        v = vs.getVersion(max_height=max_height);\n        v.load(features_to_load = 'all');\n        return v;\n    else:\n        return None;\n\ndef Dancefer(source_video, target,\n             synch_video_beat=0, synch_audio_beat=0,\n             beat_offset = 0, leadin = None, nbeats=None,\n             source_harmonic = None, target_harmonic = None, source_harmonic_offset=None, target_harmonic_offset=None,\n             force_recompute=None, warp_type = 'quad',\n             name_tag=None, name_tag_prefix=None, output_path = None,\n             **kwargs):\n    \"\"\"\n\n    :param source_video: video to warp\n    :param target: music to warp to\n    :param synch_video_beat: integer specifying a beat (as in the nth beat) from the video to synchronize with synch_audio_beat\n    :param synch_audio_beat: integer specifying a beat (as in the nth beat) from the video to synchronize with synch_video_beat\n    :param beat_offset: Lets you offset which beats you want to render. This is mostly for testing different parts of an output.\n    :param leadin: how many beats before the synch beats to render\n    :param nbeats: lets you restrict output to rendering n beats\n    :param source_harmonic: can be None, 'half', or 'double'. 'half' will use every other beat, which you can offset with source_harmonic_offset. 'double' will add an additional beat between every consecutive beat. update - added 'third' for waltzes.\n    :param target_harmonic: can be None, 'half', or 'double'. 'half' will use every other beat, which you can offset with source_harmonic_offset. 'double' will add an additional beat between every consecutive beat. update - added 'third' for waltzes.\n    :param source_harmonic_offset: optional offset for harmonic\n    :param target_harmonic_offset: optional offset for harmonic\n    :param force_recompute:\n    :param warp_type:\n    :param name_tag:\n    :param name_tag_prefix:\n    :param output_path:\n    :param kwargs:\n    :return:\n    \"\"\"\n\n\n    if((output_path is not None) and (not force_recompute)):\n        if(os.path.exists(output_path)):\n            return Video(output_path);\n\n    if(isinstance(target, Video)):\n        target_audio = target.getAudio();\n    else:\n        target_audio = target;\n\n\n    synchaudio = synch_audio_beat;\n    synchvideo = synch_video_beat;\n    lead_in = leadin;\n    if(lead_in is None):\n        lead_in = min(synchaudio, synchvideo);\n    elif(isinstance(lead_in, str) and lead_in[0]=='<'):\n        # lead_in = min(synchaudio, synchvideo, int(lead_in));\n        lead_in = min(synchaudio, int(lead_in));\n\n    start_audio_beat = synchaudio-lead_in;\n    start_video_beat = synchvideo-lead_in;\n\n    if(beat_offset and beat_offset>0):\n        start_audio_beat = start_audio_beat+beat_offset;\n        start_video_beat = start_video_beat+beat_offset;\n\n    print((\"Warping {} to {}\".format(source_video.getName(), target_audio.getName())));\n    bitrate = None;\n    vbeats = source_video.audio.getBeatEvents()\n    tbeats = target_audio.getBeatEvents()\n\n    if(start_video_beat < 0):\n        if(synchvideo == 0):\n            vbeats = [vbeats[0].clone()]+vbeats;\n            vbeats[0].start = vbeats[0].start-(vbeats[2].start-vbeats[1].start);\n        vbadd = Event.SubdivideIntervals(vbeats[:2], -start_video_beat);\n        vbeats = vbadd+vbeats[2:];\n        start_video_beat = 0;\n\n\n    vbeats = vbeats[start_video_beat:];\n    tbeats = tbeats[start_audio_beat:];\n\n    if(source_harmonic=='half'):\n        vbeats = Event.Half(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'third'):\n        vbeats = Event.Third(vbeats, source_harmonic_offset);\n    elif(source_harmonic == 'double'):\n        vbeats = Event.Double(vbeats);\n\n    if (target_harmonic == 'half'):\n        tbeats = Event.Half(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'third'):\n        tbeats = Event.Third(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'double'):\n        tbeats = Event.Double(tbeats);\n\n\n    if(nbeats):\n        print((\"Rendering {} beats of result\".format(nbeats)))\n        if(len(vbeats)>nbeats):\n            vbeats = vbeats[:nbeats];\n            print((len(vbeats)))\n        if(len(tbeats)>nbeats):\n            tbeats = tbeats[:nbeats];\n            print((len(tbeats)))\n    else:\n        if(vbeats[-1].start<source_video.getDuration()):\n            print(tbeats)\n            print((\"length of tbeats is: {}\".format(len(tbeats))));\n            print((\"start_video_beat: {}, start_audio_beat: {}\".format(start_video_beat, start_audio_beat)))\n            newbeat = vbeats[-1].clone();\n            deltatime = source_video.getDuration()-newbeat.start;\n            newbeat.start = source_video.getDuration();\n            target_newbeat = tbeats[-1].clone();\n            target_newbeat.start = min(target_newbeat.start+deltatime, target_audio.getDuration());\n            tbeats.append(target_newbeat);\n\n    if(warp_type is 'weight'):\n        vbeats = source_video.visualBeatsFromEvents(vbeats);\n\n    if(name_tag is None):\n        name_tag = warp_type+'_sab_'+str(start_audio_beat)+'_svb_'+str(start_video_beat);\n    if(name_tag_prefix is not None):\n        name_tag = name_tag+name_tag_prefix;\n\n    warp_args = dict(target=target_audio,\n                     source_events=vbeats,\n                     target_events = tbeats,\n                     warp_type=warp_type,\n                     force_recompute=force_recompute,\n                     name_tag = name_tag)\n    if(bitrate):\n        warp_args.update(dict(bitrate=bitrate));\n\n    warp_args.update(kwargs);\n    warped_result = source_video.getWarped(**warp_args);\n\n    if(output_path):\n        final_output_path = output_path;\n        if(os.path.isfile(final_output_path)):\n            output_filename = os.path.basename(output_path);\n            name_parts = os.path.splitext(output_filename);\n            output_filename_base = name_parts[0];\n            output_directory_path = os.path.dirname(output_path);\n            if (output_directory_path == ''):\n                output_directory_path = '.'\n            output_ext = name_parts[1];\n            ntry = 1;\n            tryname = output_filename_base+ '_' + str(ntry);\n            while (os.path.isfile(os.path.join(output_directory_path, tryname+output_ext)) and ntry<100):\n                ntry = ntry+1;\n                tryname = output_filename_base + '_' + str(ntry);\n\n            final_output_path = os.path.join(output_directory_path, tryname + output_ext);\n        shutil.copy2(src=warped_result.getPath(), dst=final_output_path);\n        n_frames_total = warped_result.num_frames_total;\n        warp_used = warped_result.getInfo('warp_used');\n        warped_result_final = Video(path = final_output_path, num_frames_total=n_frames_total);\n        warped_result_final.setInfo(label='warp_used', value=warp_used);\n        os.remove(warped_result.getPath())\n        warped_result = warped_result_final;\n    return warped_result;\n\ndef get_temp_file_path(final_file_path=\"TEMP\", temp_dir_path = None):\n    pparts = os.path.split(final_file_path);\n    destfolder = pparts[0]+os.sep;\n    tempdir = temp_dir_path;\n    if(tempdir is None):\n        tempdir='.';\n    destfolder=pathstring(tempdir+os.sep);\n    tempname = 'TEMP_'+pparts[1];\n    temptry = 0;\n    while(os.path.isfile(destfolder+tempname)):\n        temptry=temptry+1;\n        tempname = 'TEMP{}_'.format(temptry)+pparts[1];\n    return pathstring(destfolder+tempname);\n\n\ndef AutoDancefer(source, target, output_path = None, synch_video_beat = 0, synch_audio_beat = 0, beat_offset = 0, **kwargs):\n    sourcev = PullVideo(source_location=source);\n    targetv = PullVideo(source_location=target);\n\n    result =  Dancefer(source_video=sourcev, target=targetv, output_path=output_path, force_recompute = True, synch_audio_beat=synch_audio_beat, synch_video_beat=synch_video_beat, beat_offset=beat_offset,**kwargs)\n    AINFORM(\"\\n\\n\\nResult saved to {}\\n\\n\\n\".format(result.getPath()));\n    return result;\n\n#########\n\n\ndef Dancify(source_video, target,\n            source_beats=None, target_beats=None,\n            synch_video_beat=0, synch_audio_beat=0,\n            beat_offset = 0, leadin = None, nbeats=None,\n            unfold_to_n=None,\n            source_harmonic = None, source_harmonic_offset=None,\n            target_harmonic = None, target_harmonic_offset=None,\n            force_recompute=None, warp_type = 'quad',\n            name_tag=None, name_tag_prefix=None, output_path = None,\n            momentum = 0.1,\n            **kwargs):\n    \"\"\"\n\n    :param source_video:\n    :param target:\n    :param source_beats:\n    :param target_beats:\n    :param synch_video_beat:\n    :param synch_audio_beat:\n    :param beat_offset:\n    :param leadin:\n    :param nbeats:\n    :param unfold_to_n:\n    :param source_harmonic:\n    :param target_harmonic:\n    :param source_harmonic_offset:\n    :param target_harmonic_offset:\n    :param force_recompute:\n    :param warp_type:\n    :param name_tag:\n    :param name_tag_prefix:\n    :param output_path:\n    :param momentum:\n    :param kwargs:\n    :return:\n    \"\"\"\n\n\n    if((output_path is not None) and (not force_recompute)):\n        if(os.path.exists(output_path)):\n            return Video(output_path);\n\n    if(isinstance(target, Video)):\n        target_audio = target.getAudio();\n    else:\n        target_audio = target;\n\n\n    synchaudio = synch_audio_beat;\n    synchvideo = synch_video_beat;\n    lead_in = leadin;\n    if(lead_in is None):\n        lead_in = min(synchaudio, synchvideo);\n    elif(isinstance(lead_in, str) and lead_in[0]=='<'):\n        # lead_in = min(synchaudio, synchvideo, int(lead_in));\n        lead_in = min(synchaudio, int(lead_in));\n\n    start_audio_beat = synchaudio-lead_in;\n    start_video_beat = synchvideo-lead_in;\n\n    if(beat_offset and beat_offset>0):\n        start_audio_beat = start_audio_beat+beat_offset;\n        start_video_beat = start_video_beat+beat_offset;\n\n    print((\"Warping {} to {}\".format(source_video.getName(), target_audio.getName())));\n    bitrate = None;\n    vbeats = source_beats;\n    if(source_beats is None):\n        vbeats = source_video.getVisualBeats();\n\n\n    tbeats = target_beats;\n    if(target_beats is None):\n        tbeats = target_audio.getBeatEvents();\n\n    if(start_video_beat < 0):\n        if(synchvideo == 0):\n            vbeats = [vbeats[0].clone()]+vbeats;\n            vbeats[0].start = vbeats[0].start-(vbeats[2].start-vbeats[1].start);\n        vbadd = Event.SubdivideIntervals(vbeats[:2], -start_video_beat);\n        vbeats = vbadd+vbeats[2:];\n        start_video_beat = 0;\n\n\n    vbeats = vbeats[start_video_beat:];\n    tbeats = tbeats[start_audio_beat:];\n\n    if (source_harmonic == 'half'):\n        vbeats = Event.Half(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'third'):\n        vbeats = Event.Third(vbeats, source_harmonic_offset);\n    elif (source_harmonic == 'double'):\n        vbeats = Event.Double(vbeats);\n\n    if (target_harmonic == 'half'):\n        tbeats = Event.Half(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'third'):\n        tbeats = Event.Third(tbeats, target_harmonic_offset);\n    elif (target_harmonic == 'double'):\n        tbeats = Event.Double(tbeats);\n\n\n    if(nbeats):\n        print((\"Rendering {} beats of result\".format(nbeats)))\n        if(len(vbeats)>nbeats):\n            vbeats = vbeats[:nbeats];\n            print((len(vbeats)))\n\n\n    if(unfold_to_n):\n        vbeats = Event.UnfoldToN(vbeats, unfold_to_n, momentum=momentum);\n\n    if (len(tbeats) > len(vbeats)):\n        tbeats = tbeats[:len(vbeats)];\n\n    if(warp_type is 'weight'):\n        vbeats = source_video.visualBeatsFromEvents(vbeats);\n\n    if(name_tag is None):\n        name_tag = warp_type+'_sab_'+str(start_audio_beat)+'_svb_'+str(start_video_beat);\n    if(name_tag_prefix is not None):\n        name_tag = name_tag+name_tag_prefix;\n\n    warp_args = dict(target=target_audio,\n                     source_events=vbeats,\n                     target_events = tbeats,\n                     warp_type=warp_type,\n                     force_recompute=force_recompute,\n                     name_tag = name_tag)\n    if(bitrate):\n        warp_args.update(dict(bitrate=bitrate));\n\n    warp_args.update(kwargs);\n    warped_result = source_video.getWarped(**warp_args);\n\n    if(output_path):\n        final_output_path = output_path;\n        if(os.path.isfile(final_output_path)):\n            output_filename = os.path.basename(output_path);\n            name_parts = os.path.splitext(output_filename);\n            output_filename_base = name_parts[0];\n            output_directory_path = os.path.dirname(output_path);\n            if (output_directory_path == ''):\n                output_directory_path = '.'\n            output_ext = name_parts[1];\n            ntry = 1;\n            tryname = output_filename_base+ '_' + str(ntry);\n            while (os.path.isfile(os.path.join(output_directory_path, tryname+output_ext)) and ntry<100):\n                ntry = ntry+1;\n                tryname = output_filename_base + '_' + str(ntry);\n\n            final_output_path = os.path.join(output_directory_path, tryname + output_ext);\n        shutil.copy2(src=warped_result.getPath(), dst=final_output_path);\n        n_frames_total = warped_result.num_frames_total;\n        warp_used = warped_result.getInfo('warp_used');\n        warped_result_final = Video(path = final_output_path, num_frames_total=n_frames_total);\n        warped_result_final.setInfo(label='warp_used', value=warp_used);\n        os.remove(warped_result.getPath())\n        warped_result = warped_result_final;\n    return warped_result;\n\n\n\n    def getVBSegments(self,source_video,\n                      source_beats = None,\n                      search_tempo=None,\n                      search_window=None,\n                      max_height=None,\n                      beat_limit=None,\n                      n_return=None,\n                      unary_weight=None,\n                      binary_weight=None,\n                      break_on_cuts=None,\n                      peak_vars=None):\n\n        source = source_video;\n        if(source_beats is None):\n            if (peak_vars is not None):\n                vbeats = source.getFeature('simple_visual_beats', **peak_vars);\n            else:\n                vbeats = source.getFeature('simple_visual_beats');\n        else:\n            vbeats = source_beats;\n\n        #\n\n        if (search_tempo is not None):\n            tempo = search_tempo;\n            beat_time = np.true_divide(60.0, tempo);\n            clips = VisualBeat.PullOptimalPaths_Basic(vbeats, target_period=beat_time, unary_weight=unary_weight,\n                                                      binary_weight=binary_weight, break_on_cuts=break_on_cuts,\n                                                      window_size=search_window);\n        else:\n            clips = VisualBeat.PullOptimalPaths_Autocor(vbeats, unary_weight=unary_weight, binary_weight=binary_weight,\n                                                        break_on_cuts=break_on_cuts, window_size=search_window);\n\n        if (beat_limit is None):\n            beat_limit = 2;\n\n        print((\"There were {} candidates\".format(len(vbeats))));\n        nclips = 0;\n        segments = [];\n\n        for S in clips:\n            if (len(S) > beat_limit):\n                nclips = nclips + 1;\n                segments.append(S);\n\n        if (n_return is not None):\n            segments.sort(key=len, reverse=True);\n            segments = segments[:n_return];\n        return segments;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/_dancefer_examples.py",
    "content": "\n\nfrom .VisBeatExampleVideo import *\nfrom ._music_examples import *\n\n# dances = [];\ndances.append(VisBeatExampleVideo(display_name = 'SNSD: HAHAHA', name='snsd_hahaha', url='https://www.youtube.com/watch?v=OxNsx0eMsGU', start_beat=42));\ndances.append(VisBeatExampleVideo(display_name = 'Boston Dynamics: Spot the Dancing Robot', name='spot_the_dancing_robot', url='https://www.youtube.com/watch?v=kHBcVlqpvZ8', start_beat = 9));\ndances.append(VisBeatExampleVideo(display_name = 'Michael Jackson: Thriller', name = 'thriller', url = 'https://www.youtube.com/watch?v=wlHUJbl-t7o', start_beat = 4))\ndances.append(VisBeatExampleVideo(display_name = 'LMFAO: Party Rock Anthem',name='party_rock', url='https://www.youtube.com/watch?v=WZRMpC_wh0M', start_beat=4, leadin=4))\ndances.append(VisBeatExampleVideo(display_name = 'BTS: Boy in Luv', name='boy_in_luv', url='https://www.youtube.com/watch?v=gqz6Adx63w8', start_beat=34));\ndances.append(VisBeatExampleVideo(display_name = 'Thays Monaro: Redneck Woman',name='gwilson_redneck_woman', url='https://www.youtube.com/watch?v=1apy8YPygKo', start_beat=65))\ndances.append(VisBeatExampleVideo(display_name = 'Music Express: Dancing in the Street', name='dance_cc_dancing_in_the_street', url='https://www.youtube.com/watch?v=fzZ2CoL3IMQ', start_beat=3));\ndances.append(VisBeatExampleVideo(display_name = 'Barney and Friends: Mr. Golden Sun',name='barney_mr_golden_sun', url='https://www.youtube.com/watch?v=ya4yyg9XiI4', start_beat=24))\ndances.append(VisBeatExampleVideo(display_name = 'M. Express: Friends Forever', name='dance_cc_friends_forever', url='https://www.youtube.com/watch?v=T6ZX6wkJ5Ns', start_beat=2));\ndances.append(VisBeatExampleVideo(display_name = 'Just Dance Kids: Gummy Bear',name='jdk_gummy_bear', url='https://www.youtube.com/watch?v=KVE-T2_vLpY', start_beat=60))\ndances.append(VisBeatExampleVideo(display_name = 'M. Express: Feelin Good',name='dance_cc_feelin_good', url='https://www.youtube.com/watch?v=uBWp9rr6w08', start_beat=49));\n# dances.append(VisBeatExampleVideo(display_name = 'Kiesza: Hideaway', name='hideaway', url='https://www.youtube.com/watch?v=Vnoz5uBEWOA', start_beat=124))\ndances.append(VisBeatExampleVideo(display_name = 'SNSD: Genie', name='snsd_genie', url='https://www.youtube.com/watch?v=6SwiSpudKWI', start_beat=141));\ndances.append(VisBeatExampleVideo(display_name = 'Momoland Boom Boom', name='momoland_boom_boom', url='https://www.youtube.com/watch?v=0HKfjsM2hSw', start_beat = 145));#33#\ndances.append(VisBeatExampleVideo(display_name = 'Snap: Rhythm is a Dancer', name='rhythm_is_a_dancer', url='https://www.youtube.com/watch?v=fDWFVI8PQOI', start_beat=65));\ndances.append(VisBeatExampleVideo(display_name = 'Janet Jackson: Rhythm Nation', name='rhythm_nation', url='https://www.youtube.com/watch?v=OAwaNWGLM0c', start_beat = 226));\ndances.append(VisBeatExampleVideo(display_name = 'BTS Just One Day', name='bts_just_one_day', url='https://www.youtube.com/watch?v=KQeAg45p2UI', start_beat=200));\n\n\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n# dances.append(VisBeatExampleVideo(display_name = '', name='', url='', start_beat = ));\n\n\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/_dancify_examples.py",
    "content": "from .VisBeatExampleVideo import *\nfrom ._music_examples import *\n\ndances.append(VisBeatExampleVideo(display_name = 'Turtle', name='turtle', url='https://www.youtube.com/watch?v=PWD4gktEUAY', start_beat=0));\ndances.append(VisBeatExampleVideo(display_name = 'Louie The Cat', name='louie_the_cat', url='https://www.youtube.com/watch?v=hqFG6d86ygI', start_beat=None));\n\n\n\naccidental_dances = [];\naccidental_dances.append(VisBeatExampleVideo(display_name=\"Trump IACP Full\", name=\"trump_iacp_full\", url='https://www.youtube.com/watch?v=pu4dPTi6SEg', target_n_beats = 7))\naccidental_dances.append(VisBeatExampleVideo(display_name=\"Trump Tax Reform WH.gov Full\", name=\"trump_taxreform_remarks_1\", url=\"https://www.youtube.com/watch?v=zB-lhTEQdKY\"))\n# accidental_dances.append(VisBeatExampleVideo(display_name=\"\", name=\"\", url=\"\"))\n\n\nsynth = [];\nsynth.append(VisBeatExampleVideo(name='synth_ball_metronome_w_noise', url = 'https://youtu.be/-mqJIGdro6A', start_beat = None));\nsynth.append(VisBeatExampleVideo(name='synth_test_ball_1', url = 'https://youtu.be/SjXsMYBJEF8', start_beat = None));\nsynth.append(VisBeatExampleVideo(name='synth_test_ball_1_gt_impact_sounds', url = 'https://youtu.be/tsdsQm4iTNg', start_beat = None));\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/_mediafiles.py",
    "content": "import os\n\n\nVB_MEDIA_UTILS_PATH = os.path.abspath(__file__)\nVB_MEDIA_UTILS_DIR = os.path.abspath(os.path.dirname(__file__));\nMEDIAFILES_DIR = os.path.join(VB_MEDIA_UTILS_DIR, 'assets'+os.sep)\n\nAUDIO_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'audio'+os.sep);\nAUDIO_FILES = [];\nAUDIO_FILE_PATHS = {};\nfor filename in os.listdir(AUDIO_FILES_DIR):\n    # if(reduce(lambda x,y: x or y, map(lambda ext: filename.lower().endswith(ext), Audio.MEDIA_FILE_EXTENSIONS()))):\n    AUDIO_FILES.append(filename);\n    AUDIO_FILE_PATHS[filename]=(os.path.join(AUDIO_FILES_DIR, filename));\n\n\ndef GetTestAudioPath(filename):\n    return AUDIO_FILE_PATHS[filename];\n\n\nVIDEO_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'video'+os.sep);\nVIDEO_FILES = [];\nVIDEO_FILE_PATHS = [];\nif(os.path.exists(VIDEO_FILES_DIR)):\n    for filename in os.listdir(VIDEO_FILES_DIR):\n        VIDEO_FILES.append(filename);\n        VIDEO_FILE_PATHS.append(os.path.join(VIDEO_FILES_DIR, filename));\n\n\n\nIMAGE_FILES_DIR = os.path.join(MEDIAFILES_DIR, 'images'+os.sep);\nIMAGE_FILES = [];\nIMAGE_FILE_PATHS = {};\nfor filename in os.listdir(IMAGE_FILES_DIR):\n    IMAGE_FILES.append(filename);\n    IMAGE_FILE_PATHS[filename] = (os.path.join(IMAGE_FILES_DIR, filename));\n\ndef GetTestImagePath(filename=None):\n    if(filename is None):\n        filename = \"VisBeatWatermark.png\"\n    return IMAGE_FILE_PATHS[filename];\n\ndef GetVBMarkPath():\n    return IMAGE_FILE_PATHS[\"VisBeatWatermark.png\"];\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/_music_examples.py",
    "content": "from .VisBeatExampleVideo import *\ndances = [];\n\nmusic = [];\n\nmusic.append(VisBeatExampleVideo(display_name = 'U Cant Touch This', name='cant_touch_this', url='https://www.youtube.com/watch?v=_NNYI8VbFyY', start_beat=2, leadin=2));\nmusic.append(VisBeatExampleVideo(display_name = 'Mary Poppins: Supercalifrag.', name='supercalifrag', url='https://www.youtube.com/watch?v=rihNRTTcztQ', start_beat = 5, leadin = 3));\nmusic.append(VisBeatExampleVideo(display_name = 'Migos: Walk It Talk It',name='walkit_talkit', url='https://www.youtube.com/watch?v=fGqdIPer-ms', start_beat = 134));\nmusic.append(VisBeatExampleVideo(display_name = 'Rammstein: Du Hast',name='du_hast', url = 'https://www.youtube.com/watch?v=W3q8Od5qJio', start_beat = 193));\nmusic.append(VisBeatExampleVideo(display_name = 'Taylor Swift: Shake It Off', name='shake_it_off', url='https://www.youtube.com/watch?v=nfWlot6h_JM', start_beat=112));\nmusic.append(VisBeatExampleVideo(display_name = 'Michael Jackson: Billie Jean', name='billie_jean', url='https://www.youtube.com/watch?v=Zi_XLOBDo_Y', start_beat=169));\nmusic.append(VisBeatExampleVideo(display_name = 'Hall and Oates: You Make My Dreams', name='you_make_my_dreams', url='https://www.youtube.com/watch?v=EErSKhC0CZs', start_beat=95));\nmusic.append(VisBeatExampleVideo(display_name = 'Parry Gripp: Breakfast Burrito',name=\"breakfast_burrito\", url='https://www.youtube.com/watch?v=prPjpwsGiws', start_beat=32))\nmusic.append(VisBeatExampleVideo(display_name = 'Pharrell Williams: Happy',name='happy', url='https://www.youtube.com/watch?v=y6Sxv-sUYtM', start_beat=69, leadin=3))\nmusic.append(VisBeatExampleVideo(display_name = 'Aqua: Barbie Girl',name='barbie_girl', url='https://www.youtube.com/watch?v=ZyhrYis509A', start_beat=67, leadin=4));\nmusic.append(VisBeatExampleVideo(display_name = 'Jhameel: Montage',name='music_cc_jhameel_montage', url='https://www.youtube.com/watch?v=vYr_nCmsgoE', start_beat=103))\nmusic.append(VisBeatExampleVideo(display_name = 'Vengaboys: We like to Party',name='we_like_to_party', url='https://www.youtube.com/watch?v=6Zbi0XmGtMw', start_beat=65))\nmusic.append(VisBeatExampleVideo(display_name = 'Rick Astley: Never Gonna Give You Up', name='rick_roll', url='https://www.youtube.com/watch?v=dQw4w9WgXcQ', start_beat = 3, leadin=3));\nmusic.append(VisBeatExampleVideo(display_name = 'Mark Ronson: Uptown Funk ft. Bruno Mars', name='uptown_funk', url='https://www.youtube.com/watch?v=OPf0YbXqDm0', start_beat=32));\nmusic.append(VisBeatExampleVideo(display_name = 'Missy Elliot: Work It', name='work_it', url='https://www.youtube.com/watch?v=cjIvu7e6Wq8', start_beat=52, leadin = 1));\nmusic.append(VisBeatExampleVideo(display_name = 'If I only had a brain', name='only_had_a_brain', url='https://www.youtube.com/watch?v=nauLgZISozs', start_beat=14));\nmusic.append(VisBeatExampleVideo(display_name = 'Kane Brown: Lose It', name='kb_lose_it', url='https://www.youtube.com/watch?v=Z8nkc2KKjd8', start_beat=56));\n# music.append(VisBeatExampleVideo(display_name = 'Check Meowt', name='pg_check_meowt', url='https://youtu.be/NjKYX4bQpf0', start_beat = 16));\n# music.append(VisBeatExampleVideo(display_name = 'Wu-Tang Clan: Protect Ya Neck', name='wutang_protect_ya_neck', url='https://www.youtube.com/watch?v=R0IUR4gkPIE', start_beat = None));\n# music.append(VisBeatExampleVideo(display_name = 'Ice Cube: It Was A Good Day',name='it_was_a_good_day', url='https://www.youtube.com/watch?v=h4UqMyldS7Q', start_beat=64, harmonic = 'half'));"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/command_line.py",
    "content": ""
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/fileui/__init__.py",
    "content": "\nfrom sys import platform\nif platform == \"linux\" or platform == \"linux2\":\n    PLATFORM = 'linux';\nelif platform == \"darwin\":\n    PLATFORM = 'osx';\nelif platform == \"win32\":\n    PLATFORM = 'windows'\n\nSUPPORTED = False;\n\nINITIAL_DIR ='./';\n\nif(PLATFORM == 'osx'):\n    from . import uipath\n\n    def GetFilePath(initial_path=None):\n        if(initial_path is None):\n            return uipath.uiGetFilePath(initial_path=INITIAL_DIR);\n        else:\n            return uipath.uiGetFilePath(initial_path);\n    def GetDirectory(initial_path=None):\n        if(initial_path is None):\n            return uipath.uiGetDirectory(initial_path=INITIAL_DIR);\n        else:\n            return uipath.uiGetDirectory(initial_path);\n    def GetSaveFilePath(initial_path=None, file_extension = None):\n        if(initial_path is None):\n            return uipath.uiGetSaveFilePath(initial_path=INITIAL_DIR, file_extension=file_extension);\n        else:\n            return uipath.uiGetSaveFilePath(initial_path=initial_path, file_extension=file_extension);\n\n    def Show(path):\n        uipath.showInFinder(path);\n\n    def Open(path):\n        uipath.openOSX(path);\n    SUPPORTED = True;\nelse:\n    def GetFilePath(initial_path=None):\n        return None;\n    def GetDirectory(initial_path=None):\n        return None;\n    def GetSaveFilePath(initial_path=None, file_extension = None):\n        return None;\n    def Show(path):\n        return None;\n    def Open(path):\n        return None;"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/fileui/uipath.py",
    "content": "import os\nimport subprocess\n\n\n\ndef uiGetFilePath(initial_path=None):\n    try:\n        if(initial_path):\n            output = subprocess.check_output(\"osascript -e 'set strPath to POSIX file \\\"{}\\\"' -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\" default location strPath' -e 'set theDocument to (the POSIX path of theDocument)'\".format(initial_path), shell=True)\n        else:\n            output = subprocess.check_output(\"osascript -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\"' -e 'set theDocument to (the POSIX path of theDocument)'\", shell=True)\n        return output.replace('\\n', '');\n    except subprocess.CalledProcessError as e:\n        print((e.output));\n    # assert(False)\n    #     grabpath = get_ipython().run_cell_magic(u'bash', u'', \"osascript -e 'set theDocument to choose file with prompt \\\"Please select a document to process:\\\"' -e 'set theDocument to (the POSIX path of theDocument)'>&2\")\n\ndef uiGetDirectory(initial_path=None):\n    try:\n        if(initial_path):\n            output = subprocess.check_output(\"osascript -e 'set strPath to POSIX file \\\"{}\\\"' -e 'set thedir to choose folder with prompt \\\"Please select a file:\\\" default location strPath' -e 'set thedir to (the POSIX path of thedir)'\".format(initial_path), shell=True)\n        else:\n            output = subprocess.check_output(\"osascript -e 'set thedir to choose folder with prompt \\\"Please select a directory:\\\"' -e 'set thedir to (the POSIX path of thedir)'\", shell=True)\n        return output.replace('\\n', '');\n    except subprocess.CalledProcessError as e:\n        print((e.output));\n    # assert(False)\n\ndef uiGetSaveFilePath(initial_path=None, file_extension=None):\n    try:\n        osastr = \"osascript \";\n        if(initial_path):\n            osastr = osastr+\"-e 'set strPath to POSIX file \\\"{}\\\"' \".format(initial_path);\n        osastr = osastr+\"-e 'set theDocument to choose file name with prompt \\\"Save As File:\\\" \";\n        if(initial_path):\n            osastr = osastr+\"default location strPath\";\n        osastr = osastr+\"' \";\n        osastr = osastr+\"-e 'set theDocument to (the POSIX path of theDocument)'\"\n        output = subprocess.check_output(osastr, shell=True);\n        ostring = output.replace('\\n', '');\n        if (file_extension is not None):\n            if (not ostring.endswith(file_extension)):\n                ostring = ostring + file_extension;\n        return ostring;\n    except subprocess.CalledProcessError as e:\n        AWARN('ERROR')\n        print((e.output));\n\ndef showInFinder(path):\n    return openOSX(get_dir_from_path(path));\n\ndef openOSX(path):\n    return subprocess.check_output(\"open {}\".format(put_string_in_quotes(path)), shell=True);\n\ndef put_string_in_quotes(s):\n    return \"\\\"\"+s+\"\\\"\"\n\ndef get_file_name_from_path(pth):\n    return os.path.split(pth)[1];\n\ndef get_dir_from_path(pth):\n    return (os.path.split(pth)[0]+os.sep);"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/vbgui/BeatGUI.py",
    "content": "from visbeat3.AImports import *\n\nVIEWER_INSTALLED = 1;\ntry:\n    import vbwidget as Viewer\nexcept ImportError as e:\n    VIEWER_INSTALLED = 0;\n    AWARN(\"VBViewer not installed. Consider installing for full functionality.\")\n\nfrom ..TimeSignal import *\nfrom ..EventList import *\n\n\n\n#this is what media should call to get its gui object\ndef media_GUI_func(self):\n    if (self._gui is None):\n        self._gui = BeatGUI();\n        self._gui.media = self;\n    return self._gui;\n\nclass BeatGUI(AObject):\n    \"\"\"\n\n    \"\"\"\n    def AOBJECT_TYPE(self):\n        return 'BeatGUI';\n\n    def __init__(self, media=None, path=None, clear_temp=None):\n        \"\"\"If you provide a directory, it will look for a existing AFileManager.json in that directory, or create one if it does not already exist.\n            If you provide a json, it will use that json, unless the json doesn't exist, in which case it will complain...\n        \"\"\"\n        AObject.__init__(self, path=path);\n        if(media is not None):\n            self.media = media;\n\n    def initializeBlank(self):\n        AObject.initializeBlank(self);\n        self._widget = None;\n        self._media = None;\n\n\n    def getJSONName(self):\n        return self.AOBJECT_TYPE()+\".json\";\n\n\n    #########\n\n    # <editor-fold desc=\"Property: 'media'\">\n    @property\n    def media(self):\n        return self._getMedia();\n    def _getMedia(self):\n        return self._media;\n    @media.setter\n    def media(self, value):\n        self._setMedia(value);\n    def _setMedia(self, value):\n        self._media = value;\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'media_type'\">\n    @property\n    def media_type(self):\n        return self._getMediaType();\n    def _getMediaType(self):\n        if(self.media is None):\n            return None;\n        else:\n            return self.media.AObjectType();\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'widget'\">\n    @property\n    def widget(self):\n        return self._getWidget();\n    def _getWidget(self):\n        if (self._widget is None):\n            self._widget = Viewer.VBVSignal();\n        return self._widget;\n    @widget.setter\n    def widget(self, value):\n        self._setWidget(value);\n    def _setWidget(self, value):\n        self._widget = value;\n    # </editor-fold>\n\n    # <editor-fold desc=\"Property: 'frame_rate'\">\n    @property\n    def frame_rate(self):\n        return self._getFrameRate();\n    def _getFrameRate(self):\n        gfr = self.widget.frame_rate;\n        if (gfr is None):\n            media = self.media;\n            if (media is not None):\n                gfr = media.getFrameRate();\n        return gfr;\n    @frame_rate.setter\n    def frame_rate(self, value):\n        self._setFrameRate(value);\n    def _setFrameRate(self, value):\n        self.widget.frame_rate = float(value);\n    # </editor-fold>\n\n\n    # <editor-fold desc=\"Property: 'frame_offset'\">\n    @property\n    def frame_offset(self):\n        return self._getFrameOffset();\n    def _getFrameOffset(self):\n        return self.widget.frame_offset;\n    @frame_offset.setter\n    def frame_offset(self, value):\n        self._setFrameOffset(value);\n    def _setFrameOffset(self, value):\n        self.widget.frame_offset = value;\n    # </editor-fold>\n\n    def run(self, local_saliency=None, frame_rate = None, eventlist = 'default', frame_offset=None):\n        if(frame_rate is None):\n            # self.widget.frame_rate = float(self.getMedia().getFrameRate());\n            self.frame_rate = self.media._getFrameRate();\n        else:\n            # self.widget.frame_rate = float(frame_rate);\n            self.frame_rate = frame_rate;\n\n        if(local_saliency is None):\n            self.widget.signal = self.media.getLocalRhythmicSaliency().tolist();\n            # self.widget.signal = self.getBothWayVisualImpactEnvelope(highpass_window_seconds=None, force_recompute = True).tolist();\n        else:\n            self.widget.signal = local_saliency.tolist();\n\n        if(frame_offset is None):\n            self.frame_offset = 0;\n        elif(frame_offset is 'guess'):\n            self.frame_offset = self.guessFrameOffset();\n        else:\n            self.frame_offset = frame_offset;\n\n        if(eventlist is None):\n            self.widget.events = [];\n        elif(eventlist == 'default'):\n            self.widget.events = EventList._toGUIDicts(self.media.getEventList());\n        else:\n            self.widget.events = EventList._toGUIDicts(eventlist);\n        self.widget.data_string = self.media.getStringForHTMLStreamingBase64();\n        return self.widget;\n\n\n    def guessFrameOffset(self):\n        if(isinstance(self.media, Video)):\n            return self.media.reader.get_length() - self.media.n_frames();\n        else:\n            return 0;\n\n\n    def deactivateAllEvents(self):\n        newes = []\n        gevents = self.getEventDicts();\n        for e in gevents:\n            newe = e;\n            newe['is_active']=0;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n    def activateAllEvents(self):\n        newes = []\n        gevents = self.getEventDicts();\n        for e in gevents:\n            newe = e;\n            newe['is_active'] = 1;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n    def activatePattern(self, pattern=None, prefix=None, apply_to_active=None):\n        assert(pattern), \"must provide pattern to activate\"\n        newes = []\n        gevents = self.getGUIEventDicts();\n        counter = 0;\n        prefix_length = 0;\n        if(prefix_length is not None):\n            prefix_length = len(prefix);\n        for i, e in enumerate(gevents):\n            if (apply_to_active):\n                if (e.get('is_active')):\n                    if (counter < prefix_length):\n                        e['is_active']=prefix[counter];\n                    else:\n                        e['is_active'] = pattern[(counter - prefix_length) % len(pattern)];\n                    counter = counter + 1;\n                else:\n                    print((\"Skipping beat {}, inactive\".format(i)));\n            else:\n                if (i < prefix_length):\n                    e['is_active'] = prefix[i];\n                else:\n                    e['is_active'] = pattern[(i - prefix_length) % len(pattern)];\n            newes.append(e);\n\n        self.widget.events = [];\n        self.widget.events = newes;\n\n\n    def shiftEventsByNFrames(self, n_frames=None):\n        assert(n_frames), \"must provide number of frames to shift by\"\n        newes = []\n        gevents = self.getEventDicts();\n        sample_step = np.true_divide(1.0,self.getFrameRate());\n        for e in gevents:\n            newe = e;\n            newe['start'] = newe['start']+n_frames*sample_step;\n            newes.append(newe);\n        self.widget.events = [];\n        self.widget.events = newes;\n\n\n    def getActiveEventTimes(self):\n        gevents = self.getEventDicts(active_only=True);\n        revents = []\n        for e in gevents:\n            revents.append(e.get('time'));\n        return np.asarray(revents);\n\n    def getEventTimes(self):\n        gevents = self.getEventDicts();\n        revents = []\n        for e in gevents:\n            revents.append(e.t);\n        return np.asarray(revents);\n\n    def getEvents(self, active_only=None):\n        return Event._FromGUIDicts(self.getEventDicts(active_only = active_only));\n\n    def getEventList(self, active_only=None):\n        elist = EventList._FromGUIDicts(self.getEventDicts(active_only=active_only));\n        elist.setInfo(label='html_frame_offset', value=self.getFrameOffset());\n        return elist;\n\n    def getActiveEvents(self):\n        return self.getEvents(active_only=True);\n\n    def getEventDicts(self, active_only = None):\n        gevents = self.widget.events[:];\n        if(not active_only):\n            return gevents;\n        else:\n            nevents = []\n            for e in gevents:\n                if(e.get('is_active')):\n                    nevents.append(e);\n            return nevents;\n\n    def saveEvents(self, save_path = None):\n        elist = self.getEventList(active_only=False);\n        if(save_path is not None):\n            elist.writeToJSON(json_path=save_path);\n            self.widget.last_save_path = save_path;\n        else:\n            save_path = self.widget.last_save_path;\n            if(save_path is None):\n                save_path = uiGetSaveFilePath(file_extension='.json');\n            if(save_path is not None):\n                elist.writeToJSON(json_path=save_path);\n                self.widget.last_save_path = save_path;\n\n    def saveEventsAs(self, save_path = None):\n        elist = self.getEventList(active_only=False);\n        if (save_path is not None):\n            elist.writeToJSON(json_path=save_path);\n            self.widget.last_save_path = save_path;\n            print(('savepath not none {}'.format(save_path)))\n        else:\n            save_path = uiGetSaveFilePath(file_extension='.json');\n            print(('savepath from ui {}'.format(save_path)))\n            if (save_path is not None):\n                print(('save path from ui {}'.format(save_path)));\n                elist.writeToJSON(json_path=save_path);\n                self.widget.last_save_path = save_path;\n        print(save_path)\n\n    def setEvents(self, events):\n        self.widget.events = Event._ToGUIDicts(events);\n\n    def setEventList(self, event_list):\n        if(event_list.getInfo('html_frame_offset') is not None):\n            self.widget.frame_offset = event_list.getInfo('html_frame_offset');\n        self.widget.events = event_list._toGUIDicts();\n\n\n    def loadEvents(self, load_path = None):\n        if(load_path is None):\n            load_path = uiGetFilePath();\n        elist = EventList();\n        elist.loadFromJSON(json_path=load_path);\n        self.setEventList(event_list = elist);\n\n\n\n    def getEventListWithSelectedSegments(self):\n        eventlist = self.getEventList();\n        events = eventlist.events;\n        segments = [];\n        for i, e in enumerate(events):\n            if(e.direction>-1): # meaning not a back beat\n                newseg = [];\n                for si in range(i, len(events)):\n                    newseg.append(si);\n                    if(events[si].direction<0): # meaning a back beat\n                        break;\n                segments.append(newseg);\n        eventlist.setInfo(label='selected_segments', value=segments);\n        return eventlist;\n\n\n\n\n\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3/vbgui/__init__.py",
    "content": "\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3.egg-info/PKG-INFO",
    "content": "Metadata-Version: 2.1\nName: visbeat3\nVersion: 0.0.8\nSummary: Python3 Implementation for 'Visual Rhythm and Beat' SIGGRAPH 2018\nHome-page: https://github.com/haofanwang/visbeat3\nAuthor: Haofan Wang\nAuthor-email: haofanwang.ai@gmail.com\nLicense: UNKNOWN\nDescription: # visbeat3\n        \n        This is a migration of [visbeat](http://abedavis.com/visualbeat/) from Python2 to Python3. All credits belong to the original author.\n        \n        Note: This repo is under development, for any issue, please PR directly!\n        \n        ## Install\n        \n        ```\n        pip3 install visbeat3\n        ```\n        \n        or\n        \n        ```\n        pip3 install -e git+https://github.com/haofanwang/visbeat3.git#egg=visbeat3\n        ```\n        \n        ## Usage\n        \n        ```\n        import visbeat3 as vb\n        ```\n        \n        ## Reference\n        ```\n        @inproceedings{davis2018visual,\n          title={Visual rhythm and beat},\n          author={Davis, Abe and Agrawala, Maneesh},\n          booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition Workshops},\n          pages={2532--2535},\n          year={2018}\n        }\n        ```\n        \nPlatform: UNKNOWN\nClassifier: Programming Language :: Python :: 3\nClassifier: License :: OSI Approved :: Apache Software License\nClassifier: Operating System :: OS Independent\nDescription-Content-Type: text/markdown\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3.egg-info/SOURCES.txt",
    "content": ".DS_Store\nLICENSE\nLICENSE.pdf\nMANIFEST.in\nREADME.md\nsetup.cfg\nsetup.py\ntest.py\n.git/.DS_Store\n.git/HEAD\n.git/config\n.git/description\n.git/index\n.git/packed-refs\n.git/hooks/applypatch-msg.sample\n.git/hooks/commit-msg.sample\n.git/hooks/fsmonitor-watchman.sample\n.git/hooks/post-update.sample\n.git/hooks/pre-applypatch.sample\n.git/hooks/pre-commit.sample\n.git/hooks/pre-merge-commit.sample\n.git/hooks/pre-push.sample\n.git/hooks/pre-rebase.sample\n.git/hooks/pre-receive.sample\n.git/hooks/prepare-commit-msg.sample\n.git/hooks/push-to-checkout.sample\n.git/hooks/update.sample\n.git/info/exclude\n.git/logs/HEAD\n.git/logs/refs/heads/main\n.git/logs/refs/remotes/origin/HEAD\n.git/objects/pack/pack-390cb819f9aa179975f055403fc70bc5f8d17684.idx\n.git/objects/pack/pack-390cb819f9aa179975f055403fc70bc5f8d17684.pack\n.git/refs/heads/main\n.git/refs/remotes/origin/HEAD\nVisBeatAssets/.DS_Store\nVisBeatAssets/VideoSources/.DS_Store/VideoSource.json\nVisBeatAssets/VideoSources/.DS_Store/Versions/Source/Full/.DS_Store\nVisBeatAssets/VideoSources/animation.mp4/.DS_Store\nVisBeatAssets/VideoSources/animation.mp4/VideoSource.json\nVisBeatAssets/VideoSources/animation.mp4/Data/.DS_Store\nVisBeatAssets/VideoSources/animation.mp4/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/animation.mp4/Data/Features/video/directogram_powers/animation_maxheight_360.pkl\nVisBeatAssets/VideoSources/animation.mp4/Versions/.DS_Store\nVisBeatAssets/VideoSources/animation.mp4/Versions/Original/.DS_Store\nVisBeatAssets/VideoSources/animation.mp4/Versions/Original/maxheight_360/animation.mp4\nVisBeatAssets/VideoSources/animation.mp4/Versions/Source/Full/animation.mp4\nVisBeatAssets/VideoSources/demo-new.mp4/VideoSource.json\nVisBeatAssets/VideoSources/demo-new.mp4/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/demo-new.mp4/Data/Features/video/directogram_powers/demo-new_maxheight_360.pkl\nVisBeatAssets/VideoSources/demo-new.mp4/Versions/Original/maxheight_360/demo-new.mp4\nVisBeatAssets/VideoSources/demo-new.mp4/Versions/Source/Full/demo-new.mp4\nVisBeatAssets/VideoSources/final_640.mp4/VideoSource.json\nVisBeatAssets/VideoSources/final_640.mp4/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/final_640.mp4/Data/Features/video/directogram_powers/final_640_maxheight_360.pkl\nVisBeatAssets/VideoSources/final_640.mp4/Versions/Original/maxheight_360/final_640.mp4\nVisBeatAssets/VideoSources/final_640.mp4/Versions/Source/Full/final_640.mp4\nVisBeatAssets/VideoSources/wzk1_0.mp4/VideoSource.json\nVisBeatAssets/VideoSources/wzk1_0.mp4/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/wzk1_0.mp4/Data/Features/video/directogram_powers/wzk1_0_maxheight_360.pkl\nVisBeatAssets/VideoSources/wzk1_0.mp4/Versions/Original/maxheight_360/wzk1_0.mp4\nVisBeatAssets/VideoSources/wzk1_0.mp4/Versions/Source/Full/wzk1_0.mp4\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/VideoSource.json\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238.mp4/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238.mp4/VideoSource.json\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238.mp4/Data/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238.mp4/Versions/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Data/Features/video/directogram_powers/wzk_vlog_beat_enhance1_track1238_maxheight_360.pkl\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/.DS_Store\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Original/maxheight_360/wzk_vlog_beat_enhance1_track1238.mp4\nVisBeatAssets/VideoSources/wzk_vlog_beat_enhance1_track1238/Versions/Source/Full/wzk_vlog_beat_enhance1_track1238.mp4\nVisBeatAssets/VideoSources/zly2_0.mp4/.DS_Store\nVisBeatAssets/VideoSources/zly2_0.mp4/VideoSource.json\nVisBeatAssets/VideoSources/zly2_0.mp4/Data/.DS_Store\nVisBeatAssets/VideoSources/zly2_0.mp4/Data/Backups/VideoSource.json\nVisBeatAssets/VideoSources/zly2_0.mp4/Data/Features/video/directogram_powers/zly2_0_maxheight_360.pkl\nVisBeatAssets/VideoSources/zly2_0.mp4/Versions/.DS_Store\nVisBeatAssets/VideoSources/zly2_0.mp4/Versions/Original/maxheight_360/zly2_0.mp4\nVisBeatAssets/VideoSources/zly2_0.mp4/Versions/Source/Full/zly2_0.mp4\nVisBeatAssets/VideoSources/zly3_0.mp4/VideoSource.json\nVisBeatAssets/VideoSources/zly3_0.mp4/Versions/Source/Full/zly3_0.mp4\nbin/dancefer\nvisbeat3/.DS_Store\nvisbeat3/ADefines.py\nvisbeat3/AFileManager.py\nvisbeat3/AFuncDict.py\nvisbeat3/AImports.py\nvisbeat3/AObject.py\nvisbeat3/AParamDict.py\nvisbeat3/Audio.py\nvisbeat3/AudioClip.py\nvisbeat3/Event.py\nvisbeat3/EventList.py\nvisbeat3/Image.py\nvisbeat3/Image_CV.py\nvisbeat3/SourceLocationParser.py\nvisbeat3/TimeSignal.py\nvisbeat3/TimeSignal1D.py\nvisbeat3/VBMIDI.py\nvisbeat3/VBObject.py\nvisbeat3/Video.py\nvisbeat3/VideoClip.py\nvisbeat3/VideoSource.py\nvisbeat3/Video_CV.py\nvisbeat3/VisBeatDefines.py\nvisbeat3/VisBeatExampleVideo.py\nvisbeat3/VisBeatImports.py\nvisbeat3/VisualBeat.py\nvisbeat3/Warp.py\nvisbeat3/__init__.py\nvisbeat3/_dancefer_examples.py\nvisbeat3/_dancify_examples.py\nvisbeat3/_mediafiles.py\nvisbeat3/_music_examples.py\nvisbeat3/command_line.py\nvisbeat3.egg-info/PKG-INFO\nvisbeat3.egg-info/SOURCES.txt\nvisbeat3.egg-info/dependency_links.txt\nvisbeat3.egg-info/requires.txt\nvisbeat3.egg-info/top_level.txt\nvisbeat3/__pycache__/ADefines.cpython-37.pyc\nvisbeat3/__pycache__/AFileManager.cpython-37.pyc\nvisbeat3/__pycache__/AFuncDict.cpython-37.pyc\nvisbeat3/__pycache__/AImports.cpython-37.pyc\nvisbeat3/__pycache__/AObject.cpython-37.pyc\nvisbeat3/__pycache__/AParamDict.cpython-37.pyc\nvisbeat3/__pycache__/Audio.cpython-37.pyc\nvisbeat3/__pycache__/AudioClip.cpython-37.pyc\nvisbeat3/__pycache__/Event.cpython-37.pyc\nvisbeat3/__pycache__/EventList.cpython-37.pyc\nvisbeat3/__pycache__/Image.cpython-37.pyc\nvisbeat3/__pycache__/Image_CV.cpython-37.pyc\nvisbeat3/__pycache__/SourceLocationParser.cpython-37.pyc\nvisbeat3/__pycache__/TimeSignal.cpython-37.pyc\nvisbeat3/__pycache__/TimeSignal1D.cpython-37.pyc\nvisbeat3/__pycache__/VBObject.cpython-37.pyc\nvisbeat3/__pycache__/Video.cpython-37.pyc\nvisbeat3/__pycache__/VideoClip.cpython-37.pyc\nvisbeat3/__pycache__/VideoSource.cpython-37.pyc\nvisbeat3/__pycache__/Video_CV.cpython-37.pyc\nvisbeat3/__pycache__/VisBeatDefines.cpython-37.pyc\nvisbeat3/__pycache__/VisBeatExampleVideo.cpython-37.pyc\nvisbeat3/__pycache__/VisBeatImports.cpython-37.pyc\nvisbeat3/__pycache__/VisualBeat.cpython-37.pyc\nvisbeat3/__pycache__/Warp.cpython-37.pyc\nvisbeat3/__pycache__/__init__.cpython-37.pyc\nvisbeat3/__pycache__/_mediafiles.cpython-37.pyc\nvisbeat3/assets/audio/hit.wav\nvisbeat3/assets/images/VisBeatWatermark.png\nvisbeat3/fileui/__init__.py\nvisbeat3/fileui/uipath.py\nvisbeat3/fileui/__pycache__/__init__.cpython-37.pyc\nvisbeat3/fileui/__pycache__/uipath.cpython-37.pyc\nvisbeat3/vbgui/BeatGUI.py\nvisbeat3/vbgui/__init__.py\nvisbeat3/vbgui/__pycache__/BeatGUI.cpython-37.pyc\nvisbeat3/vbgui/__pycache__/__init__.cpython-37.pyc"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3.egg-info/dependency_links.txt",
    "content": "\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3.egg-info/requires.txt",
    "content": "numpy\nscipy\nbs4\nlibrosa\nimageio\nrequests\nmoviepy\ntermcolor\nyoutube-dl\nmatplotlib\n"
  },
  {
    "path": "src/video2npz/visbeat3/visbeat3.egg-info/top_level.txt",
    "content": "visbeat3\n"
  },
  {
    "path": "videos/.gitkeep",
    "content": ""
  }
]