Skip to content

Commit

Permalink
Fixed test data file locations (#76)
Browse files Browse the repository at this point in the history
* Created test fixture pyogg_config.

* Fixed location of test data files.  They now are always stored in `tests/out` irrespective of the current working directory. 

* Added signed attribute to FlacFile
  • Loading branch information
mattgwwalker committed Dec 24, 2020
1 parent c78487e commit 3783343
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 101 deletions.
71 changes: 56 additions & 15 deletions pyogg/flac.py
Original file line number Diff line number Diff line change
Expand Up @@ -1372,21 +1372,62 @@ class FLAC__StreamDecoder(Structure):
_fields_ = [("protected_", POINTER(FLAC__StreamDecoderProtected)),
("private_", POINTER(FLAC__StreamDecoderPrivate))]

FLAC__StreamDecoderReadCallback = CFUNCTYPE(FLAC__StreamDecoderReadStatus, POINTER(FLAC__StreamDecoder), POINTER(FLAC__byte*0), c_size_t_p, c_void_p)

FLAC__StreamDecoderSeekCallback = CFUNCTYPE(FLAC__StreamDecoderSeekStatus, POINTER(FLAC__StreamDecoder), FLAC__uint64, c_void_p)

FLAC__StreamDecoderTellCallback = CFUNCTYPE(FLAC__StreamDecoderTellStatus, POINTER(FLAC__StreamDecoder), FLAC__uint64_p, c_void_p)

FLAC__StreamDecoderLengthCallback = CFUNCTYPE(FLAC__StreamDecoderLengthStatus, POINTER(FLAC__StreamDecoder), FLAC__uint64_p, c_void_p)

FLAC__StreamDecoderEofCallback = CFUNCTYPE(FLAC__bool, POINTER(FLAC__StreamDecoder), c_void_p)

FLAC__StreamDecoderWriteCallback = CFUNCTYPE(FLAC__StreamDecoderWriteStatus, POINTER(FLAC__StreamDecoder), POINTER(FLAC__Frame), POINTER(FLAC__int32_p*0), c_void_p)#FLAC__int32_p*0, c_void_p)

FLAC__StreamDecoderMetadataCallback = CFUNCTYPE(None, POINTER(FLAC__StreamDecoder), POINTER(FLAC__StreamMetadata), c_void_p)

FLAC__StreamDecoderErrorCallback = CFUNCTYPE(None, POINTER(FLAC__StreamDecoder), FLAC__StreamDecoderErrorStatus, c_void_p)
FLAC__StreamDecoderReadCallback = CFUNCTYPE(
FLAC__StreamDecoderReadStatus,
POINTER(FLAC__StreamDecoder),
POINTER(FLAC__byte*0),
c_size_t_p,
c_void_p
)

FLAC__StreamDecoderSeekCallback = CFUNCTYPE(
FLAC__StreamDecoderSeekStatus,
POINTER(FLAC__StreamDecoder),
FLAC__uint64,
c_void_p
)

FLAC__StreamDecoderTellCallback = CFUNCTYPE(
FLAC__StreamDecoderTellStatus,
POINTER(FLAC__StreamDecoder),
FLAC__uint64_p,
c_void_p
)

FLAC__StreamDecoderLengthCallback = CFUNCTYPE(
FLAC__StreamDecoderLengthStatus,
POINTER(FLAC__StreamDecoder),
FLAC__uint64_p,
c_void_p
)

FLAC__StreamDecoderEofCallback = CFUNCTYPE(
FLAC__bool,
POINTER(FLAC__StreamDecoder),
c_void_p
)

FLAC__StreamDecoderWriteCallback = CFUNCTYPE(
FLAC__StreamDecoderWriteStatus,
POINTER(FLAC__StreamDecoder),
POINTER(FLAC__Frame),
POINTER(FLAC__int32_p*0),
c_void_p
)

FLAC__StreamDecoderMetadataCallback = CFUNCTYPE(
None,
POINTER(FLAC__StreamDecoder),
POINTER(FLAC__StreamMetadata),
c_void_p
)

FLAC__StreamDecoderErrorCallback = CFUNCTYPE(
None,
POINTER(FLAC__StreamDecoder),
FLAC__StreamDecoderErrorStatus,
c_void_p
)


libflac.FLAC__stream_decoder_new.restype = POINTER(FLAC__StreamDecoder)
Expand Down
10 changes: 8 additions & 2 deletions pyogg/flac_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ def __init__(self, path):
)

if init_status: # error
raise PyOggError("An error occured when trying to open '{}': {}".format(path, flac.FLAC__StreamDecoderInitStatusEnum[init_status]))
error = flac.FLAC__StreamDecoderInitStatusEnum[init_status]
raise PyOggError(
"An error occured when trying to open '{}': {}".format(path, error)
)

metadata_status = (flac.FLAC__stream_decoder_process_until_end_of_metadata(self.decoder))
if not metadata_status: # error
Expand All @@ -100,9 +103,12 @@ def __init__(self, path):
self.bytes_per_sample = ctypes.sizeof(flac.FLAC__int16) # See definition of Buffer in metadata_callback()

# Cast buffer to one-dimensional array of chars
print("len(self.buffer):",len(self.buffer))
CharBuffer = (
ctypes.c_byte *
(self.bytes_per_sample * len(self.buffer))
)
self.buffer = CharBuffer.from_buffer(self.buffer)

# FLAC audio is always signed. See
# https://xiph.org/flac/api/group__flac__stream__decoder.html#gaf98a4f9e2cac5747da6018c3dfc8dde1
self.signed = True
7 changes: 7 additions & 0 deletions tests/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import pathlib

# Definition of class returned by PyTest fixture 'pyogg_config'.
class Config:
def __init__(self):
self.rootdir: pathlib.Path
self.outdir: pathlib.Path
45 changes: 45 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import shutil
from typing import Any

import pytest

from config import Config


_config = Config()


# FIXME: Mypy: What is the correct type for 'config'? It is of type
# _pytest.config.Config (see
# https://docs.pytest.org/en/stable/_modules/_pytest/hookspec.html#pytest_configure)
# but this isn't part of the public API. Using 'Any' as a
# placeholder.
def pytest_configure(config: Any) -> None:
# Create an object to store the directories

_config.rootdir = config.rootdir
_config.outdir = config.rootdir / "tests/out"

# If the previous output directory exists, delete it
out_previous = config.rootdir / "tests/out_previous"
if out_previous.exists():
try:
shutil.rmtree(out_previous)
except Exception as e:
raise Exception(
"Failed to remove previous output directory. "+
"You will need to manually delete the directory "+
f"'{out_previous}': "+str(e)
)

# If the output directory already exists, rename it
if _config.outdir.exists():
_config.outdir.rename(config.rootdir / "tests/out_previous")

# Create the output directory
_config.outdir.mkdir()


@pytest.fixture(scope="session")
def pyogg_config() -> Config:
return _config
20 changes: 12 additions & 8 deletions tests/test_flac_file.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import pytest
import pyogg

def test_error_in_filename():
def test_error_in_filename() -> None:
# Load a non-existant file
filename = "does-not-exist.flac"
with pytest.raises(pyogg.PyOggError):
flac_file = pyogg.FlacFile(filename)


def test_as_array():
def test_as_array(pyogg_config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"
filename = str(pyogg_config.rootdir / "examples/left-right-demo-5s.flac")
flac_file = pyogg.FlacFile(filename)

# Test that the loaded file is indeed 5 seconds long (using
Expand All @@ -25,9 +25,9 @@ def test_as_array():
assert duration_samples == expected_duration_samples


def test_as_bytes():
def test_as_bytes(pyogg_config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"
filename = str(pyogg_config.rootdir / "examples/left-right-demo-5s.flac")
flac_file = pyogg.FlacFile(filename)

# Test that the loaded file is indeed 5 seconds long (using
Expand All @@ -46,14 +46,18 @@ def test_as_bytes():
assert duration_bytes == expected_duration_bytes


def test_output_via_wav():
def test_output_via_wav(pyogg_config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"
filename = str(pyogg_config.rootdir / "examples/left-right-demo-5s.flac")
flac_file = pyogg.FlacFile(filename)

import wave
out_filename = str(
pyogg_config.outdir
/ "test_flac_file__test_output_via_wav.wav"
)
wave_out = wave.open(
"test_flac_file__test_output_via_wav.wav",
out_filename,
"wb"
)
wave_out.setnchannels(flac_file.channels)
Expand Down
29 changes: 20 additions & 9 deletions tests/test_flac_file_stream.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import pytest
import pyogg

def test_error_in_filename():
from config import Config

def test_error_in_filename() -> None:
# Load a non-existant file
filename = "does-not-exist.flac"
with pytest.raises(pyogg.PyOggError):
flac_stream = pyogg.FlacFileStream(filename)


def test_total_length():
def test_total_length(pyogg_config: Config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"
filename = str(
pyogg_config.rootdir
/ "examples/left-right-demo-5s.flac"
)

# Open the file using FlacFileStream, which does not read the entire
# file immediately.
Expand Down Expand Up @@ -39,10 +44,13 @@ def test_total_length():
assert duration_samples == expected_duration_samples


def test_same_data_as_flac_file():
def test_same_data_as_flac_file(pyogg_config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"

filename = str(
pyogg_config.rootdir
/ "examples/left-right-demo-5s.flac"
)

# Open the file using FlacFile to read the entire file into memory
flac_file = pyogg.FlacFile(filename)

Expand All @@ -68,12 +76,15 @@ def test_same_data_as_flac_file():
assert buf_all == bytes(flac_file.buffer)


def test_same_data_as_flac_file_using_as_array():
def test_same_data_as_flac_file_using_as_array(pyogg_config):
import numpy # type: ignore

# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.flac"

filename = str(
pyogg_config.rootdir
/ "examples/left-right-demo-5s.flac"
)

# Open the file using FlacFile to read the entire file into memory
flac_file = pyogg.FlacFile(filename)

Expand Down
54 changes: 39 additions & 15 deletions tests/test_ogg_opus_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
import pyogg
import os

os.chdir(os.path.dirname(__file__))
from config import Config

def test_zero_length_audio() -> None:
def test_zero_length_audio(pyogg_config: Config) -> None:
# Save the audio using OggOpusWriter
filename = "test_ogg_opus_writer__test_zero_length_audio.opus"
filename = str(
pyogg_config.outdir
/ "test_ogg_opus_writer__test_zero_length_audio.opus"
)
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
encoder.set_sampling_frequency(48000)
Expand All @@ -27,9 +30,12 @@ def test_zero_length_audio() -> None:
assert len(opus_file.buffer) == 0


def test_one_frame_audio() -> None:
def test_one_frame_audio(pyogg_config: Config) -> None:
# Save the audio using OggOpusWriter
filename = "test_ogg_opus_writer__test_one_frame_audio.opus"
filename = str(
pyogg_config.outdir
/ "test_ogg_opus_writer__test_one_frame_audio.opus"
)
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
samples_per_second = 48000
Expand Down Expand Up @@ -57,12 +63,15 @@ def test_one_frame_audio() -> None:
assert len(bytes(opus_file.buffer)) == bytes_per_sample * frame_size_samples


def test_n_frames_audio() -> None:
def test_n_frames_audio(pyogg_config: Config) -> None:
# Number of frames to write
n = 2

# Save the audio using OggOpusWriter
filename = f"test_ogg_opus_writer__test_{n}_frames_audio.opus"
filename = str(
pyogg_config.outdir
/ f"test_ogg_opus_writer__test_{n}_frames_audio.opus"
)
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
samples_per_second = 48000
Expand All @@ -88,13 +97,19 @@ def test_n_frames_audio() -> None:
assert len(bytes(opus_file.buffer)) == bytes_per_sample * frame_size_samples * n


def test_duplicate_audio() -> None:
def test_duplicate_audio(pyogg_config: Config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.opus"
filename = str(
pyogg_config.rootdir
/ "examples/left-right-demo-5s.opus"
)
opus_file = pyogg.OpusFile(filename)

# Save the audio using OggOpusWriter
out_filename = "test_ogg_opus_writer__test_duplicate_audio.opus"
out_filename = str(
pyogg_config.outdir
/ "test_ogg_opus_writer__test_duplicate_audio.opus"
)
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
encoder.set_sampling_frequency(48000)
Expand All @@ -105,13 +120,19 @@ def test_duplicate_audio() -> None:
writer.write(memoryview(opus_file.buffer))


def test_already_loaded_file() -> None:
def test_already_loaded_file(pyogg_config: Config) -> None:
# Load the demonstration file that is exactly 5 seconds long
filename = "../examples/left-right-demo-5s.opus"
filename = str(
pyogg_config.rootdir
/ "examples/left-right-demo-5s.opus"
)
opus_file = pyogg.OpusFile(filename)

# Save the audio using OggOpusWriter
out_filename = "test_ogg_opus_writer__test_already_loaded_file.opus"
out_filename = str(
pyogg_config.outdir
/ "test_ogg_opus_writer__test_already_loaded_file.opus"
)
f = open(out_filename, "wb")
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
Expand All @@ -126,9 +147,12 @@ def test_already_loaded_file() -> None:
f.close()


def test_custom_pre_skip() -> None:
def test_custom_pre_skip(pyogg_config: Config) -> None:
# Save the audio using OggOpusWriter
filename = "test_ogg_opus_writer__test_zero_length_audio.opus"
filename = str(
pyogg_config.outdir
/ "test_ogg_opus_writer__test_custom_pre_skip.opus"
)
samples_of_pre_skip = 500
encoder = pyogg.OpusBufferedEncoder()
encoder.set_application("audio")
Expand Down
2 changes: 0 additions & 2 deletions tests/test_opus_buffered_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import pytest
import pyogg

os.chdir(os.path.dirname(__file__))

# Function to create an encoder and encode a sample of silence
def init_encoder(samples_per_second:int = 48000,
application: str = "audio",
Expand Down

0 comments on commit 3783343

Please sign in to comment.