Index: andscape.yml
===================================================================
--- .landscape.yml	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ 	(revision )
@@ -1,5 +1,0 @@
-strictness: medium
-test-warnings: true
-python-targets:
-  - 2
-  - 3
Index: .travis.yml
===================================================================
--- .travis.yml	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ .travis.yml	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -9,4 +9,5 @@
       os: linux
       compiler: gcc
+      env: WAFOPTS="--build-type=debug"
     - python: 2.7
       os: linux
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ ChangeLog	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -1,2 +1,82 @@
+2018-12-19 Paul Brossier <piem@aubio.org>
+
+	[ Overview ]
+
+	* VERSION: bump to 0.4.9
+	* library: improve stability, fixing potential crashes and memory leaks on
+	invalid arguments; improve library messages and reporting of system errors
+	* tests/: major clean-up, check return codes, increase code coverage
+	* python/tests/: switch to pytest (closes gh-163), check emitted warnings
+	* python/: add pages to manual with brief descriptions of classes
+
+	[ Fixes ]
+
+	* security: improve arguments validation in new_aubio_filterbank (prevent
+	possible null-pointer dereference on invalid n_filters, CVE-2018-19801),
+	new_aubio-tempo (prevent possible buffer overflow, CVE-2018-19800), and
+	new_aubio_onset (prevent null-pointer dereference, CVE-2018-19802). Thanks
+	to Guoxiang Niu (@niugx), from the EaglEye Team for reporting these issues.
+	* tempo: fix delay_ms methods
+	* filterbank: fix aubio_filterbank_get_power (thanks to @romanbsd who
+	also noticed this issue)
+	* dct: creation fail on negative sizes or invalid accelerate radix,
+	fix typo in error and warning messages, prevent possible memory leak
+	* pitch: prevent null pointer dereference in yinfast, comment out unused
+	functions in mcomb and yin, prevent possible leak in specacf
+	* mfcc: always use dct module, strengthen input validation, change
+	get_{scale,power} to return smpl_t
+	* specdesc: improve error message
+	* notes: prevent null pointer dereference
+	* hist: add validation for size argument, prevent possible leak
+	* awhitening: use shortest length available (closes gh-216)
+	* io: add macros to display system errors, add helpers to validate input
+	arguments of source and sink methods, always clean-up after failure
+	* source: validate input sizes to prevent invalid reads
+	* apple_audio: use native format conversions in source and sink, prevent
+	possible apple_audio crash on empty string, get_duration returns 0 on failure
+	* ffmpeg/avcodec: prevent deprecation warnings, read after close, and skipped
+	samples warnings, improve warning messages, only show a warning when
+	swr_convert failed, prevent possible memory leak when closing swr context
+	* wavwrite: copy to all channels if needed, check fseek and fwrite return
+	values, call fflush in open to return failure on full disk-system
+	* source_sndfile: fix reading sizes when resampling, set error message when
+	reading after close
+	* aubio_priv.h: include blas first (see gh-225), add STRERROR macros
+
+	[ Python ]
+
+	* documentation: add pages to manual, add minimal docstrings for fft,
+	digital_filter, and generated objects, improve specdesc documentation
+	* filterbank: add get_norm/power documentation
+	* source: take a copy of the last frame before resizing it, raise an
+	exception when read failed, fix compilation warning
+	* fixes: remove unneeded check convert with PyFloat_FromDouble or
+	PyFloat_FromDouble, check if sink, digital_filter, were created before
+	deleting
+
+	[ Tests ]
+
+	* python/tests/: switch to pytest (slightly slower than nose2 but better at
+	capturing warnings and parametrization), improve coding style and coverage.
+	Tests should now be run with `pytest`.
+	* tests/: Each test program in C must now return 0, otherwise the test will
+	fail. Examples have been modified to run themselves on a test audio file,
+	but can still be run with arguments. Tests for `source` and `sink` have been
+	factorised, and some code cleaning. A python script is used to create a
+	test sound file. Tested on linux, macos, and windows, improvements to
+	test-mfcc (closes gh-219).
+
+	[ Build system ]
+
+	* waf: upgrade to 2.0.14, check the return code of each test program,
+	update rules to build manual and api documentation into build/, check
+	for errno.h
+	* osx: use -Os in scripts/build_apple_frameworks
+	* Makefile: improve coverage reports
+	* appveyor, travis, circleci: switch to pytest, set one travis config to use
+	sndfile only
+	* travis: add py3.6, drop py3.4, use py3.5 to test debug mode
+	* azure: add basic configuration
+
 2018-11-21 Paul Brossier <piem@aubio.org>
 
Index: README.md
===================================================================
--- README.md	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ README.md	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -4,5 +4,4 @@
 [![Travis build status](https://travis-ci.org/aubio/aubio.svg?branch=master)](https://travis-ci.org/aubio/aubio "Travis build status")
 [![Appveyor build status](https://img.shields.io/appveyor/ci/piem/aubio/master.svg)](https://ci.appveyor.com/project/piem/aubio "Appveyor build status")
-[![Landscape code health](https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat)](https://landscape.io/github/aubio/aubio/master "Landscape code health")
 [![Commits since last release](https://img.shields.io/github/commits-since/aubio/aubio/latest.svg)](https://github.com/aubio/aubio "Commits since last release")
 
Index: VERSION
===================================================================
--- VERSION	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ VERSION	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -1,5 +1,5 @@
 AUBIO_MAJOR_VERSION=0
-AUBIO_MINOR_VERSION=4
-AUBIO_PATCH_VERSION=9
+AUBIO_MINOR_VERSION=5
+AUBIO_PATCH_VERSION=0
 AUBIO_VERSION_STATUS='~alpha'
 LIBAUBIO_LT_CUR=5
Index: azure-pipelines.yml
===================================================================
--- azure-pipelines.yml	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ azure-pipelines.yml	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -4,5 +4,5 @@
 - job: linux
   pool:
-    vmImage: 'Ubuntu 16.04'
+    vmImage: 'ubuntu-16.04'
   steps:
   - script: |
@@ -14,5 +14,5 @@
 - job: windows
   pool:
-    vmIMage: 'VS2017-Win2016'
+    vmImage: 'vs2017-win2016'
   steps:
   - script: |
@@ -25,5 +25,5 @@
 - job: macos
   pool:
-    vmIMage: macOS-10.13
+    vmImage: 'macos-10.13'
   steps:
   - script: |
Index: doc/statuslinks.rst
===================================================================
--- doc/statuslinks.rst	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ doc/statuslinks.rst	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -10,8 +10,4 @@
    :alt: Appveyor build status
 
-.. image:: https://landscape.io/github/aubio/aubio/master/landscape.svg?style=flat
-   :target: https://landscape.io/github/aubio/aubio/master
-   :alt: Landscape code health
-
 .. image:: https://readthedocs.org/projects/aubio/badge/?version=latest
    :target: https://aubio.readthedocs.io/en/latest/?badge=latest
Index: python/demos/demo_wav2midi.py
===================================================================
--- python/demos/demo_wav2midi.py	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/demos/demo_wav2midi.py	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -64,5 +64,5 @@
         if new_note[2] > 0:
             track.append(Message('note_off', note=int(new_note[2]),
-                velocity=127, time=0)
+                velocity=127, time=delta)
                 )
         track.append(Message('note_on',
Index: python/ext/py-source.c
===================================================================
--- python/ext/py-source.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/ext/py-source.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -582,5 +582,8 @@
     } else if (PyLong_AsLong(size) > 0) {
       // short read, return a shorter array
-      PyArrayObject *shortread = (PyArrayObject*)PyTuple_GetItem(done, 0);
+      PyObject *vec = PyTuple_GetItem(done, 0);
+      // take a copy to prevent resizing internal arrays
+      PyArrayObject *shortread = (PyArrayObject*)PyArray_FROM_OTF(vec,
+          NPY_NOTYPE, NPY_ARRAY_ENSURECOPY);
       PyArray_Dims newdims;
       PyObject *reshaped;
@@ -595,4 +598,5 @@
       reshaped = PyArray_Newshape(shortread, &newdims, NPY_CORDER);
       Py_DECREF(shortread);
+      Py_DECREF(vec);
       return reshaped;
     } else {
Index: python/lib/moresetuptools.py
===================================================================
--- python/lib/moresetuptools.py	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/lib/moresetuptools.py	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -69,5 +69,5 @@
     for define_macro in ['HAVE_STDLIB_H', 'HAVE_STDIO_H',
                          'HAVE_MATH_H', 'HAVE_STRING_H',
-                         'HAVE_C99_VARARGS_MACROS',
+                         'HAVE_ERRNO_H', 'HAVE_C99_VARARGS_MACROS',
                          'HAVE_LIMITS_H', 'HAVE_STDARG_H',
                          'HAVE_MEMCPY_HACKS']:
Index: python/tests/test_sink.py
===================================================================
--- python/tests/test_sink.py	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/tests/test_sink.py	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -4,5 +4,6 @@
 from aubio import fvec, source, sink
 from utils import list_all_sounds, get_tmp_sink_path, del_tmp_sink_path
-from _tools import parametrize, skipTest, assert_raises
+from utils import parse_file_samplerate
+from _tools import parametrize, skipTest, assert_raises, assert_warns
 
 list_of_sounds = list_all_sounds('sounds')
@@ -61,6 +62,12 @@
     @parametrize('hop_size, samplerate, path', all_params)
     def test_read_and_write(self, hop_size, samplerate, path):
+        orig_samplerate = parse_file_samplerate(soundfile)
         try:
-            f = source(path, samplerate, hop_size)
+            if orig_samplerate is not None and orig_samplerate < samplerate:
+                # upsampling should emit a warning
+                with assert_warns(UserWarning):
+                    f = source(soundfile, samplerate, hop_size)
+            else:
+                f = source(soundfile, samplerate, hop_size)
         except RuntimeError as e:
             err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
@@ -79,6 +86,12 @@
     @parametrize('hop_size, samplerate, path', all_params)
     def test_read_and_write_multi(self, hop_size, samplerate, path):
+        orig_samplerate = parse_file_samplerate(soundfile)
         try:
-            f = source(path, samplerate, hop_size)
+            if orig_samplerate is not None and orig_samplerate < samplerate:
+                # upsampling should emit a warning
+                with assert_warns(UserWarning):
+                    f = source(soundfile, samplerate, hop_size)
+            else:
+                f = source(soundfile, samplerate, hop_size)
         except RuntimeError as e:
             err_msg = '{:s} (hop_s = {:d}, samplerate = {:d})'
Index: python/tests/test_source.py
===================================================================
--- python/tests/test_source.py	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/tests/test_source.py	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -4,7 +4,8 @@
 from numpy.testing import TestCase, assert_equal
 from aubio import source
-from utils import list_all_sounds
+from utils import list_all_sounds, parse_file_samplerate
 import unittest
-from _tools import parametrize, assert_raises, assert_equal, skipTest
+from _tools import assert_raises, assert_equal, assert_warns
+from _tools import parametrize, skipTest
 
 list_of_sounds = list_all_sounds('sounds')
@@ -23,4 +24,5 @@
 
 _debug = False
+
 
 class Test_aubio_source_test_case(TestCase):
@@ -75,6 +77,12 @@
     @parametrize('hop_size, samplerate, soundfile', all_params)
     def test_samplerate_hopsize(self, hop_size, samplerate, soundfile):
+        orig_samplerate = parse_file_samplerate(soundfile)
         try:
-            f = source(soundfile, samplerate, hop_size)
+            if orig_samplerate is not None and orig_samplerate < samplerate:
+                # upsampling should emit a warning
+                with assert_warns(UserWarning):
+                    f = source(soundfile, samplerate, hop_size)
+            else:
+                f = source(soundfile, samplerate, hop_size)
         except RuntimeError as e:
             err_msg = 'failed opening with hop_s={:d}, samplerate={:d} ({:s})'
Index: python/tests/utils.py
===================================================================
--- python/tests/utils.py	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ python/tests/utils.py	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -2,4 +2,5 @@
 
 import os
+import re
 import glob
 import numpy as np
@@ -78,2 +79,15 @@
                     total_files += 1
     return total_files
+
+def parse_file_samplerate(soundfile):
+    samplerate = None
+    # parse samplerate
+    re_sr = re.compile(r'/([0-9]{4,})Hz_.*')
+    match_samplerate = re_sr.findall(soundfile)
+    if match_samplerate:
+        samplerate = int(match_samplerate[0])
+    else:
+        import warnings
+        warnings.warn(UserWarning("could not parse samplerate for {:s}"
+            .format(soundfile)))
+    return samplerate
Index: scripts/get_waf.sh
===================================================================
--- scripts/get_waf.sh	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ scripts/get_waf.sh	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -4,5 +4,5 @@
 #set -x
 
-WAFVERSION=2.0.13
+WAFVERSION=2.0.14
 WAFTARBALL=waf-$WAFVERSION.tar.bz2
 WAFURL=https://waf.io/$WAFTARBALL
Index: src/aubio_priv.h
===================================================================
--- src/aubio_priv.h	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/aubio_priv.h	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -63,4 +63,8 @@
 #endif
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
 #ifdef HAVE_LIMITS_H
 #include <limits.h> // for CHAR_BIT, in C99 standard
@@ -71,10 +75,6 @@
 #endif
 
-#if defined(HAVE_ACCELERATE)
-#define HAVE_ATLAS 1
-#define HAVE_BLAS 1
-#include <Accelerate/Accelerate.h>
-#elif defined(HAVE_ATLAS_CBLAS_H)
-#elif defined(HAVE_BLAS)
+#if defined(HAVE_BLAS) // --enable-blas=true
+// check which cblas header we found
 #if defined(HAVE_ATLAS_CBLAS_H)
 #define HAVE_ATLAS 1
@@ -84,9 +84,15 @@
 #elif defined(HAVE_CBLAS_H)
 #include <cblas.h>
-#endif
-#endif
-
-#ifdef HAVE_ACCELERATE
+#elif !defined(HAVE_ACCELERATE)
+#error "HAVE_BLAS was defined, but no blas header was found"
+#endif /* end of cblas includes */
+#endif
+
+#if defined(HAVE_ACCELERATE)
+// include accelerate framework after blas
+#define HAVE_ATLAS 1
+#define HAVE_BLAS 1
 #include <Accelerate/Accelerate.h>
+
 #ifndef HAVE_AUBIO_DOUBLE
 #define aubio_vDSP_mmov       vDSP_mmov
@@ -331,4 +337,16 @@
 #endif
 
+#ifdef HAVE_C99_VARARGS_MACROS
+#define AUBIO_STRERR(...)            \
+    char errorstr[256]; \
+    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
+    AUBIO_ERR(__VA_ARGS__)
+#else
+#define AUBIO_STRERR(format, args...)   \
+    char errorstr[256]; \
+    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr)); \
+    AUBIO_ERR(format, ##args)
+#endif
+
 /* handy shortcuts */
 #define DB2LIN(g) (POW(10.0,(g)*0.05f))
Index: src/io/sink.c
===================================================================
--- src/io/sink.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/sink.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -216,5 +216,5 @@
 
 void del_aubio_sink(aubio_sink_t * s) {
-  AUBIO_ASSERT(s);
+  //AUBIO_ASSERT(s);
   if (s && s->s_del && s->sink)
     s->s_del((void *)s->sink);
Index: src/io/sink_wavwrite.c
===================================================================
--- src/io/sink_wavwrite.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/sink_wavwrite.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -28,6 +28,4 @@
 #include "io/sink_wavwrite.h"
 #include "io/ioutils.h"
-
-#include <errno.h>
 
 #define MAX_SIZE 4096
@@ -168,7 +166,5 @@
   s->fid = fopen((const char *)s->path, "wb");
   if (!s->fid) {
-    char errorstr[256];
-    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
-    AUBIO_ERR("sink_wavwrite: could not open %s (%s)\n", s->path, errorstr);
+    AUBIO_STRERR("sink_wavwrite: could not open %s (%s)\n", s->path, errorstr);
     goto beach;
   }
@@ -216,9 +212,9 @@
 
   // fwrite(*, *, 1, s->fid) was called 13 times, check success
-  if (written != 13) {
-    char errorstr[256];
-    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
-    AUBIO_WRN("sink_wavwrite: writing header to %s failed, expected %d"
-        " write but got only %d (%s)\n", s->path, 13, written, errorstr);
+  if (written != 13 || fflush(s->fid)) {
+    AUBIO_STRERR("sink_wavwrite: writing header to %s failed"
+        " (wrote %d/%d, %s)\n", s->path, written, 13, errorstr);
+    fclose(s->fid);
+    s->fid = NULL;
     return AUBIO_FAIL;
   }
@@ -247,7 +243,5 @@
 
   if (written_frames != write) {
-    char errorstr[256];
-    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
-    AUBIO_WRN("sink_wavwrite: trying to write %d frames to %s, but only %d"
+    AUBIO_STRERR("sink_wavwrite: trying to write %d frames to %s, but only %d"
         " could be written (%s)\n", write, s->path, written_frames, errorstr);
   }
@@ -298,14 +292,10 @@
   written += fwrite(write_little_endian(data_size, buf, 4), 4, 1, s->fid);
   if (written != 2 || err != 0) {
-    char errorstr[256];
-    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
-    AUBIO_WRN("sink_wavwrite: updating header of %s failed, expected %d"
+    AUBIO_STRERR("sink_wavwrite: updating header of %s failed, expected %d"
         " write but got only %d (%s)\n", s->path, 2, written, errorstr);
   }
   // close file
   if (fclose(s->fid)) {
-    char errorstr[256];
-    AUBIO_STRERROR(errno, errorstr, sizeof(errorstr));
-    AUBIO_ERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, errorstr);
+    AUBIO_STRERR("sink_wavwrite: Error closing file %s (%s)\n", s->path, errorstr);
   }
   s->fid = NULL;
Index: src/io/source.c
===================================================================
--- src/io/source.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/source.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -139,5 +139,5 @@
 
 void del_aubio_source(aubio_source_t * s) {
-  AUBIO_ASSERT(s);
+  //AUBIO_ASSERT(s);
   if (s && s->s_del && s->source)
     s->s_del((void *)s->source);
Index: src/io/source_avcodec.c
===================================================================
--- src/io/source_avcodec.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/source_avcodec.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -31,5 +31,4 @@
 #endif
 #include <libavutil/opt.h>
-#include <stdlib.h>
 
 // determine whether we use libavformat from ffmpeg or from libav
@@ -121,7 +120,7 @@
     uint_t samplerate, uint_t hop_size) {
   aubio_source_avcodec_t * s = AUBIO_NEW(aubio_source_avcodec_t);
-  AVFormatContext *avFormatCtx = s->avFormatCtx;
-  AVCodecContext *avCodecCtx = s->avCodecCtx;
-  AVFrame *avFrame = s->avFrame;
+  AVFormatContext *avFormatCtx = NULL;
+  AVCodecContext *avCodecCtx = NULL;
+  AVFrame *avFrame = NULL;
   sint_t selected_stream = -1;
 #if FF_API_LAVF_AVCTX
@@ -465,7 +464,7 @@
       (const uint8_t **)avFrame->data, in_samples);
 #endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
-  if (out_samples <= 0) {
-    AUBIO_WRN("source_avcodec: no sample found while converting frame (%s)\n",
-        s->path);
+  if (out_samples < 0) {
+    AUBIO_WRN("source_avcodec: error while resampling %s (%d)\n",
+        s->path, out_samples);
     goto beach;
   }
@@ -474,12 +473,4 @@
 
 beach:
-  s->avFormatCtx = avFormatCtx;
-  s->avCodecCtx = avCodecCtx;
-  s->avFrame = avFrame;
-#if defined(HAVE_AVRESAMPLE) || defined(HAVE_SWRESAMPLE)
-  s->avr = avr;
-#endif /* HAVE_AVRESAMPLE || HAVE_SWRESAMPLE */
-  s->output = output;
-
   av_packet_unref(&avPacket);
 }
@@ -629,8 +620,9 @@
 #ifdef HAVE_AVRESAMPLE
     avresample_close( s->avr );
+    av_free ( s->avr );
 #elif defined(HAVE_SWRESAMPLE)
     swr_close ( s->avr );
-#endif
-    av_free ( s->avr );
+    swr_free ( &s->avr );
+#endif
   }
   s->avr = NULL;
Index: src/io/source_sndfile.c
===================================================================
--- src/io/source_sndfile.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/source_sndfile.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -175,4 +175,9 @@
   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
       s->scratch_size);
+  uint_t read_length = read_samples / s->input_channels;
+
+  /* where to store de-interleaved data */
+  smpl_t *ptr_data;
+
   if (!s->handle) {
     AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
@@ -182,8 +187,4 @@
   }
 
-  uint_t read_length = read_samples / s->input_channels;
-
-  /* where to store de-interleaved data */
-  smpl_t *ptr_data;
 #ifdef HAVE_SAMPLERATE
   if (s->ratio != 1) {
@@ -226,4 +227,9 @@
   sf_count_t read_samples = aubio_sf_read_smpl (s->handle, s->scratch_data,
       s->scratch_size);
+  uint_t read_length = read_samples / s->input_channels;
+
+  /* where to store de-interleaved data */
+  smpl_t **ptr_data;
+
   if (!s->handle) {
     AUBIO_ERR("source_sndfile: could not read from %s (file was closed)\n",
@@ -233,8 +239,4 @@
   }
 
-  uint_t read_length = read_samples / s->input_channels;
-
-  /* where to store de-interleaved data */
-  smpl_t **ptr_data;
 #ifdef HAVE_SAMPLERATE
   if (s->ratio != 1) {
Index: src/io/source_wavread.c
===================================================================
--- src/io/source_wavread.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ src/io/source_wavread.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -28,9 +28,7 @@
 #include "source_wavread.h"
 
-#include <errno.h>
-
 #define AUBIO_WAVREAD_BUFSIZE 1024
 
-#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
+//#define SHORT_TO_FLOAT(x) (smpl_t)(x * 3.0517578125e-05)
 
 struct _aubio_source_wavread_t {
@@ -101,5 +99,5 @@
   s->fid = fopen((const char *)path, "rb");
   if (!s->fid) {
-    AUBIO_ERR("source_wavread: Failed opening %s (System error: %s)\n", s->path, strerror(errno));
+    AUBIO_STRERR("source_wavread: Failed opening %s (%s)\n", s->path, errorstr);
     goto beach;
   }
@@ -134,6 +132,6 @@
     bytes_junk += read_little_endian(buf, 4);
     if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
-      AUBIO_ERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
-          s->path, strerror(errno));
+      AUBIO_STRERR("source_wavread: Failed opening %s (could not seek past JUNK Chunk: %s)\n",
+          s->path, errorstr);
       goto beach;
     }
@@ -262,6 +260,6 @@
     bytes_junk += read_little_endian(buf, 4);
     if (fseek(s->fid, bytes_read + bytes_junk, SEEK_SET) != 0) {
-      AUBIO_ERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
-          s->path, strerror(errno));
+      AUBIO_STRERR("source_wavread: could not seek past unknown chunk in %s (%s)\n",
+          s->path, errorstr);
       goto beach;
     }
@@ -443,5 +441,5 @@
   ret = fseek(s->fid, s->seek_start + pos * s->blockalign, SEEK_SET);
   if (ret != 0) {
-    AUBIO_ERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, strerror(errno));
+    AUBIO_STRERR("source_wavread: could not seek %s at %d (%s)\n", s->path, pos, errorstr);
     return AUBIO_FAIL;
   }
@@ -464,5 +462,5 @@
   }
   if (fclose(s->fid)) {
-    AUBIO_ERR("source_wavread: could not close %s (%s)\n", s->path, strerror(errno));
+    AUBIO_STRERR("source_wavread: could not close %s (%s)\n", s->path, errorstr);
     return AUBIO_FAIL;
   }
Index: tests/src/spectral/test-mfcc.c
===================================================================
--- tests/src/spectral/test-mfcc.c	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ tests/src/spectral/test-mfcc.c	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -34,7 +34,7 @@
   aubio_mfcc_t *mfcc = 0;
 
-  fvec_t *in = new_fvec (win_s); // input buffer
-  cvec_t *fftgrain = new_cvec (win_s); // input buffer
-  fvec_t *out = new_fvec (n_coeffs); // output coefficients
+  fvec_t *in = new_fvec (hop_s);       // phase vocoder input
+  cvec_t *fftgrain = new_cvec (win_s); // pvoc output / mfcc input
+  fvec_t *out = new_fvec (n_coeffs);   // mfcc output
 
   if (!in || !fftgrain || !out) { err = 1; goto failure; }
Index: wscript
===================================================================
--- wscript	(revision 08246ee55357da38cb8b16822834e5c610814cca)
+++ wscript	(revision 1dfe40925bf16faa125beae73a84e425dec95480)
@@ -146,4 +146,5 @@
     ctx.check(header_name='math.h')
     ctx.check(header_name='string.h')
+    ctx.check(header_name='errno.h')
     ctx.check(header_name='limits.h')
     ctx.check(header_name='stdarg.h')
@@ -650,5 +651,5 @@
     ctx.excl += ' **/.cache'
     ctx.excl += ' **/**.zip **/**.tar.bz2'
-    ctx.excl += ' **.tar.bz2'
+    ctx.excl += ' **.tar.bz2**'
     ctx.excl += ' **/doc/full/* **/doc/web/*'
     ctx.excl += ' **/doc/full.cfg'
@@ -662,5 +663,4 @@
     ctx.excl += ' **/.DS_Store'
     ctx.excl += ' **/.travis.yml'
-    ctx.excl += ' **/.landscape.yml'
     ctx.excl += ' **/.appveyor.yml'
     ctx.excl += ' **/.circleci/*'
