diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..79a16af --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 120 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6dacd8b..b1f084d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,158 +4,88 @@ on: workflow_dispatch: inputs: version: - description: 'The version of libFLAC to build' + description: "The version of libFLAC to build" required: false - default: '1.3.4' + default: "1.4.3" debug: - description: 'Enable debug' + description: "Enable debug" required: false - default: 'no' + default: "no" jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - - name: Install dependencies - run: | - sudo apt-get update -y - sudo apt-get install -y \ - autoconf \ - clang \ - gcc-arm-linux-gnueabihf \ - gcc-aarch64-linux-gnu \ - libtool \ - mingw-w64 \ - patchelf \ - wget - - name: Download libFLAC - run: | - wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-${{ github.event.inputs.version }}.tar.xz + - name: Install dependencies + run: | + sudo apt-get update -y + sudo apt-get install -y \ + autoconf \ + clang \ + gcc-arm-linux-gnueabihf \ + gcc-aarch64-linux-gnu \ + libtool \ + mingw-w64 \ + patchelf \ + wget + - name: Download libFLAC + run: | + wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-${{ github.event.inputs.version }}.tar.xz - - name: Build libFLAC (Linux x86_64) - run: | - tar xJf flac-${{ github.event.inputs.version }}.tar.xz - mv flac-${{ github.event.inputs.version }} flac-linux-x86_64 - cd flac-linux-x86_64 - CC=clang ./configure --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} --enable-shared --disable-static --disable-examples - make - ls -l src/libFLAC/.libs - mkdir ../linux-x86_64 - cp src/libFLAC/.libs/libFLAC.so.8.3.0 ../linux-x86_64/libFLAC-8.3.0.so - cd ../linux-x86_64 - patchelf --set-soname libFLAC-8.3.0.so libFLAC-8.3.0.so - - name: Upload Linux x86_64 library - uses: actions/upload-artifact@v1 - with: - name: linux-x86_64 - path: linux-x86_64 + - name: Build libFLAC (Raspbian) + run: ./scripts/raspbian.sh ${{ github.event.inputs.version }} + - name: Upload Raspbian armv7a library + uses: actions/upload-artifact@v1 + with: + name: raspbian-armv7a + path: raspbian-armv7a + - name: Upload Raspbian armv6l library + uses: actions/upload-artifact@v1 + with: + name: raspbian-armv6l + path: raspbian-armv6l - - name: Build libFLAC (Linux arm64) - run: | - tar xJf flac-${{ github.event.inputs.version }}.tar.xz - mv flac-${{ github.event.inputs.version }} flac-linux-arm64 - cd flac-linux-arm64 - ./configure --host=aarch64-linux-gnu --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} --enable-shared --disable-static --disable-examples - make - ls -l src/libFLAC/.libs - mkdir ../linux-arm64 - cp src/libFLAC/.libs/libFLAC.so.8.3.0 ../linux-arm64/libFLAC-8.3.0.so - cd ../linux-arm64 - patchelf --set-soname libFLAC-8.3.0.so libFLAC-8.3.0.so - - name: Upload Linux arm64 library - uses: actions/upload-artifact@v1 - with: - name: linux-arm64 - path: linux-arm64 + - name: Build libFLAC (Linux) + run: ./scripts/linux.sh ${{ github.event.inputs.version }} + - name: Upload Linux x86_64 library + uses: actions/upload-artifact@v1 + with: + name: linux-x86_64 + path: linux-x86_64 + - name: Upload Linux arm64 library + uses: actions/upload-artifact@v1 + with: + name: linux-arm64 + path: linux-arm64 - - name: Build libFLAC (Windows x64) - run: | - tar xJf flac-${{ github.event.inputs.version }}.tar.xz - mv flac-${{ github.event.inputs.version }} flac-windows-x86_64 - cd flac-windows-x86_64 - ./configure --host=x86_64-w64-mingw32 --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} CFLAGS="-D_FORTIFY_SOURCE=0" --enable-shared --disable-static --disable-examples - make - ls -l src/libFLAC/.libs - mkdir ../windows-x86_64 - cp src/libFLAC/.libs/libFLAC-8.dll ../windows-x86_64/ - cp src/libFLAC/.libs/libFLAC.dll.a ../windows-x86_64/FLAC-8.lib - - name: Upload Windows x64 library - uses: actions/upload-artifact@v1 - with: - name: windows-x86_64 - path: windows-x86_64 - - - name: Build libFLAC (Windows x86) - run: | - tar xJf flac-${{ github.event.inputs.version }}.tar.xz - mv flac-${{ github.event.inputs.version }} flac-windows-i686 - cd flac-windows-i686 - ./configure --host=i686-w64-mingw32 --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} CFLAGS="-D_FORTIFY_SOURCE=0" --enable-shared --disable-static --disable-examples - make - ls -l src/libFLAC/.libs - mkdir ../windows-i686 - cp src/libFLAC/.libs/libFLAC-8.dll ../windows-i686/ - cp src/libFLAC/.libs/libFLAC.dll.a ../windows-i686/FLAC-8.lib - - name: Upload Windows x64 library - uses: actions/upload-artifact@v1 - with: - name: windows-i686 - path: windows-i686 - - - name: Build libFLAC (Raspbian armv7a) - run: | - tar xJf flac-${{ github.event.inputs.version }}.tar.xz - mv flac-${{ github.event.inputs.version }} flac-raspbian-armv7a - cd flac-raspbian-armv7a - ./configure --host=arm-linux-gnueabihf --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} CFLAGS="-mfpu=neon -march=armv7-a -mfloat-abi=hard" --enable-shared --disable-static --disable-examples - make - ls -l src/libFLAC/.libs - mkdir ../raspbian-armv7a - cp src/libFLAC/.libs/libFLAC.so.8.3.0 ../raspbian-armv7a/libFLAC-8.3.0.so - cd ../raspbian-armv7a - patchelf --set-soname libFLAC-8.3.0.so libFLAC-8.3.0.so - - name: Upload Raspbian armv7a library - uses: actions/upload-artifact@v1 - with: - name: raspbian-armv7a - path: raspbian-armv7a + # Now taken from https://packages.msys2.org/package/ instead + - name: Build libFLAC (Windows) + run: ./scripts/windows.sh ${{ github.event.inputs.version }} + - name: Upload Windows x64 library + uses: actions/upload-artifact@v1 + with: + name: windows-x86_64 + path: windows-x86_64 + - name: Upload Windows i686 library + uses: actions/upload-artifact@v1 + with: + name: windows-i686 + path: windows-i686 build_macos: runs-on: macos-latest steps: - - name: Install dependencies - run: brew install wget - - name: Download libFLAC - run: | - wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-${{ github.event.inputs.version }}.tar.xz - tar xvf flac-${{ github.event.inputs.version }}.tar.xz - - name: Build libFLAC (x86_64) - run: | - cd flac-${{ github.event.inputs.version }} - CC=clang ./configure --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} --enable-shared --disable-static --disable-examples - make - mkdir ../darwin-x86_64 - ls -l src/libFLAC/.libs - cp src/libFLAC/.libs/libFLAC.8.dylib ../darwin-x86_64/ - cd ../darwin-x86_64 - install_name_tool -id @rpath/libFLAC.8.dylib libFLAC.8.dylib - - name: Upload macOS x86_64 library - uses: actions/upload-artifact@v1 - with: - name: darwin-x86_64 - path: darwin-x86_64 - - name: Build libFLAC (arm64) - run: | - cd flac-${{ github.event.inputs.version }} - ./configure --host=aarch64-apple-darwin --with-ogg=no --enable-debug=${{ github.event.inputs.debug }} CFLAGS="-arch arm64 -target arm64-apple-macos11" CXXFLAGS="-arch arm64 -target arm64-apple-macos11" --enable-shared --disable-static --disable-examples - make - mkdir ../darwin-arm64 - ls -l src/libFLAC/.libs - cp src/libFLAC/.libs/libFLAC.8.dylib ../darwin-arm64/ - cd ../darwin-arm64 - install_name_tool -id @rpath/libFLAC.8.dylib libFLAC.8.dylib - - name: Upload macOS arm64 library - uses: actions/upload-artifact@v1 - with: - name: darwin-arm64 - path: darwin-arm64 + - name: Install dependencies + run: brew install wget + - name: Build libFLAC (macOS) + run: ./scripts/darwin.sh ${{ github.event.inputs.version }} + - name: Upload macOS x86_64 library + uses: actions/upload-artifact@v1 + with: + name: darwin-x86_64 + path: darwin-x86_64 + - name: Upload macOS arm64 library + uses: actions/upload-artifact@v1 + with: + name: darwin-arm64 + path: darwin-arm64 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 281edf8..38920b6 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,12 +11,11 @@ on: - develop jobs: - flake8: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - name: Lint the Python code - uses: TrueBrain/actions-flake8@master - with: - path: pyflac + - uses: actions/checkout@v3 + - name: Lint the Python code + uses: TrueBrain/actions-flake8@master + with: + path: pyflac diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9b62d25..a5d095b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,64 +11,66 @@ on: - develop jobs: - linux: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.7', '3.8', '3.9', '3.10' ] + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: | - sudo apt-get update -y - sudo apt-get install libsndfile1 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install coverage - - name: Run tests - run: coverage run setup.py test - - name: Run coveralls - uses: AndreMiras/coveralls-python-action@v20201129 - with: - parallel: true - flag-name: unittest + - uses: actions/checkout@v3 + - name: Install dependencies + run: | + sudo apt-get update -y + sudo apt-get install libsndfile1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install coverage + - name: Run tests + run: coverage run setup.py test + - name: Run coveralls + uses: AndreMiras/coveralls-python-action@v20201129 + with: + parallel: true + flag-name: unittest macos: runs-on: macos-latest steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v1 - with: - python-version: 3.9 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox tox-gh-actions - - name: Run tests - run: tox + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + python setup.py develop + - name: Run tests + run: tox windows: runs-on: windows-latest steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Check install - run: python setup.py install + - uses: actions/checkout@v3 + with: + submodules: recursive + - name: Check install + run: | + python setup.py develop + python setup.py install coverage: needs: linux runs-on: ubuntu-latest steps: - - name: coveralls - uses: AndreMiras/coveralls-python-action@v20201129 - with: - parallel-finished: true + - name: coveralls + uses: AndreMiras/coveralls-python-action@v20201129 + with: + parallel-finished: true diff --git a/.readthedocs.yml b/.readthedocs.yml index bb13ca6..f295f0b 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,6 +5,11 @@ # Required version: 2 +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py @@ -13,11 +18,9 @@ sphinx: formats: - pdf -# Optionally set the version of Python and requirements required to build your docs python: - version: 3.7 install: - - requirements: docs/requirements.txt + - requirements: docs/requirements.txt submodules: - exclude: all + exclude: all diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e1ac802..eca7004 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ pyFLAC Changelog ---------------- +**v2.2.0** + +* Updated FLAC library to v1.4.3. + See `FLAC Changelog `_. +* Added support for `int32` data +* Added `limit_min_bitrate` property. +* Removed support for Python 3.7 + **v2.1.0** * Added support for Linux `arm64` architectures diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f99b1db..9ff6e3e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -3,15 +3,14 @@ Contributing If you find any bugs or other things that need improvement, or would like to add additional features, please create an issue or a pull request at -https://github.com/sonos/pyFLAC -Contributions are always welcome! +https://github.com/sonos/pyFLAC. You get started, grab the latest version of the code from GitHub:: git clone https://github.com/sonos/pyFLAC.git cd pyflac -To build the package for development:: +To build the package:: python3 pyflac/builder/encoder.py @@ -22,7 +21,7 @@ you can also install your local copy with pip:: pip3 install . Before submitting a pull request, make sure all tests are passing and the -test coverage has not been decreased. +test coverage has not decreased. Testing ------- @@ -42,7 +41,8 @@ You can install it and the read the docs theme with:: To create the HTML pages, use:: - python3 setup.py build_sphinx + cd docs + make html The generated files will be available in the directory ``docs/_build/html``. diff --git a/README.rst b/README.rst index 1354121..4fa7c3a 100644 --- a/README.rst +++ b/README.rst @@ -5,8 +5,6 @@ :target: https://github.com/sonos/pyFLAC/actions/workflows/lint.yml .. image:: https://github.com/sonos/pyFLAC/actions/workflows/test.yml/badge.svg :target: https://github.com/sonos/pyFLAC/actions/workflows/test.yml -.. image:: https://github.com/sonos/pyFLAC/actions/workflows/build.yml/badge.svg - :target: https://github.com/sonos/pyFLAC/actions/workflows/build.yml .. image:: https://coveralls.io/repos/github/sonos/pyFLAC/badge.svg :target: https://coveralls.io/github/sonos/pyFLAC .. image:: https://readthedocs.org/projects/pyflac/badge @@ -46,7 +44,7 @@ Supported platforms - **macOS** (Intel/Apple Silicon) - **Linux** (x86_64/arm64) - **RPi** Zero/2/3/4 -- **Windows** 7/8/10 +- **Windows** 8/10/11 CLI diff --git a/docs/index.rst b/docs/index.rst index a931db4..2108372 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,8 +30,9 @@ of the compression to the terminal. :: Limitations ----------- -- pyFLAC currently only supports 16-bit audio. +- pyFLAC only supports 16-bit and 32-bit audio. - FLAC metadata handling is not implemented. +- The built in libraries do not include OGG support. API Reference diff --git a/examples/passthrough.py b/examples/passthrough.py index 341f5d4..eb329ae 100755 --- a/examples/passthrough.py +++ b/examples/passthrough.py @@ -9,7 +9,7 @@ # then back through through the FLAC decoder. It also asserts that the # uncompressed output is exactly equal to the original signal. # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ diff --git a/examples/stream.py b/examples/stream.py index 03c61ae..3ef2a24 100755 --- a/examples/stream.py +++ b/examples/stream.py @@ -10,7 +10,7 @@ # # Requires sounddevice. # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ diff --git a/pyflac/__init__.py b/pyflac/__init__.py index 08e5765..fb72601 100644 --- a/pyflac/__init__.py +++ b/pyflac/__init__.py @@ -4,13 +4,13 @@ # # pyFLAC # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ __title__ = 'pyFLAC' -__version__ = '2.1.0' +__version__ = '2.2.0' __all__ = [ 'StreamEncoder', 'FileEncoder', @@ -39,9 +39,9 @@ ffi = FFI() base_path = os.path.dirname(os.path.abspath(__file__)) if platform.architecture()[0] == '32bit': - libflac = ffi.dlopen(os.path.join(base_path, 'libraries', 'windows-i686', 'libFLAC-8.dll')) + libflac = ffi.dlopen(os.path.join(base_path, 'libraries', 'windows-i686', 'libFLAC.dll')) elif platform.architecture()[0] == '64bit': - libflac = ffi.dlopen(os.path.join(base_path, 'libraries', 'windows-x86_64', 'libFLAC-8.dll')) + libflac = ffi.dlopen(os.path.join(base_path, 'libraries', 'windows-x86_64', 'libFLAC.dll')) # flake8: noqa: F401 diff --git a/pyflac/__main__.py b/pyflac/__main__.py index 8487507..2a14dd7 100644 --- a/pyflac/__main__.py +++ b/pyflac/__main__.py @@ -5,7 +5,7 @@ # # pyFLAC file reader/writer # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2023, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -27,6 +27,7 @@ def get_args(): parser.add_argument('-c', '--compression-level', type=int, choices=range(0, 9), default=5, help='0 is the fastest compression, 5 is the default, 8 is the highest compression') parser.add_argument('-b', '--block-size', type=int, default=0, help='The block size') + parser.add_argument('-d', '--dtype', default='int16', help='The encoded data type (int16 or int32)') parser.add_argument('-v', '--verify', action='store_false', default=True, help='Verify the compressed data') args = parser.parse_args() return args @@ -44,6 +45,7 @@ def main(): input_file=args.input_file, output_file=args.output_file, blocksize=args.block_size, + dtype=args.dtype, compression_level=args.compression_level, verify=args.verify ) diff --git a/pyflac/builder/build_args.py b/pyflac/builder/build_args.py index b628974..d900eaf 100644 --- a/pyflac/builder/build_args.py +++ b/pyflac/builder/build_args.py @@ -4,7 +4,7 @@ # # pyFLAC builder # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2023, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -30,7 +30,7 @@ def get_build_kwargs(): else: architecture = 'darwin-x86_64' - build_kwargs['libraries'] = ['FLAC.8'] + build_kwargs['libraries'] = ['FLAC.12'] build_kwargs['library_dirs'] = [os.path.join(package_path, 'libraries', architecture)] build_kwargs['extra_link_args'] = ['-Wl,-rpath,@loader_path/libraries/' + architecture] @@ -46,7 +46,7 @@ def get_build_kwargs(): else: architecture = 'linux-x86_64' - build_kwargs['libraries'] = ['FLAC-8.3.0'] + build_kwargs['libraries'] = ['FLAC-12.1.0'] build_kwargs['library_dirs'] = [os.path.join(package_path, 'libraries', architecture)] build_kwargs['extra_link_args'] = ['-Wl,-rpath,$ORIGIN/libraries/' + architecture] @@ -56,7 +56,7 @@ def get_build_kwargs(): else: architecture = 'windows-x86_64' - build_kwargs['libraries'] = ['FLAC-8'] + build_kwargs['libraries'] = ['FLAC-12'] build_kwargs['library_dirs'] = [os.path.join(package_path, 'libraries', architecture)] else: raise RuntimeError('%s platform is not supported' % system) diff --git a/pyflac/builder/decoder.py b/pyflac/builder/decoder.py index f222596..3331804 100644 --- a/pyflac/builder/decoder.py +++ b/pyflac/builder/decoder.py @@ -4,7 +4,7 @@ # # pyFLAC decoder builder # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2023, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -105,7 +105,8 @@ FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, - FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM, + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA } FLAC__StreamDecoderErrorStatus; extern const char * const FLAC__StreamDecoderErrorStatusString[]; @@ -175,17 +176,26 @@ } FLAC__EntropyCodingMethod; typedef struct { - FLAC__int32 value; /**< The constant signal value. */ + FLAC__int64 value; /**< The constant signal value. */ } FLAC__Subframe_Constant; +typedef enum { + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32 = 0, + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64 = 1, +} FLAC__VerbatimSubframeDataType; + typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ + union { + const FLAC__int32 *int32; /**< A FLAC__int32 pointer to verbatim signal. */ + const FLAC__int64 *int64; /**< A FLAC__int64 pointer to verbatim signal. */ + } data; + FLAC__VerbatimSubframeDataType data_type; } FLAC__Subframe_Verbatim; typedef struct { FLAC__EntropyCodingMethod entropy_coding_method; uint32_t order; - FLAC__int32 warmup[4]; + FLAC__int64 warmup[4]; const FLAC__int32 *residual; } FLAC__Subframe_Fixed; @@ -195,7 +205,7 @@ uint32_t qlp_coeff_precision; int quantization_level; FLAC__int32 qlp_coeff[32]; - FLAC__int32 warmup[32]; + FLAC__int64 warmup[32]; const FLAC__int32 *residual; } FLAC__Subframe_LPC; diff --git a/pyflac/builder/encoder.py b/pyflac/builder/encoder.py index 0c894f0..f79ab5b 100644 --- a/pyflac/builder/encoder.py +++ b/pyflac/builder/encoder.py @@ -4,7 +4,7 @@ # # pyFLAC encoder builder # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2023, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -285,6 +285,7 @@ FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, uint32_t value); FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value); // GETTERS FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); @@ -307,6 +308,7 @@ uint32_t FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder); uint32_t FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder); FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); +FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder); // PROCESSING FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback write_callback, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderTellCallback tell_callback, FLAC__StreamEncoderMetadataCallback metadata_callback, void *client_data); diff --git a/pyflac/decoder.py b/pyflac/decoder.py index d58dabf..d848981 100644 --- a/pyflac/decoder.py +++ b/pyflac/decoder.py @@ -4,7 +4,7 @@ # # pyFLAC decoder # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -402,8 +402,8 @@ def _write_callback(_decoder, # -------------------------------------------------------------- bytes_per_frame = frame.header.blocksize * np.dtype(np.int32).itemsize - if frame.header.bits_per_sample != 16: - raise ValueError('Only int16 data type is supported') + if frame.header.bits_per_sample not in (16, 32): + raise ValueError('Only int16/int32 data type is supported') # -------------------------------------------------------------- # The buffer contains an array of pointers to decoded channels @@ -414,9 +414,11 @@ def _write_callback(_decoder, # -------------------------------------------------------------- for ch in range(0, frame.header.channels): cbuffer = _ffi.buffer(buffer[ch], bytes_per_frame) - channels.append( - np.frombuffer(cbuffer, dtype='int32').astype(np.int16) - ) + npbuffer = np.frombuffer(cbuffer, dtype='int32') + if frame.header.bits_per_sample == 16: + channels.append(npbuffer.astype(np.int16)) + elif frame.header.bits_per_sample == 32: + channels.append(npbuffer) output = np.column_stack(channels) decoder.write_callback( output, diff --git a/pyflac/encoder.py b/pyflac/encoder.py index 932ed37..fde1797 100644 --- a/pyflac/encoder.py +++ b/pyflac/encoder.py @@ -4,7 +4,7 @@ # # pyFLAC encoder # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -222,6 +222,14 @@ def _streamable_subset(self) -> bool: def _streamable_subset(self, value: bool): _lib.FLAC__stream_encoder_set_streamable_subset(self._encoder, value) + @property + def _limit_min_bitrate(self) -> bool: + return _lib.FLAC__stream_encoder_get_limit_min_bitrate(self._encoder) + + @_limit_min_bitrate.setter + def _limit_min_bitrate(self, value: bool): + _lib.FLAC__stream_encoder_set_limit_min_bitrate(self._encoder, value) + class StreamEncoder(_Encoder): """ @@ -254,6 +262,8 @@ class StreamEncoder(_Encoder): If a mismatch occurs, the `process` method will raise a `EncoderProcessException`. Note that this will slow the encoding process by the extra time required for decoding and comparison. + limit_min_bitrate (bool): If `True`, the encoder will not output frames which contain + only constant subframes, which can be beneficial for streaming applications. Examples: An example write callback which adds the encoded data to a queue for @@ -289,7 +299,8 @@ def __init__(self, compression_level: int = 5, blocksize: int = 0, streamable_subset: bool = True, - verify: bool = False): + verify: bool = False, + limit_min_bitrate: bool = False): super().__init__() self.write_callback = write_callback @@ -302,6 +313,7 @@ def __init__(self, self._compression_level = compression_level self._streamable_subset = streamable_subset self._verify = verify + self._limit_min_bitrate = limit_min_bitrate def _init(self): rc = _lib.FLAC__stream_encoder_init_stream( @@ -333,6 +345,8 @@ class FileEncoder(_Encoder): blocksize (int): The size of the block to be returned in the callback. The default is 0 which allows libFLAC to determine the best block size. + dtype (str): The data type to use in the FLAC encoder, either int16 or int32, + defaults to int16. streamable_subset (bool): Whether to use the streamable subset for encoding. If true the encoder will check settings for compatibility. If false, the settings may take advantage of the full range that the format allows. @@ -351,11 +365,15 @@ def __init__(self, output_file: Path = None, compression_level: int = 5, blocksize: int = 0, + dtype: str = 'int16', streamable_subset: bool = True, verify: bool = False): super().__init__() - self.__raw_audio, sample_rate = sf.read(str(input_file), dtype='int16') + if dtype not in ('int16', 'int32'): + raise ValueError('FLAC encoding data type must be either int16 or int32') + + self.__raw_audio, sample_rate = sf.read(str(input_file), dtype=dtype) if output_file: self.__output_file = output_file else: diff --git a/pyflac/include/FLAC/export.h b/pyflac/include/FLAC/export.h index 3e3e764..d14728a 100644 --- a/pyflac/include/FLAC/export.h +++ b/pyflac/include/FLAC/export.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,22 +49,40 @@ * This module contains \#defines and symbols for exporting function * calls, and providing version information and compiled-in features. * - * If you are compiling with MSVC and will link to the static library - * (libFLAC.lib) you should define FLAC__NO_DLL in your project to - * make sure the symbols are exported properly. + * If you are compiling for Windows (with Visual Studio or MinGW for + * example) and will link to the static library (libFLAC++.lib) you + * should define FLAC__NO_DLL in your project to make sure the symbols + * are exported properly. * * \{ */ -#if defined(FLAC__NO_DLL) -#define FLAC_API +/** This \#define is used internally in libFLAC and its headers to make + * sure the correct symbols are exported when working with shared + * libraries. On Windows, this \#define is set to __declspec(dllexport) + * when compiling libFLAC into a library and to __declspec(dllimport) + * when the headers are used to link to that DLL. On non-Windows systems + * it is used to set symbol visibility. + * + * Because of this, the define FLAC__NO_DLL must be defined when linking + * to libFLAC statically or linking will fail. + */ +/* This has grown quite complicated. FLAC__NO_DLL is used by MSVC sln + * files and CMake, which build either static or shared. autotools can + * build static, shared or **both**. Therefore, DLL_EXPORT, which is set + * by libtool, must override FLAC__NO_DLL on building shared components + */ +#if defined(_WIN32) -#elif defined(_WIN32) +#if defined(FLAC__NO_DLL) && !(defined(DLL_EXPORT)) +#define FLAC_API +#else #ifdef FLAC_API_EXPORTS #define FLAC_API __declspec(dllexport) #else #define FLAC_API __declspec(dllimport) #endif +#endif #elif defined(FLAC__USE_VISIBILITY_ATTR) #define FLAC_API __attribute__ ((visibility ("default"))) @@ -77,9 +95,9 @@ /** These \#defines will mirror the libtool-based library version number, see * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning */ -#define FLAC_API_VERSION_CURRENT 11 +#define FLAC_API_VERSION_CURRENT 13 #define FLAC_API_VERSION_REVISION 0 /**< see above */ -#define FLAC_API_VERSION_AGE 3 /**< see above */ +#define FLAC_API_VERSION_AGE 1 /**< see above */ #ifdef __cplusplus extern "C" { diff --git a/pyflac/include/FLAC/format.h b/pyflac/include/FLAC/format.h index 769ab8a..ef7c8b2 100644 --- a/pyflac/include/FLAC/format.h +++ b/pyflac/include/FLAC/format.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -60,7 +60,7 @@ extern "C" { * structures used by the rest of the interfaces. * * First, you should be familiar with the - * FLAC format. Many of the values here + * FLAC format. Many of the values here * follow directly from the specification. As a user of libFLAC, the * interesting parts really are the structures that describe the frame * header and metadata blocks. @@ -113,19 +113,16 @@ extern "C" { /** The maximum sample resolution permitted by libFLAC. * - * \warning * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, - * the reference encoder/decoder is currently limited to 24 bits because - * of prevalent 32-bit math, so make sure and use this value when - * appropriate. + * the reference encoder/decoder used to be limited to 24 bits. This + * value was used to signal that limit. */ -#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) +#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (32u) /** The maximum sample rate permitted by the format. The value is - * ((2 ^ 16) - 1) * 10; see FLAC format - * as to why. + * ((2 ^ 20) - 1) */ -#define FLAC__MAX_SAMPLE_RATE (655350u) +#define FLAC__MAX_SAMPLE_RATE (1048575u) /** The maximum LPC order permitted by the format. */ #define FLAC__MAX_LPC_ORDER (32u) @@ -228,7 +225,7 @@ typedef struct { */ } FLAC__EntropyCodingMethod_PartitionedRiceContents; -/** Header for a Rice partitioned residual. (c.f. format specification) +/** Header for a Rice partitioned residual. (c.f. format specification) */ typedef struct { @@ -250,7 +247,7 @@ extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCA extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER; /**< == (1<format specification) +/** Header for the entropy coding method. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethodType type; @@ -279,21 +276,31 @@ typedef enum { extern FLAC_API const char * const FLAC__SubframeTypeString[]; -/** CONSTANT subframe. (c.f. format specification) +/** CONSTANT subframe. (c.f. format specification) */ typedef struct { - FLAC__int32 value; /**< The constant signal value. */ + FLAC__int64 value; /**< The constant signal value. */ } FLAC__Subframe_Constant; +/** An enumeration of the possible verbatim subframe data types. */ +typedef enum { + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32, /**< verbatim subframe has 32-bit int */ + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64 /**< verbatim subframe has 64-bit int */ +} FLAC__VerbatimSubframeDataType; + -/** VERBATIM subframe. (c.f. format specification) +/** VERBATIM subframe. (c.f. format specification) */ typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ + union { + const FLAC__int32 *int32; /**< A FLAC__int32 pointer to verbatim signal. */ + const FLAC__int64 *int64; /**< A FLAC__int64 pointer to verbatim signal. */ + } data; + FLAC__VerbatimSubframeDataType data_type; } FLAC__Subframe_Verbatim; -/** FIXED subframe. (c.f. format specification) +/** FIXED subframe. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethod entropy_coding_method; @@ -302,7 +309,7 @@ typedef struct { uint32_t order; /**< The polynomial order. */ - FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + FLAC__int64 warmup[FLAC__MAX_FIXED_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; @@ -310,7 +317,7 @@ typedef struct { } FLAC__Subframe_Fixed; -/** LPC subframe. (c.f. format specification) +/** LPC subframe. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethod entropy_coding_method; @@ -328,7 +335,7 @@ typedef struct { FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /**< FIR filter coefficients. */ - FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + FLAC__int64 warmup[FLAC__MAX_LPC_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; @@ -339,7 +346,7 @@ extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ -/** FLAC subframe structure. (c.f. format specification) +/** FLAC subframe structure. (c.f. format specification) */ typedef struct { FLAC__SubframeType type; @@ -406,7 +413,7 @@ typedef enum { extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; -/** FLAC frame header structure. (c.f. format specification) +/** FLAC frame header structure. (c.f. format specification) */ typedef struct { uint32_t blocksize; @@ -455,7 +462,7 @@ extern FLAC_API const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) extern FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ -/** FLAC frame footer structure. (c.f. format specification) +/** FLAC frame footer structure. (c.f. format specification) */ typedef struct { FLAC__uint16 crc; @@ -468,7 +475,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ -/** FLAC frame structure. (c.f. format specification) +/** FLAC frame structure. (c.f. format specification) */ typedef struct { FLAC__FrameHeader header; @@ -489,25 +496,25 @@ typedef struct { typedef enum { FLAC__METADATA_TYPE_STREAMINFO = 0, - /**< STREAMINFO block */ + /**< STREAMINFO block */ FLAC__METADATA_TYPE_PADDING = 1, - /**< PADDING block */ + /**< PADDING block */ FLAC__METADATA_TYPE_APPLICATION = 2, - /**< APPLICATION block */ + /**< APPLICATION block */ FLAC__METADATA_TYPE_SEEKTABLE = 3, - /**< SEEKTABLE block */ + /**< SEEKTABLE block */ FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, - /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ + /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ FLAC__METADATA_TYPE_CUESHEET = 5, - /**< CUESHEET block */ + /**< CUESHEET block */ FLAC__METADATA_TYPE_PICTURE = 6, - /**< PICTURE block */ + /**< PICTURE block */ FLAC__METADATA_TYPE_UNDEFINED = 7, /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ @@ -524,7 +531,7 @@ typedef enum { extern FLAC_API const char * const FLAC__MetadataTypeString[]; -/** FLAC STREAMINFO structure. (c.f. format specification) +/** FLAC STREAMINFO structure. (c.f. format specification) */ typedef struct { uint32_t min_blocksize, max_blocksize; @@ -549,7 +556,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< /** The total stream length of the STREAMINFO block in bytes. */ #define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) -/** FLAC PADDING structure. (c.f. format specification) +/** FLAC PADDING structure. (c.f. format specification) */ typedef struct { int dummy; @@ -560,7 +567,7 @@ typedef struct { } FLAC__StreamMetadata_Padding; -/** FLAC APPLICATION structure. (c.f. format specification) +/** FLAC APPLICATION structure. (c.f. format specification) */ typedef struct { FLAC__byte id[4]; @@ -569,7 +576,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ -/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) +/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) */ typedef struct { FLAC__uint64 sample_number; @@ -597,7 +604,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; -/** FLAC SEEKTABLE structure. (c.f. format specification) +/** FLAC SEEKTABLE structure. (c.f. format specification) * * \note From the format specification: * - The seek points must be sorted by ascending sample number. @@ -615,7 +622,7 @@ typedef struct { } FLAC__StreamMetadata_SeekTable; -/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) +/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) * * For convenience, the APIs maintain a trailing NUL character at the end of * \a entry which is not counted toward \a length, i.e. @@ -629,7 +636,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ -/** FLAC VORBIS_COMMENT structure. (c.f. format specification) +/** FLAC VORBIS_COMMENT structure. (c.f. format specification) */ typedef struct { FLAC__StreamMetadata_VorbisComment_Entry vendor_string; @@ -641,7 +648,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS /** FLAC CUESHEET track index structure. (See the - * format specification for + * format specification for * the full description of each field.) */ typedef struct { @@ -660,7 +667,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN /** FLAC CUESHEET track structure. (See the - * format specification for + * format specification for * the full description of each field.) */ typedef struct { @@ -697,7 +704,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_ /** FLAC CUESHEET structure. (See the - * format specification + * format specification * for the full description of each field.) */ typedef struct { @@ -763,7 +770,7 @@ typedef enum { extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; /** FLAC PICTURE structure. (See the - * format specification + * format specification * for the full description of each field.) */ typedef struct { @@ -829,9 +836,9 @@ typedef struct { } FLAC__StreamMetadata_Unknown; -/** FLAC metadata block structure. (c.f. format specification) +/** FLAC metadata block structure. (c.f. format specification) */ -typedef struct { +typedef struct FLAC__StreamMetadata { FLAC__MetadataType type; /**< The type of the metadata block; used determine which member of the * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED diff --git a/pyflac/include/FLAC/ordinals.h b/pyflac/include/FLAC/ordinals.h index 75b830d..d61aac5 100644 --- a/pyflac/include/FLAC/ordinals.h +++ b/pyflac/include/FLAC/ordinals.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,26 +33,10 @@ #ifndef FLAC__ORDINALS_H #define FLAC__ORDINALS_H -#if defined(_MSC_VER) && _MSC_VER < 1600 - -/* Microsoft Visual Studio earlier than the 2010 version did not provide - * the 1999 ISO C Standard header file . - */ - -typedef signed __int8 FLAC__int8; -typedef signed __int16 FLAC__int16; -typedef signed __int32 FLAC__int32; -typedef signed __int64 FLAC__int64; -typedef unsigned __int8 FLAC__uint8; -typedef unsigned __int16 FLAC__uint16; -typedef unsigned __int32 FLAC__uint32; -typedef unsigned __int64 FLAC__uint64; - -#else - -/* For MSVC 2010 and everything else which provides . */ +/* This of course assumes C99 headers */ #include +#include typedef int8_t FLAC__int8; typedef uint8_t FLAC__uint8; @@ -64,22 +48,8 @@ typedef uint16_t FLAC__uint16; typedef uint32_t FLAC__uint32; typedef uint64_t FLAC__uint64; -#endif - typedef int FLAC__bool; typedef FLAC__uint8 FLAC__byte; - -#ifdef true -#undef true -#endif -#ifdef false -#undef false -#endif -#ifndef __cplusplus -#define true 1 -#define false 0 -#endif - #endif diff --git a/pyflac/include/FLAC/stream_decoder.h b/pyflac/include/FLAC/stream_decoder.h index 57215c5..93b5fd7 100644 --- a/pyflac/include/FLAC/stream_decoder.h +++ b/pyflac/include/FLAC/stream_decoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,7 @@ #define FLAC__STREAM_DECODER_H #include /* for FILE */ + #include "export.h" #include "format.h" @@ -41,7 +42,6 @@ extern "C" { #endif - /** \file include/FLAC/stream_decoder.h * * \brief @@ -70,8 +70,8 @@ extern "C" { * info see the \link flac_stream_decoder stream decoder \endlink module. */ -/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface - * \ingroup flac_decoder +/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder + * interface \ingroup flac_decoder * * \brief * This module contains the functions which implement the stream @@ -89,8 +89,9 @@ extern "C" { * prepare for decoding using * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file() for native FLAC, - * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() - * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC + * - FLAC__stream_decoder_init_ogg_stream() or + * FLAC__stream_decoder_init_ogg_FILE() or FLAC__stream_decoder_init_ogg_file() + * for Ogg FLAC * - The program calls the FLAC__stream_decoder_process_*() functions * to decode data, which subsequently calls the callbacks. * - The program finishes the decoding with FLAC__stream_decoder_finish(), @@ -168,7 +169,8 @@ extern "C" { * the STREAMINFO block. These functions allow you to tell the decoder * explicitly which blocks to parse and return via the metadata_callback * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), - * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), + * FLAC__stream_decoder_set_metadata_ignore() ... or + * FLAC__stream_decoder_set_metadata_ignore_all(), * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify * which blocks to return. Remember that metadata blocks can potentially * be big (for example, cover art) so filtering out the ones you don't @@ -194,52 +196,52 @@ extern "C" { * \{ */ - /** State values for a FLAC__StreamDecoder * - * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). + * The decoder's state can be obtained by calling + * FLAC__stream_decoder_get_state(). */ typedef enum { - FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, - /**< The decoder is ready to search for metadata. */ + FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, + /**< The decoder is ready to search for metadata. */ - FLAC__STREAM_DECODER_READ_METADATA, - /**< The decoder is ready to or is in the process of reading metadata. */ + FLAC__STREAM_DECODER_READ_METADATA, + /**< The decoder is ready to or is in the process of reading metadata. */ - FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, - /**< The decoder is ready to or is in the process of searching for the - * frame sync code. - */ + FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, + /**< The decoder is ready to or is in the process of searching for the + * frame sync code. + */ - FLAC__STREAM_DECODER_READ_FRAME, - /**< The decoder is ready to or is in the process of reading a frame. */ + FLAC__STREAM_DECODER_READ_FRAME, + /**< The decoder is ready to or is in the process of reading a frame. */ - FLAC__STREAM_DECODER_END_OF_STREAM, - /**< The decoder has reached the end of the stream. */ + FLAC__STREAM_DECODER_END_OF_STREAM, + /**< The decoder has reached the end of the stream. */ - FLAC__STREAM_DECODER_OGG_ERROR, - /**< An error occurred in the underlying Ogg layer. */ + FLAC__STREAM_DECODER_OGG_ERROR, + /**< An error occurred in the underlying Ogg layer. */ - FLAC__STREAM_DECODER_SEEK_ERROR, - /**< An error occurred while seeking. The decoder must be flushed - * with FLAC__stream_decoder_flush() or reset with - * FLAC__stream_decoder_reset() before decoding can continue. - */ + FLAC__STREAM_DECODER_SEEK_ERROR, + /**< An error occurred while seeking. The decoder must be flushed + * with FLAC__stream_decoder_flush() or reset with + * FLAC__stream_decoder_reset() before decoding can continue. + */ - FLAC__STREAM_DECODER_ABORTED, - /**< The decoder was aborted by the read or write callback. */ + FLAC__STREAM_DECODER_ABORTED, + /**< The decoder was aborted by the read or write callback. */ - FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. The decoder is in an invalid - * state and can no longer be used. - */ + FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. The decoder is in an invalid + * state and can no longer be used. + */ - FLAC__STREAM_DECODER_UNINITIALIZED - /**< The decoder is in the uninitialized state; one of the - * FLAC__stream_decoder_init_*() functions must be called before samples - * can be processed. - */ + FLAC__STREAM_DECODER_UNINITIALIZED + /**< The decoder is in the uninitialized state; one of the + * FLAC__stream_decoder_init_*() functions must be called before samples + * can be processed. + */ } FLAC__StreamDecoderState; @@ -248,36 +250,35 @@ typedef enum { * Using a FLAC__StreamDecoderState as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderStateString[]; /** Possible return values for the FLAC__stream_decoder_init_*() functions. */ typedef enum { - FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, - /**< Initialization was successful. */ + FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, + /**< Initialization was successful. */ - FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, - /**< The library was not compiled with support for the given container - * format. - */ + FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, + /**< The library was not compiled with support for the given container + * format. + */ - FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, - /**< A required callback was not supplied. */ + FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, + /**< A required callback was not supplied. */ - FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. */ + FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, + /**< An error occurred allocating memory. */ - FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, - /**< fopen() failed in FLAC__stream_decoder_init_file() or - * FLAC__stream_decoder_init_ogg_file(). */ + FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, + /**< fopen() failed in FLAC__stream_decoder_init_file() or + * FLAC__stream_decoder_init_ogg_file(). */ - FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED - /**< FLAC__stream_decoder_init_*() was called when the decoder was - * already initialized, usually because - * FLAC__stream_decoder_finish() was not called. - */ + FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED + /**< FLAC__stream_decoder_init_*() was called when the decoder was + * already initialized, usually because + * FLAC__stream_decoder_finish() was not called. + */ } FLAC__StreamDecoderInitStatus; @@ -286,29 +287,29 @@ typedef enum { * Using a FLAC__StreamDecoderInitStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderInitStatusString[]; /** Return values for the FLAC__StreamDecoder read callback. */ typedef enum { - FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, - /**< The read was OK and decoding can continue. */ + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, + /**< The read was OK and decoding can continue. */ - FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, - /**< The read was attempted while at the end of the stream. Note that - * the client must only return this value when the read callback was - * called when already at the end of the stream. Otherwise, if the read - * itself moves to the end of the stream, the client should still return - * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on - * the next read callback it should return - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count - * of \c 0. - */ + FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, + /**< The read was attempted while at the end of the stream. Note that + * the client must only return this value when the read callback was + * called when already at the end of the stream. Otherwise, if the read + * itself moves to the end of the stream, the client should still return + * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on + * the next read callback it should return + * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count + * of \c 0. + */ - FLAC__STREAM_DECODER_READ_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_READ_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the + process call. */ } FLAC__StreamDecoderReadStatus; @@ -317,21 +318,21 @@ typedef enum { * Using a FLAC__StreamDecoderReadStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderReadStatusString[]; /** Return values for the FLAC__StreamDecoder seek callback. */ typedef enum { - FLAC__STREAM_DECODER_SEEK_STATUS_OK, - /**< The seek was OK and decoding can continue. */ + FLAC__STREAM_DECODER_SEEK_STATUS_OK, + /**< The seek was OK and decoding can continue. */ - FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the + process call. */ - FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - /**< Client does not support seeking. */ + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED + /**< Client does not support seeking. */ } FLAC__StreamDecoderSeekStatus; @@ -340,21 +341,21 @@ typedef enum { * Using a FLAC__StreamDecoderSeekStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderSeekStatusString[]; /** Return values for the FLAC__StreamDecoder tell callback. */ typedef enum { - FLAC__STREAM_DECODER_TELL_STATUS_OK, - /**< The tell was OK and decoding can continue. */ + FLAC__STREAM_DECODER_TELL_STATUS_OK, + /**< The tell was OK and decoding can continue. */ - FLAC__STREAM_DECODER_TELL_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_TELL_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the + process call. */ - FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - /**< Client does not support telling the position. */ + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED + /**< Client does not support telling the position. */ } FLAC__StreamDecoderTellStatus; @@ -363,21 +364,21 @@ typedef enum { * Using a FLAC__StreamDecoderTellStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderTellStatusString[]; /** Return values for the FLAC__StreamDecoder length callback. */ typedef enum { - FLAC__STREAM_DECODER_LENGTH_STATUS_OK, - /**< The length call was OK and decoding can continue. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_OK, + /**< The length call was OK and decoding can continue. */ - FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, + /**< An unrecoverable error occurred. The decoder will return from the + process call. */ - FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - /**< Client does not support reporting the length. */ + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED + /**< Client does not support reporting the length. */ } FLAC__StreamDecoderLengthStatus; @@ -386,18 +387,18 @@ typedef enum { * Using a FLAC__StreamDecoderLengthStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderLengthStatusString[]; /** Return values for the FLAC__StreamDecoder write callback. */ typedef enum { - FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, - /**< The write was OK and decoding can continue. */ + FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, + /**< The write was OK and decoding can continue. */ - FLAC__STREAM_DECODER_WRITE_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ + FLAC__STREAM_DECODER_WRITE_STATUS_ABORT + /**< An unrecoverable error occurred. The decoder will return from the + process call. */ } FLAC__StreamDecoderWriteStatus; @@ -406,8 +407,7 @@ typedef enum { * Using a FLAC__StreamDecoderWriteStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderWriteStatusString[]; /** Possible values passed back to the FLAC__StreamDecoder error callback. * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- @@ -422,21 +422,28 @@ extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; * could be because the decoder encountered a valid frame made by a future * version of the encoder which it cannot parse, or because of a false * sync making it appear as though an encountered frame was generated by - * a future encoder. + * a future encoder. \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA is + * caused by finding data that doesn't fit a metadata block (too large + * or too small) or finding inconsistencies in the metadata, for example + * a PICTURE block with an image that exceeds the size of the metadata + * block. */ typedef enum { - FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, - /**< An error in the stream caused the decoder to lose synchronization. */ + FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, + /**< An error in the stream caused the decoder to lose synchronization. */ + + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, + /**< The decoder encountered a corrupted frame header. */ - FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, - /**< The decoder encountered a corrupted frame header. */ + FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, + /**< The frame's data did not match the CRC in the footer. */ - FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, - /**< The frame's data did not match the CRC in the footer. */ + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM, + /**< The decoder encountered reserved fields in use in the stream. */ - FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM - /**< The decoder encountered reserved fields in use in the stream. */ + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA + /**< The decoder encountered a corrupted metadata block. */ } FLAC__StreamDecoderErrorStatus; @@ -445,8 +452,7 @@ typedef enum { * Using a FLAC__StreamDecoderErrorStatus as the index to this array * will give the string equivalent. The contents should not be modified. */ -extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; - +extern FLAC_API const char *const FLAC__StreamDecoderErrorStatusString[]; /*********************************************************************** * @@ -461,8 +467,10 @@ struct FLAC__StreamDecoderPrivate; * for a detailed description. */ typedef struct { - struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ - struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ + struct FLAC__StreamDecoderProtected + *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__StreamDecoderPrivate + *private_; /* avoid the C++ keyword 'private' */ } FLAC__StreamDecoder; /** Signature for the read callback. @@ -478,7 +486,8 @@ typedef struct { * * Here is an example of a read callback for stdio streams: * \code - * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) + * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, + * FLAC__byte buffer[], size_t *bytes, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * if(*bytes > 0) { @@ -514,7 +523,9 @@ typedef struct { * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if * zero bytes were read and there is no more data to be read. */ -typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); +typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)( + const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, + void *client_data); /** Signature for the seek callback. * @@ -526,7 +537,8 @@ typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const F * * Here is an example of a seek callback for stdio streams: * \code - * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) + * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, + * FLAC__uint64 absolute_byte_offset, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * if(file == stdin) @@ -549,7 +561,9 @@ typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const F * \retval FLAC__StreamDecoderSeekStatus * The callee's return status. */ -typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); +typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)( + const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, + void *client_data); /** Signature for the tell callback. * @@ -561,7 +575,8 @@ typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const F * * Here is an example of a tell callback for stdio streams: * \code - * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) + * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, + * FLAC__uint64 *absolute_byte_offset, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * off_t pos; @@ -587,7 +602,9 @@ typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const F * \retval FLAC__StreamDecoderTellStatus * The callee's return status. */ -typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); +typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)( + const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, + void *client_data); /** Signature for the length callback. * @@ -598,7 +615,8 @@ typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const F * * Here is an example of a length callback for stdio streams: * \code - * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) + * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, + * FLAC__uint64 *stream_length, void *client_data) * { * FILE *file = ((MyClientData*)client_data)->file; * struct stat filestats; @@ -625,7 +643,9 @@ typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const F * \retval FLAC__StreamDecoderLengthStatus * The callee's return status. */ -typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); +typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)( + const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, + void *client_data); /** Signature for the EOF callback. * @@ -652,7 +672,8 @@ typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(con * \retval FLAC__bool * \c true if the currently at the end of the stream, else \c false. */ -typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); +typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)( + const FLAC__StreamDecoder *decoder, void *client_data); /** Signature for the write callback. * @@ -674,13 +695,16 @@ typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder * * samples of length \a frame->header.blocksize. * Channels will be ordered according to the FLAC * specification; see the documentation for the - * frame header. + * frame header. * \param client_data The callee's client data set through * FLAC__stream_decoder_init_*(). * \retval FLAC__StreamDecoderWriteStatus * The callee's return status. */ -typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); +typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)( + const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, + const FLAC__int32 *const buffer[], void *client_data); /** Signature for the metadata callback. * @@ -707,7 +731,9 @@ typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const * \param client_data The callee's client data set through * FLAC__stream_decoder_init_*(). */ -typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); +typedef void (*FLAC__StreamDecoderMetadataCallback)( + const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, + void *client_data); /** Signature for the error callback. * @@ -724,8 +750,9 @@ typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *d * \param client_data The callee's client data set through * FLAC__stream_decoder_init_*(). */ -typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); - +typedef void (*FLAC__StreamDecoderErrorCallback)( + const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, + void *client_data); /*********************************************************************** * @@ -750,7 +777,6 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); */ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); - /*********************************************************************** * * Public class method prototypes @@ -773,7 +799,8 @@ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); +FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number( + FLAC__StreamDecoder *decoder, long serial_number); /** Set the "MD5 signature checking" flag. If \c true, the decoder will * compute the MD5 signature of the unencoded audio data while decoding @@ -795,7 +822,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecod * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking( + FLAC__StreamDecoder *decoder, FLAC__bool value); /** Direct the decoder to pass on all metadata blocks of type \a type. * @@ -809,7 +837,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *d * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond( + FLAC__StreamDecoder *decoder, FLAC__MetadataType type); /** Direct the decoder to pass on all APPLICATION metadata blocks of the * given \a id. @@ -824,7 +853,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecode * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application( + FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); /** Direct the decoder to pass on all metadata blocks of any type. * @@ -836,7 +866,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__ * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); /** Direct the decoder to filter out all metadata blocks of type \a type. * @@ -850,7 +881,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDe * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore( + FLAC__StreamDecoder *decoder, FLAC__MetadataType type); /** Direct the decoder to filter out all APPLICATION metadata blocks of * the given \a id. @@ -865,7 +897,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); +FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application( + FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); /** Direct the decoder to filter out all metadata blocks of any type. * @@ -877,7 +910,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S * \retval FLAC__bool * \c false if the decoder is already initialized, else \c true. */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); /** Get the current decoder state. * @@ -887,7 +921,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDec * \retval FLAC__StreamDecoderState * The current decoder state. */ -FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); +FLAC_API FLAC__StreamDecoderState +FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); /** Get the current decoder state as a C string. * @@ -897,7 +932,8 @@ FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__Str * \retval const char * * The decoder state as a C string. Do not modify the contents. */ -FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); +FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string( + const FLAC__StreamDecoder *decoder); /** Get the "MD5 signature checking" flag. * This is the value of the setting, not whether or not the decoder is @@ -911,7 +947,8 @@ FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__ * \retval FLAC__bool * See above. */ -FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); /** Get the total number of samples in the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -923,7 +960,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDeco * \retval uint32_t * See above. */ -FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); +FLAC_API FLAC__uint64 +FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); /** Get the current number of channels in the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -935,7 +973,8 @@ FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamD * \retval uint32_t * See above. */ -FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); +FLAC_API uint32_t +FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); /** Get the current channel assignment in the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -947,7 +986,8 @@ FLAC_API uint32_t FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *d * \retval FLAC__ChannelAssignment * See above. */ -FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); +FLAC_API FLAC__ChannelAssignment +FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); /** Get the current sample resolution in the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -959,7 +999,8 @@ FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(con * \retval uint32_t * See above. */ -FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); +FLAC_API uint32_t +FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); /** Get the current sample rate in Hz of the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -971,7 +1012,8 @@ FLAC_API uint32_t FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDec * \retval uint32_t * See above. */ -FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); +FLAC_API uint32_t +FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); /** Get the current blocksize of the stream being decoded. * Will only be valid after decoding has started and will contain the @@ -983,7 +1025,8 @@ FLAC_API uint32_t FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder * \retval uint32_t * See above. */ -FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); +FLAC_API uint32_t +FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); /** Returns the decoder's current read position within the stream. * The position is the byte offset from the start of the stream. @@ -1004,7 +1047,19 @@ FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder * * or there was an error from the 'tell' callback or it returned * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. */ -FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); +FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position( + const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); + +/** Return client_data from decoder. + * The data pointed to by the pointer should not be modified. + * + * \param decoder A decoder instance. + * \retval const void * + * The callee's client data set through FLAC__stream_decoder_init_*(). + * Do not modify the contents. + */ +FLAC_API const void *FLAC__stream_decoder_get_client_data( + FLAC__StreamDecoder *decoder); /** Initialize the decoder instance to decode native FLAC streams. * @@ -1025,35 +1080,26 @@ FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamD * pointer must not be \c NULL. * \param seek_callback See FLAC__StreamDecoderSeekCallback. This * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly + * supported. If \a seek_callback is not \c NULL + * then a \a tell_callback, \a length_callback, and \a eof_callback must also be + * supplied. Alternatively, a dummy seek callback that just returns \c + * FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED may also be supplied, all though + * this is slightly less efficient for the decoder. \param tell_callback See + * FLAC__StreamDecoderTellCallback. This pointer may be \c NULL if not + * supported by the client. If \a seek_callback is not \c NULL then a \a + * tell_callback must also be supplied. Alternatively, a dummy tell callback + * that just returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED may also be + * supplied, all though this is slightly less efficient for the decoder. \param + * length_callback See FLAC__StreamDecoderLengthCallback. This pointer may + * be \c NULL if not supported by the client. If \a seek_callback is not \c + * NULL then a \a length_callback must also be supplied. Alternatively, a dummy + * length callback that just returns \c + * FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED may also be supplied, all + * though this is slightly less efficient for the decoder. \param eof_callback + * See FLAC__StreamDecoderEofCallback. This pointer may be \c NULL if not + * supported by the client. If \a seek_callback is not \c NULL then a \a + * eof_callback must also be supplied. Alternatively, a dummy length callback + * that just returns \c false may also be supplied, all though this is slightly * less efficient for the decoder. * \param write_callback See FLAC__StreamDecoderWriteCallback. This * pointer must not be \c NULL. @@ -1071,25 +1117,22 @@ FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamD * see FLAC__StreamDecoderInitStatus for the meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Initialize the decoder instance to decode Ogg FLAC streams. * * This flavor of initialization sets up the decoder to decode from a * FLAC stream in an Ogg container. I/O is performed via callbacks to the * client. For decoding from a plain file via filename or open FILE*, - * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() - * provide a simpler interface. + * FLAC__stream_decoder_init_ogg_file() and + * FLAC__stream_decoder_init_ogg_FILE() provide a simpler interface. * * This function should be called after FLAC__stream_decoder_new() and * FLAC__stream_decoder_set_*() but before any of the @@ -1106,35 +1149,26 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( * pointer must not be \c NULL. * \param seek_callback See FLAC__StreamDecoderSeekCallback. This * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly + * supported. If \a seek_callback is not \c NULL + * then a \a tell_callback, \a length_callback, and \a eof_callback must also be + * supplied. Alternatively, a dummy seek callback that just returns \c + * FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED may also be supplied, all though + * this is slightly less efficient for the decoder. \param tell_callback See + * FLAC__StreamDecoderTellCallback. This pointer may be \c NULL if not + * supported by the client. If \a seek_callback is not \c NULL then a \a + * tell_callback must also be supplied. Alternatively, a dummy tell callback + * that just returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED may also be + * supplied, all though this is slightly less efficient for the decoder. \param + * length_callback See FLAC__StreamDecoderLengthCallback. This pointer may + * be \c NULL if not supported by the client. If \a seek_callback is not \c + * NULL then a \a length_callback must also be supplied. Alternatively, a dummy + * length callback that just returns \c + * FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED may also be supplied, all + * though this is slightly less efficient for the decoder. \param eof_callback + * See FLAC__StreamDecoderEofCallback. This pointer may be \c NULL if not + * supported by the client. If \a seek_callback is not \c NULL then a \a + * eof_callback must also be supplied. Alternatively, a dummy length callback + * that just returns \c false may also be supplied, all though this is slightly * less efficient for the decoder. * \param write_callback See FLAC__StreamDecoderWriteCallback. This * pointer must not be \c NULL. @@ -1152,17 +1186,14 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( * see FLAC__StreamDecoderInitStatus for the meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback read_callback, + FLAC__StreamDecoderSeekCallback seek_callback, + FLAC__StreamDecoderTellCallback tell_callback, + FLAC__StreamDecoderLengthCallback length_callback, + FLAC__StreamDecoderEofCallback eof_callback, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Initialize the decoder instance to decode native FLAC files. * @@ -1202,13 +1233,10 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( * see FLAC__StreamDecoderInitStatus for the meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Initialize the decoder instance to decode Ogg FLAC files. * @@ -1252,22 +1280,23 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( * see FLAC__StreamDecoderInitStatus for the meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, FILE *file, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Initialize the decoder instance to decode native FLAC files. * * This flavor of initialization sets up the decoder to decode from a plain - * native FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + * native FLAC file. If POSIX fopen() semantics are not sufficient, you must + * use FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_decoder_new() and * FLAC__stream_decoder_set_*() but before any of the * FLAC__stream_decoder_process_*() functions. Will set and return the @@ -1275,40 +1304,36 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( * if initialization succeeded. * * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + * \param filename The name of the file to decode from. The file + * will be opened with fopen(). Use \c NULL to decode from \c stdin. Note that + * \c stdin is not seekable. \param write_callback See + * FLAC__StreamDecoderWriteCallback. This pointer must not be \c NULL. \param + * metadata_callback See FLAC__StreamDecoderMetadataCallback. This pointer may + * be \c NULL if the callback is not desired. \param error_callback See + * FLAC__StreamDecoderErrorCallback. This pointer must not be \c NULL. \param + * client_data This value will be supplied to callbacks in their \a + * client_data argument. \assert \code decoder != NULL \endcode \retval + * FLAC__StreamDecoderInitStatus \c FLAC__STREAM_DECODER_INIT_STATUS_OK if + * initialization was successful; see FLAC__StreamDecoderInitStatus for the + * meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Initialize the decoder instance to decode Ogg FLAC files. * * This flavor of initialization sets up the decoder to decode from a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() - * and provide callbacks for the I/O. + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, you must use + * FLAC__stream_decoder_init_ogg_FILE(), or + * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. + * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. * * This function should be called after FLAC__stream_decoder_new() and * FLAC__stream_decoder_set_*() but before any of the @@ -1321,32 +1346,24 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. * * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. + * \param filename The name of the file to decode from. The file + * will be opened with fopen(). Use \c NULL to decode from \c stdin. Note that + * \c stdin is not seekable. \param write_callback See + * FLAC__StreamDecoderWriteCallback. This pointer must not be \c NULL. \param + * metadata_callback See FLAC__StreamDecoderMetadataCallback. This pointer may + * be \c NULL if the callback is not desired. \param error_callback See + * FLAC__StreamDecoderErrorCallback. This pointer must not be \c NULL. \param + * client_data This value will be supplied to callbacks in their \a + * client_data argument. \assert \code decoder != NULL \endcode \retval + * FLAC__StreamDecoderInitStatus \c FLAC__STREAM_DECODER_INIT_STATUS_OK if + * initialization was successful; see FLAC__StreamDecoderInitStatus for the + * meanings of other return values. */ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); + FLAC__StreamDecoder *decoder, const char *filename, + FLAC__StreamDecoderWriteCallback write_callback, + FLAC__StreamDecoderMetadataCallback metadata_callback, + FLAC__StreamDecoderErrorCallback error_callback, void *client_data); /** Finish the decoding process. * Flushes the decoding buffer, releases resources, resets the decoder @@ -1447,7 +1464,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); * information about the decoder, check the decoder state with * FLAC__stream_decoder_get_state(). */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); /** Decode until the end of the metadata. * This version instructs the decoder to decode from the current position @@ -1468,7 +1486,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *dec * information about the decoder, check the decoder state with * FLAC__stream_decoder_get_state(). */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata( + FLAC__StreamDecoder *decoder); /** Decode until the end of the stream. * This version instructs the decoder to decode from the current position @@ -1489,7 +1508,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__Str * information about the decoder, check the decoder state with * FLAC__stream_decoder_get_state(). */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); /** Skip one audio frame. * This version instructs the decoder to 'skip' a single frame and stop, @@ -1530,7 +1550,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__Strea * information about the decoder, check the decoder state with * FLAC__stream_decoder_get_state(). */ -FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); +FLAC_API FLAC__bool +FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); /** Flush the input and seek to an absolute sample. * Decoding will resume at the given sample. Note that because of @@ -1548,7 +1569,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder * * \retval FLAC__bool * \c true if successful, else \c false. */ -FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); +FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute( + FLAC__StreamDecoder *decoder, FLAC__uint64 sample); /* \} */ diff --git a/pyflac/include/FLAC/stream_encoder.h b/pyflac/include/FLAC/stream_encoder.h index d154ac4..a0d0263 100644 --- a/pyflac/include/FLAC/stream_encoder.h +++ b/pyflac/include/FLAC/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -129,8 +129,8 @@ extern "C" { * Unlike the decoders, the stream encoder has many options that can * affect the speed and compression ratio. When setting these parameters * you should have some basic knowledge of the format (see the - * user-level documentation - * or the formal description). The + * user-level documentation + * or the formal description). The * FLAC__stream_encoder_set_*() functions themselves do not validate the * values as many are interdependent. The FLAC__stream_encoder_init_*() * functions will do this, so make sure to pay attention to the state @@ -311,8 +311,7 @@ typedef enum { FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, /**< The encoder has an invalid setting for bits-per-sample. - * FLAC supports 4-32 bps but the reference encoder currently supports - * only up to 24 bps. + * FLAC supports 4-32 bps. */ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, @@ -331,7 +330,7 @@ typedef enum { /**< The specified block size is less than the maximum LPC order. */ FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, - /**< The encoder is bound to the Subset but other settings violate it. */ + /**< The encoder is bound to the Subset but other settings violate it. */ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, /**< The metadata input to the encoder is invalid, in one of the following ways: @@ -743,7 +742,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncod */ FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); -/** Set the Subset flag. If \c true, +/** Set the Subset flag. If \c true, * the encoder will comply with the Subset and will check the * settings during FLAC__stream_encoder_init_*() to see if all settings * comply. If \c false, the settings may take advantage of the full @@ -843,15 +842,15 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en * max residual partition order * rice parameter search dist * - * 0 false false tukey(0.5) 0 0 false false false 0 3 0 - * 1 true true tukey(0.5) 0 0 false false false 0 3 0 - * 2 true false tukey(0.5) 0 0 false false false 0 3 0 - * 3 false false tukey(0.5) 6 0 false false false 0 4 0 - * 4 true true tukey(0.5) 8 0 false false false 0 4 0 - * 5 true false tukey(0.5) 8 0 false false false 0 5 0 - * 6 true false tukey(0.5);partial_tukey(2) 8 0 false false false 0 6 0 - * 7 true false tukey(0.5);partial_tukey(2) 12 0 false false false 0 6 0 - * 8 true false tukey(0.5);partial_tukey(2);punchout_tukey(3) 12 0 false false false 0 6 0 + * 0 false false tukey(0.5) 0 0 false false false 0 3 0 + * 1 true true tukey(0.5) 0 0 false false false 0 3 0 + * 2 true false tukey(0.5) 0 0 false false false 0 3 0 + * 3 false false tukey(0.5) 6 0 false false false 0 4 0 + * 4 true true tukey(0.5) 8 0 false false false 0 4 0 + * 5 true false tukey(0.5) 8 0 false false false 0 5 0 + * 6 true false subdivide_tukey(2) 8 0 false false false 0 6 0 + * 7 true false subdivide_tukey(2) 12 0 false false false 0 6 0 + * 8 true false subdivide_tukey(3) 12 0 false false false 0 6 0 * * * \default \c 5 @@ -921,7 +920,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]), - * \c punchout_tukey(n[/ov[/P]]), \c welch. + * \c punchout_tukey(n[/ov[/P]]), \c subdivide_tukey(n[/P]), \c welch. * * For \c gauss(STDDEV), STDDEV specifies the standard deviation * (0Subset flag. * * \param encoder An encoder instance to query. * \assert @@ -1429,6 +1458,16 @@ FLAC_API uint32_t FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC */ FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); +/** Get the "limit_min_bitrate" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_limit_min_bitrate(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder); + /** Initialize the encoder instance to encode native FLAC streams. * * This flavor of initialization sets up the encoder to encode to a @@ -1633,11 +1672,15 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__ /** Initialize the encoder instance to encode native FLAC files. * * This flavor of initialization sets up the encoder to encode to a plain - * FLAC file. If POSIX fopen() semantics are not sufficient (for example, - * with Unicode filenames on Windows), you must use + * FLAC file. If POSIX fopen() semantics are not sufficient you must use * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_encoder_new() and * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() * or FLAC__stream_encoder_process_interleaved(). @@ -1665,11 +1708,15 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__Stre /** Initialize the encoder instance to encode Ogg FLAC files. * * This flavor of initialization sets up the encoder to encode to a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example, - * with Unicode filenames on Windows), you must use + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, you must use * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_encoder_new() and * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() * or FLAC__stream_encoder_process_interleaved(). @@ -1734,7 +1781,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); * * For applications where channel order is important, channels must * follow the order as described in the - * frame header. + * frame header. * * \param encoder An initialized encoder instance in the OK state. * \param buffer An array of pointers to each channel's signal. @@ -1763,7 +1810,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c * * For applications where channel order is important, channels must * follow the order as described in the - * frame header. + * frame header. * * \param encoder An initialized encoder instance in the OK state. * \param buffer An array of channel-interleaved data (see above). diff --git a/pyflac/libraries/LICENSE b/pyflac/libraries/LICENSE index d8295f0..6dc5042 100644 --- a/pyflac/libraries/LICENSE +++ b/pyflac/libraries/LICENSE @@ -1,5 +1,5 @@ Copyright (C) 2000-2009 Josh Coalson -Copyright (C) 2011-2016 Xiph.Org Foundation +Copyright (C) 2020-2016 Xiph.Org Foundation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/pyflac/libraries/darwin-arm64/libFLAC.12.dylib b/pyflac/libraries/darwin-arm64/libFLAC.12.dylib new file mode 100644 index 0000000..cb99264 Binary files /dev/null and b/pyflac/libraries/darwin-arm64/libFLAC.12.dylib differ diff --git a/pyflac/libraries/darwin-arm64/libFLAC.8.dylib b/pyflac/libraries/darwin-arm64/libFLAC.8.dylib deleted file mode 100644 index 304d556..0000000 Binary files a/pyflac/libraries/darwin-arm64/libFLAC.8.dylib and /dev/null differ diff --git a/pyflac/libraries/darwin-x86_64/libFLAC.12.dylib b/pyflac/libraries/darwin-x86_64/libFLAC.12.dylib new file mode 100644 index 0000000..9d72911 Binary files /dev/null and b/pyflac/libraries/darwin-x86_64/libFLAC.12.dylib differ diff --git a/pyflac/libraries/darwin-x86_64/libFLAC.8.dylib b/pyflac/libraries/darwin-x86_64/libFLAC.8.dylib deleted file mode 100644 index 38b0d46..0000000 Binary files a/pyflac/libraries/darwin-x86_64/libFLAC.8.dylib and /dev/null differ diff --git a/pyflac/libraries/linux-arm64/libFLAC-12.1.0.so b/pyflac/libraries/linux-arm64/libFLAC-12.1.0.so new file mode 100755 index 0000000..7fd41ec Binary files /dev/null and b/pyflac/libraries/linux-arm64/libFLAC-12.1.0.so differ diff --git a/pyflac/libraries/linux-arm64/libFLAC-8.3.0.so b/pyflac/libraries/linux-arm64/libFLAC-8.3.0.so deleted file mode 100644 index 3cde363..0000000 Binary files a/pyflac/libraries/linux-arm64/libFLAC-8.3.0.so and /dev/null differ diff --git a/pyflac/libraries/linux-x86_64/libFLAC-12.1.0.so b/pyflac/libraries/linux-x86_64/libFLAC-12.1.0.so new file mode 100755 index 0000000..b4436f4 Binary files /dev/null and b/pyflac/libraries/linux-x86_64/libFLAC-12.1.0.so differ diff --git a/pyflac/libraries/linux-x86_64/libFLAC-8.3.0.so b/pyflac/libraries/linux-x86_64/libFLAC-8.3.0.so deleted file mode 100644 index c65f780..0000000 Binary files a/pyflac/libraries/linux-x86_64/libFLAC-8.3.0.so and /dev/null differ diff --git a/pyflac/libraries/raspbian-armv6z/libFLAC-8.3.0.so b/pyflac/libraries/raspbian-armv6z/libFLAC-8.3.0.so deleted file mode 100644 index 211ac81..0000000 Binary files a/pyflac/libraries/raspbian-armv6z/libFLAC-8.3.0.so and /dev/null differ diff --git a/pyflac/libraries/raspbian-armv7a/libFLAC-12.1.0.so b/pyflac/libraries/raspbian-armv7a/libFLAC-12.1.0.so new file mode 100755 index 0000000..4cccf38 Binary files /dev/null and b/pyflac/libraries/raspbian-armv7a/libFLAC-12.1.0.so differ diff --git a/pyflac/libraries/raspbian-armv7a/libFLAC-8.3.0.so b/pyflac/libraries/raspbian-armv7a/libFLAC-8.3.0.so deleted file mode 100644 index e11f91b..0000000 Binary files a/pyflac/libraries/raspbian-armv7a/libFLAC-8.3.0.so and /dev/null differ diff --git a/pyflac/libraries/windows-i686/FLAC-8.lib b/pyflac/libraries/windows-i686/FLAC-12.lib similarity index 59% rename from pyflac/libraries/windows-i686/FLAC-8.lib rename to pyflac/libraries/windows-i686/FLAC-12.lib index 3b09a12..60c2c9a 100644 Binary files a/pyflac/libraries/windows-i686/FLAC-8.lib and b/pyflac/libraries/windows-i686/FLAC-12.lib differ diff --git a/pyflac/libraries/windows-i686/libFLAC-8.dll b/pyflac/libraries/windows-i686/libFLAC-8.dll deleted file mode 100644 index 60a088d..0000000 Binary files a/pyflac/libraries/windows-i686/libFLAC-8.dll and /dev/null differ diff --git a/pyflac/libraries/windows-i686/libFLAC.dll b/pyflac/libraries/windows-i686/libFLAC.dll new file mode 100644 index 0000000..048298c Binary files /dev/null and b/pyflac/libraries/windows-i686/libFLAC.dll differ diff --git a/pyflac/libraries/windows-x86_64/FLAC-8.lib b/pyflac/libraries/windows-x86_64/FLAC-12.lib similarity index 59% rename from pyflac/libraries/windows-x86_64/FLAC-8.lib rename to pyflac/libraries/windows-x86_64/FLAC-12.lib index 9737716..98025d0 100644 Binary files a/pyflac/libraries/windows-x86_64/FLAC-8.lib and b/pyflac/libraries/windows-x86_64/FLAC-12.lib differ diff --git a/pyflac/libraries/windows-x86_64/libFLAC-8.dll b/pyflac/libraries/windows-x86_64/libFLAC-8.dll deleted file mode 100644 index fb694d6..0000000 Binary files a/pyflac/libraries/windows-x86_64/libFLAC-8.dll and /dev/null differ diff --git a/pyflac/libraries/windows-x86_64/libFLAC.dll b/pyflac/libraries/windows-x86_64/libFLAC.dll new file mode 100644 index 0000000..9cbe9e5 Binary files /dev/null and b/pyflac/libraries/windows-x86_64/libFLAC.dll differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ae42b9e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,41 @@ +# ------------------------------------------------------------------------------ +# +# pyFLAC +# +# Copyright (c) 2020-2023, Sonos, Inc. +# All rights reserved. +# +# ------------------------------------------------------------------------------ +[build-system] +requires = ["setuptools>=42", "cffi>=1.4.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "pyFLAC" +version = "2.2.0" +description = "A Python wrapper for libFLAC" +readme = "README.rst" +authors = [{ name = "Joe Todd", email = "joe.todd@sonos.com" }] +requires-python = ">=3.8" +license = { text = "Apache-2.0" } +keywords = ["lossless", "compression", "flac", "bindings", "audio"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Multimedia :: Sound/Audio", +] +dependencies = ["cffi>=1.4.0", "numpy>=1.22", "SoundFile>=0.11"] + +[project.scripts] +pyflac = "pyflac.__main__:main" + +[tool.setuptools.packages.find] +include = ["pyflac*"] +exclude = ["assets", "docs", "scripts"] diff --git a/scripts/darwin.sh b/scripts/darwin.sh new file mode 100755 index 0000000..ed2afae --- /dev/null +++ b/scripts/darwin.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +echo "Building for x86_64..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-darwin-x86_64 +cd flac-$1-darwin-x86_64 +CC=clang ./configure --with-ogg=no --enable-debug=no --enable-shared --disable-static --disable-examples +make +mkdir ../darwin-x86_64 +cp src/libFLAC/.libs/libFLAC.12.dylib ../darwin-x86_64/ +cd ../darwin-x86_64 +install_name_tool -id @rpath/libFLAC.12.dylib libFLAC.12.dylib +llvm-strip libFLAC.12.dylib + +echo "Building for arm64..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-darwin-arm64 +cd flac-$1-darwin-arm64 +./configure --host=aarch64-apple-darwin --with-ogg=no --enable-debug=no CFLAGS="-arch arm64 -target arm64-apple-macos11" CXXFLAGS="-arch arm64 -target arm64-apple-macos11" --enable-shared --disable-static --disable-examples +make +mkdir ../darwin-arm64 +cp src/libFLAC/.libs/libFLAC.12.dylib ../darwin-arm64/ +cd ../darwin-arm64 +install_name_tool -id @rpath/libFLAC.12.dylib libFLAC.12.dylib +llvm-strip libFLAC.12.dylib diff --git a/scripts/dist.sh b/scripts/dist.sh new file mode 100755 index 0000000..efcd8b1 --- /dev/null +++ b/scripts/dist.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -rf dist +python3 pyflac/builder/encoder.py +python3 pyflac/builder/decoder.py +python3 setup.py sdist diff --git a/scripts/docs.sh b/scripts/docs.sh new file mode 100755 index 0000000..5ef0700 --- /dev/null +++ b/scripts/docs.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cd docs +make html +cd .. +python3 -m http.server --directory docs/_build/html diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..21df02d --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +python3 pyflac/builder/encoder.py +python3 pyflac/builder/decoder.py +pip3 install -e . diff --git a/scripts/linux.sh b/scripts/linux.sh new file mode 100755 index 0000000..4d638f1 --- /dev/null +++ b/scripts/linux.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +echo "Building for x86_64..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-linux-x86_64 +cd flac-$1-linux-x86_64 +CC=clang ./configure --with-ogg=no --enable-debug=no --enable-shared --disable-static --disable-examples +make +mkdir ../linux-x86_64 +cp src/libFLAC/.libs/libFLAC.so.12.1.0 ../linux-x86_64/libFLAC-12.1.0.so +cd ../linux-x86_64 +patchelf --set-soname libFLAC-12.1.0.so libFLAC-12.1.0.so +llvm-strip-8 libFLAC-12.1.0.so + +echo "Building for arm64..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-linux-arm64 +cd flac-$1-linux-arm64 +CC=clang ./configure --host=aarch64-linux-gnu --with-ogg=no --enable-debug=no --enable-shared --disable-static --disable-examples +make +mkdir ../linux-arm64 +cp src/libFLAC/.libs/libFLAC.so.12.1.0 ../linux-arm64/libFLAC-12.1.0.so +cd ../linux-arm64 +patchelf --set-soname libFLAC-12.1.0.so libFLAC-12.1.0.so +llvm-strip-8 libFLAC-12.1.0.so diff --git a/scripts/raspbian.sh b/scripts/raspbian.sh new file mode 100755 index 0000000..2795f8f --- /dev/null +++ b/scripts/raspbian.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +echo "Building for armv7..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-raspbian-armv7a +cd flac-$1-raspbian-armv7a +./configure --host=arm-linux-gnueabihf --with-ogg=no --enable-debug=no CFLAGS="-mfpu=neon -march=armv7-a -mfloat-abi=hard" --enable-shared --disable-static --disable-examples +make +mkdir ../raspbian-armv7a +cp src/libFLAC/.libs/libFLAC.so.12.1.0 ../raspbian-armv7a/libFLAC-12.1.0.so +cd ../raspbian-armv7a +patchelf --set-soname libFLAC-12.1.0.so libFLAC-12.1.0.so +arm-linux-gnueabihf-strip libFLAC-12.1.0.so + +echo "Building for armv6l..." + +# untested +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-raspbian-armv6l +cd flac-$1-raspbian-armv6l +./configure --host=arm-linux-gnueabihf --with-ogg=no --enable-debug=no CFLAGS="-mfpu=neon -march=armv6l -mfloat-abi=hard" --enable-shared --disable-static --disable-examples +make +mkdir ../raspbian-armv6l +cp src/libFLAC/.libs/libFLAC.so.12.1.0 ../raspbian-armv6l/libFLAC-12.1.0.so +cd ../raspbian-armv6l +patchelf --set-soname libFLAC-12.1.0.so libFLAC-12.1.0.so +arm-linux-gnueabihf-strip libFLAC-12.1.0.so diff --git a/scripts/windows.sh b/scripts/windows.sh new file mode 100755 index 0000000..845b880 --- /dev/null +++ b/scripts/windows.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +echo "Building for x86_64..." +echo "Now just download the -win.zip files from FLAC downloads instead to get the DLL" +echo "And download from https://packages.msys2.org/package/" +echo "Renaming libFLAC.dll.a to FLAC-12.lib" +exit + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-windows-x86_64 +cd flac-$1-windows-x86_64 +./configure --host=x86_64-w64-mingw32 --with-ogg=no --enable-debug=no --enable-shared --disable-static --disable-examples +make +mkdir ../windows-x86_64 +cp src/libFLAC/.libs/libFLAC-12.dll ../windows-x86_64/ +cp src/libFLAC/.libs/libFLAC.dll.a ../windows-x86_64/FLAC-12.lib + +echo "Building for i686..." + +cd /tmp +wget https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$1.tar.xz +tar xvf flac-$1.tar.xz + +mv flac-$1 flac-$1-windows-i686 +cd flac-$1-windows-i686 +./configure --host=i686-w64-mingw32 --with-ogg=no --enable-debug=no --enable-shared --disable-static --disable-examples +make +mkdir ../windows-i686 +cp src/libFLAC/.libs/libFLAC-12.dll ../windows-i686/ +cp src/libFLAC/.libs/libFLAC.dll.a ../windows-i686/FLAC-12.lib diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 94b60b5..0000000 --- a/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[metadata] -description_file = README.rst - -[build_sphinx] -source-dir = docs -build-dir = docs/_build -all_files = 1 - -[upload_sphinx] -upload-dir = docs/_build/html - -[flake8] -max-line-length = 120 diff --git a/setup.py b/setup.py index fad452a..90a5b69 100644 --- a/setup.py +++ b/setup.py @@ -4,64 +4,22 @@ # # pyFLAC # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2023, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ -import os -import re -from setuptools import setup, find_packages - -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() - -vstr = read('pyflac/__init__.py') -regex = r"^__version__ = ['\"]([^'\"]*)['\"]" -version = re.search(regex, vstr, re.M) -__version__ = version.group(1) +from setuptools import setup setup( - name='pyFLAC', - version=__version__, - description='A Python wrapper for libFLAC', - long_description=open('README.rst').read(), - long_description_content_type='text/x-rst', - author='Sonos, Inc', - author_email='joe.todd@sonos.com', - license='Apache License 2.0', - url='http://pyflac.readthedocs.io/en/latest/', - download_url='https://github.com/sonos/pyFLAC/archive/v' + __version__ + '.tar.gz', - packages=find_packages(), - include_package_data=True, - setup_requires=['cffi>=1.4.0'], + setup_requires=["cffi>=1.4.0"], cffi_modules=[ - 'pyflac/builder/encoder.py:ffibuilder', - 'pyflac/builder/decoder.py:ffibuilder' + "pyflac/builder/encoder.py:ffibuilder", + "pyflac/builder/decoder.py:ffibuilder", ], install_requires=[ - 'cffi>=1.4.0', - 'numpy>=1.22; python_version >= "3.8"', - 'numpy<1.22; python_version < "3.8.0"', - 'SoundFile>=0.11', - ], - test_suite='tests', - python_requires='>=3.7', - entry_points={ - 'console_scripts': [ - 'pyflac = pyflac.__main__:main', - ], - }, - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Topic :: Multimedia :: Sound/Audio', + "cffi>=1.4.0", + "numpy>=1.22", + "SoundFile>=0.11", ], ) diff --git a/tests/data/32bit.flac b/tests/data/32bit.flac new file mode 100644 index 0000000..9a3397a Binary files /dev/null and b/tests/data/32bit.flac differ diff --git a/tests/data/32bit.wav b/tests/data/32bit.wav new file mode 100644 index 0000000..62adc66 Binary files /dev/null and b/tests/data/32bit.wav differ diff --git a/tests/test_decoder.py b/tests/test_decoder.py index 8c4fbe4..acfdc88 100644 --- a/tests/test_decoder.py +++ b/tests/test_decoder.py @@ -4,7 +4,7 @@ # # pyFLAC decoder test suite # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -120,6 +120,7 @@ def test_process_mono_file(self): """ Test that a mono FLAC file can be processed """ test_file = pathlib.Path(__file__).parent / 'data/mono.flac' self.default_kwargs['input_file'] = test_file + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) self.decoder = FileDecoder(**self.default_kwargs) self.assertIsNotNone(self.decoder.process()) @@ -127,6 +128,7 @@ def test_process_stereo_file(self): """ Test that a stereo FLAC file can be processed """ test_file = pathlib.Path(__file__).parent / 'data/stereo.flac' self.default_kwargs['input_file'] = test_file + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) self.decoder = FileDecoder(**self.default_kwargs) self.assertIsNotNone(self.decoder.process()) @@ -138,6 +140,14 @@ def test_process_5_1_surround_file(self): self.decoder = FileDecoder(**self.default_kwargs) self.assertIsNotNone(self.decoder.process()) + def test_process_32_bit_file(self): + """ Test that a 32-bit FLAC file can be processed """ + test_file = pathlib.Path(__file__).parent / 'data/32bit.flac' + self.default_kwargs['input_file'] = test_file + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) + self.decoder = FileDecoder(**self.default_kwargs) + self.assertIsNotNone(self.decoder.process()) + if __name__ == '__main__': unittest.main(failfast=True) diff --git a/tests/test_encoder.py b/tests/test_encoder.py index 33140a6..f84dca7 100644 --- a/tests/test_encoder.py +++ b/tests/test_encoder.py @@ -4,7 +4,7 @@ # # pyFLAC encoder test suite # -# Copyright (c) 2011-2021, Sonos, Inc. +# Copyright (c) 2020-2021, Sonos, Inc. # All rights reserved. # # ------------------------------------------------------------------------------ @@ -76,6 +76,12 @@ def test_compression_level(self): test_compression_level = 8 self.encoder._compression_level = test_compression_level + def test_limit_min_bitrate(self): + """ Test that the limit_min_bitrate setter returns the same value from libFLAC """ + self.assertFalse(self.encoder._limit_min_bitrate) + self.encoder._limit_min_bitrate = True + self.assertTrue(self.encoder._limit_min_bitrate) + def test_state(self): """ Test that the state returns uninitialised """ self.assertEqual(self.encoder.state, EncoderState.UNINITIALIZED) @@ -101,7 +107,7 @@ def setUp(self): 'sample_rate': DEFAULT_SAMPLE_RATE, 'blocksize': DEFAULT_BLOCKSIZE, 'write_callback': self._write_callback, - 'verify': True + 'verify': True, } def tearDown(self): @@ -131,7 +137,7 @@ def _metadata_callback(self, metadata): self.metadata_callback_called = True def test_invalid_sample_rate(self): - self.default_kwargs['sample_rate'] = 1000000 + self.default_kwargs['sample_rate'] = 2000000 self.encoder = StreamEncoder(**self.default_kwargs) with self.assertRaisesRegex(EncoderInitException, 'FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE'): self.encoder._init() @@ -173,6 +179,14 @@ def test_process_stereo(self): self.encoder.finish() self.assertTrue(self.write_callback_called) + def test_process_int32(self): + """ Test that an array of int32 stereo samples can be processed """ + self.encoder = StreamEncoder(**self.default_kwargs) + test_samples = np.random.rand(DEFAULT_BLOCKSIZE, 2).astype('int32') + self.encoder.process(test_samples) + self.encoder.finish() + self.assertTrue(self.write_callback_called) + def test_seek_tell(self): """ Test that seek and tell callbacks are used """ self.default_kwargs['seek_callback'] = self._seek_callback @@ -223,6 +237,12 @@ def test_invalid_blocksize(self): with self.assertRaisesRegex(EncoderInitException, 'FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE'): self.encoder._init() + def test_invalid_dtype(self): + """ Test than an exception is raised if given an invalid dtype """ + self.default_kwargs['dtype'] = 'int24' + with self.assertRaisesRegex(ValueError, 'FLAC encoding data type must be either int16 or int32'): + self.encoder = FileEncoder(**self.default_kwargs) + def test_blocksize_streamable_subset(self): """ Test that an exception is raised if blocksize is outside the streamable subset """ self.default_kwargs['blocksize'] = 65535 @@ -254,6 +274,7 @@ def test_process_stereo_file(self): """ Test that a stereo WAV file can be processed """ test_path = pathlib.Path(__file__).parent.absolute() / 'data/stereo.wav' self.default_kwargs['input_file'] = test_path + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) self.encoder = FileEncoder(**self.default_kwargs) self.encoder.process() @@ -261,6 +282,16 @@ def test_process_5_1_surround_file(self): """ Test that a 5.1 surround WAV file can be processed """ test_path = pathlib.Path(__file__).parent.absolute() / 'data/surround.wav' self.default_kwargs['input_file'] = test_path + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) + self.encoder = FileEncoder(**self.default_kwargs) + self.encoder.process() + + def test_process_32_bit_file(self): + """ Test that a 32 bit WAV file can be processed """ + test_path = pathlib.Path(__file__).parent.absolute() / 'data/32bit.wav' + self.default_kwargs['input_file'] = test_path + self.default_kwargs['output_file'] = pathlib.Path(self.temp_file.name) + self.default_kwargs['dtype'] = 'int32' self.encoder = FileEncoder(**self.default_kwargs) self.encoder.process() diff --git a/tox.ini b/tox.ini index 1aafdcc..7d87a70 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] -envlist = py37, py38, py39, py310 +envlist = py38, py39, py310, py311 [testenv] -deps = pytest==6.2.2 - pytest-cov==2.11.1 +deps = pytest==7.4.0 + pytest-cov==4.1.0 commands = pytest --cov=. --cov-config .coveragerc --cov-report=xml --maxfail=1