Skip to content

Commit d375224

Browse files
authored
add xaudio.hpp (#1)
testing, and xaudio.hpp
1 parent 633b88a commit d375224

File tree

12 files changed

+289
-65
lines changed

12 files changed

+289
-65
lines changed

.travis.yml

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: cpp
2-
dist: precise
2+
dist: trusty
33
env:
44
matrix:
55
fast_finish: true
@@ -17,19 +17,8 @@ env:
1717
- MINCONDA_VERSION="latest"
1818
- MINCONDA_LINUX="Linux-x86_64"
1919
- MINCONDA_OSX="MacOSX-x86_64"
20-
before_install:
21-
- |
22-
# Configure build variables
23-
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
24-
if [[ "$COMPILER" == "gcc" ]]; then
25-
export CXX=g++-$GCC CC=gcc-$GCC;
26-
fi
27-
if [[ "$COMPILER" == "clang" ]]; then
28-
export CXX=clang++-$CLANG CC=clang-$CLANG;
29-
fi
30-
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
31-
export CXX=clang++ CC=clang;
32-
fi
20+
# before_install:
21+
3322
install:
3423
# Define the version of miniconda to download
3524
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
@@ -43,13 +32,19 @@ install:
4332
- hash -r
4433
- conda config --set always_yes yes --set changeps1 no
4534
- conda update -q conda
46-
- conda install gtest cmake -c conda-forge
47-
- conda install xtensor==0.13.0 -c conda-forge
48-
- conda install zlib openimageio -c QuantStack -c conda-forge
35+
- conda info -a
36+
# Start test environement
37+
- conda env create -f ./test/test-environment.yml
38+
- source activate test-xtensorio
39+
- export CC=$CONDA_PREFIX/bin/gcc
40+
- export CXX=$CONDA_PREFIX/bin/g++
41+
# from conda toolchain package
42+
- export LDFLAGS="${LDFLAGS} -Wl,-rpath,$CONDA_PREFIX/lib"
43+
- export LINKFLAGS="${LDFLAGS}"
4944
# Testing
5045
- mkdir build
5146
- cd build
52-
- cmake -DBUILD_TESTS=ON -DDOWNLOAD_GTEST=ON ..;
47+
- cmake -DBUILD_TESTS=ON -DDOWNLOAD_GTEST=ON -DCMAKE_PREFIX_PATH=$CONDA_PREFIX ..;
5348
- make -j2 test_xtensor_io
5449
- cd test
5550
script:

CMakeLists.txt

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,13 @@ message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor")
3333

3434
# Find OpenImageIO
3535
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/modules")
36-
message("MODULE PATH: ${CMAKE_MODULE_PATH}")
37-
38-
find_package(OIIO)
39-
message(STATUS "Found OpenImageIO: ${OIIO_INCLUDE_DIRS}")
40-
41-
find_package(ZLIB)
42-
message(STATUS "Found zlib: ${zlib_INCLUDE_DIRS}")
4336

4437
# Build
4538
# =====
4639

4740
set(XTENSOR_IO_HEADERS
48-
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/ximageio.hpp
41+
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/ximage.hpp
42+
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xaudio.hpp
4943
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xnpz.hpp
5044
${XTENSOR_IO_INCLUDE_DIR}/xtensor-io/xtensor_io_config.hpp
5145
)

README.md

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
# xtensor-io
1+
# ![xtensor-io](http://quantstack.net/assets/images/xtensor-io.svg)
22

3-
This library delivers a couple of function to efficiently in- and output
4-
images and NumPy compressed arrays (npz) to xtensor data structures.
5-
In order to read and write images, the ![OpenImageIO](https://github.com/OpenImageIO/oiio)
6-
library is utilized. We only provide a few simple functions, but upon demand
7-
can improve this interface.
3+
[![Travis](https://travis-ci.org/QuantStack/xtensor-io.svg?branch=master)](https://travis-ci.org/QuantStack/xtensor-io)
4+
[![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5+
6+
7+
xtensor-io offers a couple of functions to read and write images, audio files, and
8+
NumPy's compressed storage format (NPZ) from C++ into xtensor data structures.
9+
It makes use of well known libraries for image and audio handling (OpenImageIO and libsndfile).
10+
Currently, only a few basic functions are provided, but upon demand we can consider to
11+
improve the interface and offer more options to customize and improve the input-output
12+
performance.
13+
14+
We haven't started building and testing on Windows, yet! Contributions welcome!
15+
16+
### Example
817

918
```cpp
1019
// loads png image into xarray with shape WIDTH x HEIGHT x CHANNELS
@@ -18,14 +27,70 @@ auto npy_map = xt::load_npz("test.npz");
1827

1928
auto arr_0 = npy_map["arr_0"].cast<double>();
2029
auto arr_1 = npy_map["arr_1"].cast<unsigned long>();
30+
31+
// open a wav file
32+
auto audio = xt::load_wav("files/xtensor.wav");
33+
auto& arr = std::get<1>(audio); // audio contents (like scipy.io.wavfile results)
34+
35+
// save a sine wave sound
36+
int freq = 2000;
37+
int sampling_freq = 44100;
38+
double duration = 1.0;
39+
40+
auto t = xt::arange(0.0, duration, 1.0 / sampling_freq);
41+
auto y = xt::sin(2.0 * numeric_constants<double>::PI * freq * t);
42+
43+
xt::dump_wav("files/sine.wav", y, SF_FORMAT_WAV | SF_FORMAT_PCM_16, sampling_freq);
44+
```
45+
46+
### Installation
47+
48+
xtensor-io depends on thirdparty libraries for audio and image handling.
49+
50+
The easiest installation (including all dependencies) is through conda:
51+
52+
```bash
53+
conda install xtensor-io
54+
```
55+
56+
To use xaudio linking with [`libsndfile`](http://www.mega-nerd.com/libsndfile/).
57+
Libsndfile can be installed as follows:
58+
59+
```bash
60+
# Conda
61+
conda install libsndfile -c conda-forge
62+
# Ubuntu / Debian
63+
sudo apt-get install libsndfile-dev
64+
# Fedora
65+
sudo dnf install libsndfile-devel
2166
```
2267

23-
## Installation
68+
For image handling, [`OpenImageIO`](http://openimageio.org/) is required.
69+
We have a build of OpenImageIO on the conda QuantStack channel, but it can also
70+
be optained from your favorite package manager on Linux. Note the conda build
71+
is only tested with the `gcc-6` package from the QuantStack channel.
72+
73+
```bash
74+
# Conda
75+
(maybe: ) conda install gcc-6 -c QuantStack
76+
conda install openimageio -c QuantStack
77+
# Ubuntu / Debian
78+
sudo apt-get install libopenimageio-dev
79+
# Fedora
80+
sudo dnf install OpenImageIO-devel
81+
```
2482

25-
In order to install this library on linux systems, please find a copy
26-
of `libopenimageio` (on fedora: `dnf install OpenImageIO-devel`,
27-
ubuntu: `apt-get install libopenimageio-dev`). This should enable you
28-
to build the library like a regular cmake package:
83+
In order to decompress and read NPZ files, zlib is needed. It should be installed
84+
on linux, but you can also obtain it:
85+
86+
```bash
87+
# Conda
88+
conda install zlib -c conda-forge
89+
# Ubuntu / Debian
90+
sudo apt-get install zlib1g-dev
91+
# Fedora
92+
sudo dnf install zlib-devel
93+
```
2994

3095
From this directory:
3196

include/xtensor-io/xaudio.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include <stdexcept>
2+
#include <string>
3+
4+
#include <sndfile.hh>
5+
6+
#include "xtensor/xarray.hpp"
7+
#include "xtensor/xeval.hpp"
8+
9+
namespace xt
10+
{
11+
/**
12+
* Read a WAV file
13+
*
14+
* @param filename Open file with file name
15+
*
16+
* @return tuple with (samplerate, xarray holding the data)
17+
*
18+
* @tparam T select type
19+
*/
20+
template <class T = short>
21+
auto load_wav(std::string filename)
22+
{
23+
SndfileHandle file(filename);
24+
auto result = xarray<T>::from_shape({(std::size_t) file.frames(), (std::size_t) file.channels()});
25+
file.read(result.raw_data(), (sf_count_t) result.size());
26+
return std::make_tuple(file.samplerate(), std::move(result));
27+
}
28+
29+
/**
30+
* Save an xarray in WAV sound file format
31+
*
32+
* @param filename save under filename
33+
* @param e xarray/xexpression
34+
* @param format select format (see sndfile documentation). Combine flags such as SF_FORMAT_WAV | SF_FORMAT_PCM_16
35+
* @param samplerate The samplerate
36+
*/
37+
template <class E>
38+
void dump_wav(std::string filename, const xexpression<E>& e, int format, int samplerate)
39+
{
40+
auto&& de = xt::eval(e.derived_cast());
41+
SndfileHandle file(filename, SFM_WRITE, format, (int) de.shape()[1], samplerate);
42+
file.write(de.raw_data(), (sf_count_t) de.size());
43+
}
44+
}
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,19 @@
66
#include "xtensor/xarray.hpp"
77
#include "xtensor/xeval.hpp"
88

9-
using namespace OIIO;
10-
119
namespace xt
1210
{
1311
// Handle types better ...
1412
template <class T = unsigned char>
1513
xarray<T> load_image(std::string filename)
1614
{
17-
ImageInput *in = ImageInput::open(filename);
15+
OIIO::ImageInput *in = OIIO::ImageInput::open(filename);
1816
if (!in)
1917
{
2018
// something went wrong
2119
throw std::runtime_error("Couldn't read image");
2220
}
23-
const ImageSpec &spec = in->spec();
21+
const OIIO::ImageSpec &spec = in->spec();
2422
int xres = spec.width;
2523
int yres = spec.height;
2624
int channels = spec.nchannels;
@@ -30,9 +28,9 @@ namespace xt
3028
static_cast<std::size_t>(spec.height),
3129
static_cast<std::size_t>(spec.nchannels)});
3230

33-
in->read_image(TypeDesc::UINT8, image.raw_data());
31+
in->read_image(OIIO::TypeDesc::UINT8, image.raw_data());
3432
in->close();
35-
ImageInput::destroy(in);
33+
OIIO::ImageInput::destroy(in);
3634

3735
return image;
3836
}
@@ -42,19 +40,19 @@ namespace xt
4240
{
4341
auto&& ex = eval(e.derived_cast());
4442

45-
ImageOutput *out = ImageOutput::create(filename);
43+
OIIO::ImageOutput *out = OIIO::ImageOutput::create(filename);
4644
if (!out)
4745
{
4846
// something went wrong
4947
throw std::runtime_error("Couldn't open file to write image.");
5048
}
51-
ImageSpec spec((int) ex.shape()[0], (int) ex.shape()[1], (int) ex.shape()[2], TypeDesc::UINT8);
49+
OIIO::ImageSpec spec((int) ex.shape()[0], (int) ex.shape()[1], (int) ex.shape()[2], OIIO::TypeDesc::UINT8);
5250

5351
spec.attribute("CompressionQuality", quality);
5452

5553
out->open(filename, spec);
56-
out->write_image(TypeDesc::UINT8, ex.raw_data());
54+
out->write_image(OIIO::TypeDesc::UINT8, ex.raw_data());
5755
out->close();
58-
ImageOutput::destroy(out);
56+
OIIO::ImageOutput::destroy(out);
5957
}
6058
}

include/xtensor-io/xtensor_io_config.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define XTENSOR_IO_CONFIG_HPP
1111

1212
#define XTENSOR_IO_VERSION_MAJOR 0
13-
#define XTENSOR_IO_VERSION_MINOR 1
13+
#define XTENSOR_IO_VERSION_MINOR 2
1414
#define XTENSOR_IO_VERSION_PATCH 0
1515

1616
#endif

modules/FindSndFile.cmake

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright: Apache License, Audaspace Project
2+
# Source: https://github.com/neXyon/audaspace/blob/d27746ca8550e2adae6ba54ded0c6dfac58d69b8/cmake/FindLibSndFile.cmake
3+
4+
# Try to find libsndfile
5+
# Once done, this will define
6+
#
7+
# LIBSNDFILE_FOUND - system has libsndfile
8+
# LIBSNDFILE_INCLUDE_DIRS - the libsndfile include directories
9+
# LIBSNDFILE_LIBRARIES - link these to use libsndfile
10+
11+
# Use pkg-config to get hints about paths
12+
find_package(PkgConfig QUIET)
13+
if(PKG_CONFIG_FOUND)
14+
pkg_check_modules(LIBSNDFILE_PKGCONF sndfile)
15+
endif(PKG_CONFIG_FOUND)
16+
17+
# Include dir
18+
find_path(LIBSNDFILE_INCLUDE_DIR
19+
NAMES sndfile.h
20+
PATHS ${LIBSNDFILE_PKGCONF_INCLUDE_DIRS}
21+
)
22+
23+
# Library
24+
find_library(LIBSNDFILE_LIBRARY
25+
NAMES sndfile libsndfile-1
26+
PATHS ${LIBSNDFILE_PKGCONF_LIBRARY_DIRS}
27+
)
28+
29+
find_package(PackageHandleStandardArgs)
30+
find_package_handle_standard_args(LibSndFile DEFAULT_MSG LIBSNDFILE_LIBRARY LIBSNDFILE_INCLUDE_DIR)
31+
32+
if(LIBSNDFILE_FOUND)
33+
set(LIBSNDFILE_LIBRARIES ${LIBSNDFILE_LIBRARY})
34+
set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE_INCLUDE_DIR})
35+
endif(LIBSNDFILE_FOUND)
36+
37+
mark_as_advanced(LIBSNDFILE_LIBRARY LIBSNDFILE_LIBRARIES LIBSNDFILE_INCLUDE_DIR LIBSNDFILE_INCLUDE_DIRS)

0 commit comments

Comments
 (0)