mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2025-12-31 17:00:41 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edbe748718 | ||
|
|
2019a4ec63 | ||
|
|
fb43838c7d | ||
|
|
4cd58b8ddd | ||
|
|
38dab7723f | ||
|
|
354d88a5b2 | ||
|
|
d8a405b6d2 | ||
|
|
5f7e467fbd | ||
|
|
3377ddb4b9 | ||
|
|
9cd6cf7f12 | ||
|
|
1f8ebe253b | ||
|
|
fe46d1b242 | ||
|
|
b213933ad8 | ||
|
|
7e314f7475 | ||
|
|
b2d6fd3c92 | ||
|
|
c4d8608c8f | ||
|
|
5605b05f9f | ||
|
|
5d71cabda7 | ||
|
|
c2f87b1fef | ||
|
|
3db40d4f12 | ||
|
|
40b30f5bd8 | ||
|
|
048f20c64c | ||
|
|
6a69df2ee8 | ||
|
|
ec327ee76f | ||
|
|
62a34cfee8 | ||
|
|
c966097e7d | ||
|
|
35311e394d | ||
|
|
0633a8685c | ||
|
|
f65665a06c | ||
|
|
261572cff3 | ||
|
|
623a8569fd | ||
|
|
31493f7cf4 | ||
|
|
4809bb4844 | ||
|
|
a76f3b1518 | ||
|
|
b8cb585d50 | ||
|
|
84a76f9c74 | ||
|
|
5a1a12e21e | ||
|
|
06835ffe11 | ||
|
|
1b25b8214d | ||
|
|
cfc1a451bc | ||
|
|
0788613ea3 | ||
|
|
e9e4b4bcbb | ||
|
|
c114eb7cf3 | ||
|
|
4576d65da6 |
13
.coveragerc
13
.coveragerc
@@ -1,13 +0,0 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = wavinfo
|
||||
|
||||
[report]
|
||||
exclude_lines =
|
||||
if self.debug:
|
||||
pragma: no cover
|
||||
raise NotImplementedError
|
||||
if __name__ == .__main__.:
|
||||
ignore_errors = True
|
||||
omit =
|
||||
tests/*
|
||||
42
.github/workflows/python-package.yml
vendored
Normal file
42
.github/workflows/python-package.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
||||
|
||||
name: Python Lint and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.5.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install flake8 pytest
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
- name: Setup FFmpeg
|
||||
uses: FedericoCarboni/setup-ffmpeg@v2
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest
|
||||
2
.github/workflows/pythonpublish.yml
vendored
2
.github/workflows/pythonpublish.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
pip install setuptools wheel twine lxml
|
||||
- name: Build and publish
|
||||
env:
|
||||
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
|
||||
# Default ignored files
|
||||
/workspace.xml
|
||||
9
.idea/dictionaries/jamiehardt.xml
generated
9
.idea/dictionaries/jamiehardt.xml
generated
@@ -1,9 +0,0 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="jamiehardt">
|
||||
<words>
|
||||
<w>bext</w>
|
||||
<w>ident</w>
|
||||
<w>umid</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (wavinfo)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (wavinfo)" project-jdk-type="Python SDK" />
|
||||
<component name="PyPackaging">
|
||||
<option name="earlyReleasesAsUpgrades" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/wavinfo.iml" filepath="$PROJECT_DIR$/.idea/wavinfo.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/wavinfo.iml
generated
6
.idea/wavinfo.iml
generated
@@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.8 (wavinfo)" jdkType="Python SDK" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.7 (wavinfo)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
107
.idea/workspace.xml
generated
Normal file
107
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="fb29ad56-fffe-478f-9c0e-1718aa04342e" name="Default Changelist" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/dictionaries/jamiehardt.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dictionaries/jamiehardt.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/wavinfo.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/wavinfo.iml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="wavinfo" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Python Script" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
<option name="UPDATE_TYPE" value="MERGE" />
|
||||
</component>
|
||||
<component name="ProjectId" id="1VtfP9ukGK4GNIXS2m0hRLG9d7w" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
<option name="showMembers" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
<property name="TODO_SCOPE" value="Project Files" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="project-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="fb29ad56-fffe-478f-9c0e-1718aa04342e" name="Default Changelist" comment="" />
|
||||
<created>1578077284420</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1578077284420</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="Vcs.Log.History.Properties">
|
||||
<option name="COLUMN_ORDER">
|
||||
<list>
|
||||
<option value="0" />
|
||||
<option value="2" />
|
||||
<option value="3" />
|
||||
<option value="1" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Vcs.Log.Tabs.Properties">
|
||||
<option name="TAB_STATES">
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
<option name="oldMeFiltersMigrated" value="true" />
|
||||
</component>
|
||||
<component name="WindowStateProjectService">
|
||||
<state x="655" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog" timestamp="1598547965709">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="655" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598547965709" />
|
||||
<state x="0" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1598555737671">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="0" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598555737671" />
|
||||
<state x="476" y="183" key="SettingsEditor" timestamp="1598548365517">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="476" y="183" key="SettingsEditor/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598548365517" />
|
||||
<state x="114" y="123" width="1706" height="842" key="com.intellij.history.integration.ui.views.FileHistoryDialog" timestamp="1597689482054">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="114" y="123" width="1706" height="842" key="com.intellij.history.integration.ui.views.FileHistoryDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1597689482054" />
|
||||
<state x="577" y="376" key="com.intellij.ide.util.TipDialog" timestamp="1601767353495">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="577" y="376" key="com.intellij.ide.util.TipDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598550975228" />
|
||||
<state x="577" y="376" key="com.intellij.ide.util.TipDialog/1920.0.1920.1080/0.0.1920.1080@0.0.1920.1080" timestamp="1601767353495" />
|
||||
<state x="772" y="468" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1598547948993">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="772" y="468" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598547948993" />
|
||||
<state x="632" y="254" width="670" height="676" key="search.everywhere.popup" timestamp="1598554315633">
|
||||
<screen x="0" y="0" width="1920" height="1080" />
|
||||
</state>
|
||||
<state x="632" y="254" width="670" height="676" key="search.everywhere.popup/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598554315633" />
|
||||
</component>
|
||||
</project>
|
||||
26
.travis.yml
26
.travis.yml
@@ -1,26 +0,0 @@
|
||||
dist: xenial
|
||||
language: python
|
||||
python:
|
||||
# - "2.7"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
script:
|
||||
- "gunzip tests/test_files/rf64/*.gz"
|
||||
- "python setup.py test"
|
||||
- "python -m pytest tests/ -v --cov wavinfo --cov-report term-missing"
|
||||
before_install:
|
||||
- "sudo apt-get update"
|
||||
- "sudo add-apt-repository universe"
|
||||
- "sudo apt-get install -y ffmpeg"
|
||||
- "pip install pytest"
|
||||
- "pip install lxml"
|
||||
- "pip install coverage"
|
||||
- "pip install codecov"
|
||||
- "pip install pytest-cov==2.5.0"
|
||||
- "pip install coverage==4.4"
|
||||
install:
|
||||
- "pip install setuptools"
|
||||
after_success:
|
||||
- "codecov"
|
||||
@@ -1,6 +1,5 @@
|
||||
[](https://travis-ci.com/iluvcapra/wavinfo)
|
||||
[](https://codecov.io/gh/iluvcapra/wavinfo)
|
||||
[](https://wavinfo.readthedocs.io/en/latest/?badge=latest)   [](https://pypi.org/project/wavinfo/) 
|
||||

|
||||
|
||||
<!--  -->
|
||||
|
||||
@@ -60,10 +59,6 @@ The length of the file in frames (interleaved samples) and bytes is available, a
|
||||
>>> (48000, 2, 6, 24)
|
||||
```
|
||||
|
||||
## Platform Lifecycle Stuff
|
||||
|
||||
Python 3.5 support is deprecated.
|
||||
|
||||
## Other Resources
|
||||
|
||||
* For other file formats and ID3 decoding, look at [audio-metadata](https://github.com/thebigmunch/audio-metadata).
|
||||
|
||||
6
metadata.py
Normal file
6
metadata.py
Normal file
@@ -0,0 +1,6 @@
|
||||
"""
|
||||
Wavinfo
|
||||
"""
|
||||
__version__ = '1.7.0'
|
||||
__author__ = 'Jamie Hardt <jamiehardt@gmail.com>'
|
||||
__license__ = "MIT"
|
||||
19
requirements.txt
Normal file
19
requirements.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
attrs==21.4.0
|
||||
ear==2.1.0
|
||||
enum34==1.1.10
|
||||
exceptiongroup==1.0.4
|
||||
iniconfig==1.1.1
|
||||
lxml==4.9.1
|
||||
multipledispatch==0.6.0
|
||||
numpy==1.23.3
|
||||
packaging==21.3
|
||||
pluggy==1.0.0
|
||||
pyparsing==3.0.9
|
||||
pytest==7.2.0
|
||||
ruamel.yaml==0.17.21
|
||||
ruamel.yaml.clib==0.2.6
|
||||
scipy==1.9.1
|
||||
six==1.16.0
|
||||
style==1.1.0
|
||||
tomli==2.0.1
|
||||
update==0.0.1
|
||||
11
setup.py
11
setup.py
@@ -1,5 +1,5 @@
|
||||
from setuptools import setup
|
||||
from wavinfo import __author__, __license__, __version__
|
||||
from metadata import __author__, __license__, __version__
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
@@ -26,12 +26,11 @@ setup(name='wavinfo',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Topic :: Multimedia',
|
||||
'Topic :: Multimedia :: Sound/Audio',
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8"],
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10"],
|
||||
keywords='waveform metadata audio ebu smpte avi library film tv editing editorial',
|
||||
install_requires=['lxml'],
|
||||
install_requires=['lxml', 'ear'],
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'wavinfo = wavinfo.__main__:main'
|
||||
|
||||
@@ -12,7 +12,7 @@ class TestWaveInfo(TestCase):
|
||||
def test_sanity(self):
|
||||
for wav_file in all_files():
|
||||
info = wavinfo.WavInfoReader(wav_file)
|
||||
self.assertEqual(info.__repr__(), 'WavInfoReader(%s, %s, %s)'.format(wav_file, 'latin_1', 'ascii'))
|
||||
self.assertEqual(info.__repr__(), 'WavInfoReader({}, latin_1, ascii)'.format(os.path.abspath(wav_file)))
|
||||
self.assertIsNotNone(info)
|
||||
|
||||
def test_fmt_against_ffprobe(self):
|
||||
|
||||
@@ -7,6 +7,3 @@ Go to the documentation for wavinfo.WavInfoReader for more information.
|
||||
from .wave_reader import WavInfoReader
|
||||
from .riff_parser import WavInfoEOFError
|
||||
|
||||
__version__ = '1.6'
|
||||
__author__ = 'Jamie Hardt <jamiehardt@gmail.com>'
|
||||
__license__ = "MIT"
|
||||
|
||||
188
wavinfo/dolby_parser.py
Normal file
188
wavinfo/dolby_parser.py
Normal file
@@ -0,0 +1,188 @@
|
||||
# Dolby RMU Metadata per EBU Tech 3285 Supp 6
|
||||
#
|
||||
# https://tech.ebu.ch/docs/tech/tech3285s6.pdf
|
||||
#
|
||||
|
||||
from struct import unpack, calcsize
|
||||
from enum import (Enum, IntEnum)
|
||||
|
||||
CHUNK_IDENT = "dbmd"
|
||||
DOLBY_VERSION = "1.0.0.6"
|
||||
|
||||
|
||||
class _DPPGenericDownMixLevel(Enum):
|
||||
PLUS_3DB = 0b000
|
||||
PLUS_1_5DB = 0b001
|
||||
UNITY = 0b010
|
||||
MINUS_1_5DB = 0b011
|
||||
MINUS_3DB = 0b100
|
||||
MINUS_4_5DB = 0b101
|
||||
MINUS_6DB = 0b110
|
||||
MUTE = 0b111
|
||||
|
||||
|
||||
class DPPDolbySurroundEncodingMode(Enum):
|
||||
RESERVED = 0b11
|
||||
IN_USE = 0b10
|
||||
NOT_IN_USE = 0b01
|
||||
NOT_INDICATED = 0b00
|
||||
|
||||
# DPPLoRoDownMixCenterLevel
|
||||
# DPPLtRtCenterMixLevel
|
||||
# DPPLtRtSurroundMixLevel
|
||||
|
||||
class DolbyMetadataSegmentTypes(IntEnum):
|
||||
END_MARKER = 0
|
||||
DOLBY_E_METADATA = 1
|
||||
DOLBY_DIGITAL_METADATA = 3
|
||||
DOLBY_DIGITAL_PLUS_METADATA = 7
|
||||
AUDIO_INFO = 8
|
||||
|
||||
|
||||
class DDPBitStreamMode(Enum):
|
||||
"""
|
||||
Dolby Digital Plus `bsmod` field
|
||||
§ 4.3.2.2
|
||||
"""
|
||||
COMPLETE_MAIN = 0b000
|
||||
MUSIC_AND_EFFECTS = 0b001
|
||||
VISUALLY_IMPAIRED = 0b010
|
||||
HEARING_IMPAIRED = 0b011
|
||||
DIALOGUE_ONLY = 0b100
|
||||
COMMENTARY = 0b101
|
||||
EMERGENCY = 0b110
|
||||
VOICEOVER = 0b111 # if audioconfigmode is 1_0
|
||||
KARAOKE = 0b1000 # if audioconfigmode is not 1_0
|
||||
|
||||
|
||||
class DDPAudioCodingMode(Enum):
|
||||
"""
|
||||
Dolby Digital Plus `acmod` field
|
||||
§ 4.3.2.3
|
||||
"""
|
||||
RESERVED = 0b000
|
||||
CH_ORD_1_0 = 0b001
|
||||
CH_ORD_2_0 = 0b010
|
||||
CH_ORD_3_0 = 0b011
|
||||
CH_ORD_2_1 = 0b100
|
||||
CH_ORD_3_1 = 0b101
|
||||
CH_ORD_2_2 = 0b110
|
||||
CH_ORD_3_2 = 0b111
|
||||
|
||||
|
||||
class DPPCenterDownMixLevel(Enum):
|
||||
"""
|
||||
§ 4.3.3.1
|
||||
"""
|
||||
DOWN_3DB = 0b00
|
||||
DOWN_45DB = 0b01
|
||||
DOWN_6DB = 0b10
|
||||
RESERVED = 0b11
|
||||
|
||||
|
||||
class DPPSurroundDownMixLevel(Enum):
|
||||
"""
|
||||
Dolby Digital Plus `surmixlev` field
|
||||
§ 4.3.3.2
|
||||
"""
|
||||
DOWN_3DB = 0b00
|
||||
DOWN_6DB = 0b01
|
||||
MUTE = 0b10
|
||||
RESERVED = 0b11
|
||||
|
||||
|
||||
class DPPLanguageCode(Enum):
|
||||
"""
|
||||
§ 4.3.4.1 , 4.3.5 (always 0xFF)
|
||||
"""
|
||||
# this is removed in https://www.atsc.org/wp-content/uploads/2015/03/A52-201212-17.pdf § 5.4.2.12
|
||||
# It should just be 0xff
|
||||
pass
|
||||
|
||||
|
||||
class DPPMixLevel(int):
|
||||
pass
|
||||
|
||||
|
||||
class DPPDialnormLevel(int):
|
||||
pass
|
||||
|
||||
|
||||
class DPPRoomTime(Enum):
|
||||
"""
|
||||
`roomtyp` 4.3.6.3
|
||||
"""
|
||||
NOT_INDICATED = 0b00
|
||||
LARGE_ROOM_X_CURVE = 0b01
|
||||
SMALL_ROOM_FLAT_CURVE = 0b10
|
||||
RESERVED = 0b11
|
||||
|
||||
|
||||
class DPPPreferredDownMixMode(Enum):
|
||||
"""
|
||||
§ 4.3.8.1
|
||||
"""
|
||||
NOT_INDICATED = 0b00
|
||||
PRO_LOGIC = 0b01
|
||||
STEREO = 0b10
|
||||
PRO_LOGIC_2 = 0b11
|
||||
|
||||
|
||||
# class DPPLtRtCenterMixLevel(_DPPGenericDownMixLevel):
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# class DPPLtRtSurroundMixLevel(_DPPGenericDownMixLevel):
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# class DPPSurroundEXMode(_DPPGenericInUseIndicator):
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# class DPPHeadphoneMode(_DPPGenericInUseIndicator):
|
||||
# pass
|
||||
|
||||
|
||||
class DPPADConverterType(Enum):
|
||||
STANDARD = 0
|
||||
HDCD = 1
|
||||
|
||||
|
||||
class DDPStreamDependency(Enum):
|
||||
"""
|
||||
Encodes `ddplus_info1.stream_type` field § 4.3.12.1
|
||||
"""
|
||||
INDEPENDENT = 0
|
||||
DEPENDENT = 1
|
||||
INDEPENDENT_FROM_DOLBY_DIGITAL = 2
|
||||
RESERVED = 3
|
||||
|
||||
|
||||
class DDPDataRate(int):
|
||||
pass
|
||||
|
||||
|
||||
class DPPRFCompressionProfile(Enum):
|
||||
NONE = 0
|
||||
FILM_STANDARD = 1
|
||||
FILM_LIGHT = 2
|
||||
MUSIC_STANDARD = 3
|
||||
MUSIC_LIGHT = 4
|
||||
SPEECH = 5
|
||||
|
||||
|
||||
class DolbyDigitalPlusMetadata:
|
||||
|
||||
@classmethod
|
||||
def parse(cls, binary_data):
|
||||
binary_format = "<BBxxBBBBBBBBBBBBBxxxBxxxxxH"
|
||||
assert len(binary_data >= calcsize(binary_format))
|
||||
fields = unpack(binary_format, binary_data)
|
||||
|
||||
|
||||
class WavDolbyReader:
|
||||
def __init__(self, dolby_data):
|
||||
version, remainder = unpack("<U", dolby_data[0]), dolby_data[1:]
|
||||
|
||||
## FIXME continues...
|
||||
9
wavinfo/wave_axml_reader.py
Normal file
9
wavinfo/wave_axml_reader.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from lxml import etree as ET
|
||||
from collections import namedtuple
|
||||
|
||||
from ear.fileio.bw64 import Bw64Reader
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# import xml.etree.ElementTree as ET
|
||||
from lxml import etree as ET
|
||||
import io
|
||||
from collections import namedtuple
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#-*- coding: utf-8 -*-
|
||||
import struct
|
||||
import os
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
|
||||
import pathlib
|
||||
@@ -28,43 +27,57 @@ class WavInfoReader:
|
||||
"""
|
||||
Create a new reader object.
|
||||
|
||||
:param path: A filesystem path to the wav file you wish to probe.
|
||||
:param path:
|
||||
A filesystem path to the wav file you wish to probe or a
|
||||
file handle to an open file.
|
||||
|
||||
:param info_encoding: The text encoding of the INFO metadata fields.
|
||||
latin_1/Win CP1252 has always been a pretty good guess for this.
|
||||
:param info_encoding:
|
||||
The text encoding of the INFO metadata fields.
|
||||
latin_1/Win CP1252 has always been a pretty good guess for this.
|
||||
|
||||
:param bext_encoding: The text encoding to use when decoding the string
|
||||
fields of the Broadcast-WAV extension. Per EBU 3285 this is ASCII
|
||||
but this parameter is available to you if you encounter a weirdo.
|
||||
:param bext_encoding:
|
||||
The text encoding to use when decoding the string
|
||||
fields of the Broadcast-WAV extension. Per EBU 3285 this is ASCII
|
||||
but this parameter is available to you if you encounter a weirdo.
|
||||
"""
|
||||
absolute_path = os.path.abspath(path)
|
||||
|
||||
#: `file://` url for the file.
|
||||
self.url = pathlib.Path(absolute_path).as_uri()
|
||||
|
||||
# for __repr__()
|
||||
self.path = absolute_path
|
||||
|
||||
self.info_encoding = info_encoding
|
||||
self.bext_encoding = bext_encoding
|
||||
|
||||
if hasattr(path, 'read'):
|
||||
self.get_wav_info(path)
|
||||
self.url = 'about:blank'
|
||||
self.path = repr(path)
|
||||
else:
|
||||
absolute_path = os.path.abspath(path)
|
||||
|
||||
with open(path, 'rb') as f:
|
||||
chunks = parse_chunk(f)
|
||||
#: `file://` url for the file.
|
||||
self.url = pathlib.Path(absolute_path).as_uri()
|
||||
|
||||
self.main_list = chunks.children
|
||||
f.seek(0)
|
||||
# for __repr__()
|
||||
self.path = absolute_path
|
||||
|
||||
with open(path, 'rb') as f:
|
||||
self.get_wav_info(f)
|
||||
|
||||
def get_wav_info(self, wavfile):
|
||||
chunks = parse_chunk(wavfile)
|
||||
|
||||
#: :class:`wavinfo.wave_reader.WavAudioFormat`
|
||||
self.fmt = self._get_format(f)
|
||||
self.main_list = chunks.children
|
||||
wavfile.seek(0)
|
||||
|
||||
#: :class:`wavinfo.wave_bext_reader.WavBextReader` with Broadcast-WAV metadata
|
||||
self.bext = self._get_bext(f, encoding=bext_encoding)
|
||||
#: :class:`wavinfo.wave_reader.WavAudioFormat`
|
||||
self.fmt = self._get_format(wavfile)
|
||||
|
||||
#: :class:`wavinfo.wave_ixml_reader.WavIXMLFormat` with iXML metadata
|
||||
self.ixml = self._get_ixml(f)
|
||||
#: :class:`wavinfo.wave_bext_reader.WavBextReader` with Broadcast-WAV metadata
|
||||
self.bext = self._get_bext(wavfile, encoding=self.bext_encoding)
|
||||
|
||||
#: :class:`wavinfo.wave_info_reader.WavInfoChunkReader` with RIFF INFO metadata
|
||||
self.info = self._get_info(f, encoding=info_encoding)
|
||||
self.data = self._describe_data()
|
||||
#: :class:`wavinfo.wave_ixml_reader.WavIXMLFormat` with iXML metadata
|
||||
self.ixml = self._get_ixml(wavfile)
|
||||
|
||||
#: :class:`wavinfo.wave_info_reader.WavInfoChunkReader` with RIFF INFO metadata
|
||||
self.info = self._get_info(wavfile, encoding=self.info_encoding)
|
||||
self.data = self._describe_data()
|
||||
|
||||
def _find_chunk_data(self, ident, from_stream, default_none=False):
|
||||
top_chunks = (chunk for chunk in self.main_list if type(chunk) is ChunkDescriptor and chunk.ident == ident)
|
||||
@@ -147,4 +160,4 @@ class WavInfoReader:
|
||||
yield 'info', key, info_dict[key]
|
||||
|
||||
def __repr__(self):
|
||||
return 'WavInfoReader(%s, %s, %s)'.format(self.path, self.info_encoding, self.bext_encoding)
|
||||
return 'WavInfoReader({}, {}, {})'.format(self.path, self.info_encoding, self.bext_encoding)
|
||||
|
||||
Reference in New Issue
Block a user