فهرست منبع

Move Audio trait to its own crate.

Add audio::Range type for treating a specific range of some other Audio
type as a new Audio type.

Use an integer step range for note mappings rather than a continuous hz
range.

Update to the latest version of hound which now supports decoding IEEE
float wavs.
mitchmindtree 10 سال پیش
والد
کامیت
3079254745
8فایلهای تغییر یافته به همراه510 افزوده شده و 343 حذف شده
  1. 4 4
      Cargo.toml
  2. 255 0
      src/audio.rs
  3. 2 1
      src/dynamic.rs
  4. 6 1
      src/lib.rs
  5. 7 262
      src/map.rs
  6. 14 13
      src/mode.rs
  7. 22 20
      src/sampler.rs
  8. 200 42
      src/serde.rs

+ 4 - 4
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "sampler"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["mitchmindtree <mitchell.nordine@gmail.com>"]
 description = "A polyphonic audio sampler instrument that supports unique sample mappings across both frequency and velocity ranges."
 readme = "README.md"
@@ -10,13 +10,13 @@ repository = "https://github.com/RustAudio/sampler.git"
 homepage = "https://github.com/RustAudio/sampler"
 
 [dependencies]
-instrument = "0.1.0"
+instrument = "0.2.0"
 pitch_calc = "0.11.0"
 time_calc = "0.11.0"
 sample = "0.6.0"
 
 # optional dependencies
-hound = { optional = true, version = "1.1.0" }
+hound = { optional = true, version = "2.0.0" }
 serde = { optional = true, version = "0.7.0" }
 serde_json = { optional = true, version = "0.7.0" }
 find_folder = { optional = true, version = "0.3.0" }
@@ -35,4 +35,4 @@ serde_serialization = [
 
 [dev-dependencies]
 find_folder = "0.3.0"
-portaudio = "0.6.2"
+portaudio = "0.6.4"

+ 255 - 0
src/audio.rs

@@ -0,0 +1,255 @@
+use sample;
+use std;
+
+
+/// The audio data that provides the slice of frames that are to be rendered.
+///
+/// By making this a trait instead of a hard type, we can allow users to use their own `Audio`
+/// types which might require other data (i.e. file paths, names, etc) for unique serialization
+/// implementations.
+pub trait Audio: Clone {
+    /// The type of `Frame` data associated with the audio.
+    type Frame: sample::Frame;
+    /// A reference to the slice of frames used to play the audio.
+    fn data(&self) -> &[Self::Frame];
+}
+
+/// A wrapper around `sampler::map::Audio` types that slices a specific range of frames.
+#[derive(Clone, Debug, PartialEq)]
+pub struct Range<A> {
+    /// The start index of the range.
+    pub start: usize,
+    /// The end index of the range.
+    pub end: usize,
+    /// Some audio type that implements `Audio` and can yield a slice of frames.
+    pub audio: A,
+}
+
+
+impl<A> Range<A> {
+    /// Construct a new `Range` with a max playback range.
+    pub fn new(audio: A) -> Self
+        where A: Audio,
+    {
+        Range {
+            start: 0,
+            end: audio.data().len(),
+            audio: audio,
+        }
+    }
+}
+
+impl<A> Audio for std::sync::Arc<A>
+    where A: Audio,
+{
+    type Frame = A::Frame;
+    #[inline]
+    fn data(&self) -> &[Self::Frame] {
+        A::data(self)
+    }
+}
+
+impl<A> Audio for Range<A>
+    where A: Audio,
+{
+    type Frame = A::Frame;
+    #[inline]
+    fn data(&self) -> &[Self::Frame] {
+        let slice = self.audio.data();
+        let len = slice.len();
+        if self.start < len && self.end <= len {
+            &slice[self.start..self.end]
+        } else {
+            &[]
+        }
+    }
+}
+
+
+#[cfg(feature="wav")]
+pub mod wav {
+    use hound;
+    use sample;
+    use std;
+
+
+    /// WAV data loaded into memory as a single contiguous slice of PCM frames.
+    #[derive(Clone, Debug, PartialEq)]
+    pub struct Audio<F> {
+        pub path: std::path::PathBuf,
+        pub data: Box<[F]>,
+        pub sample_hz: f64,
+    }
+
+    /// Errors that may occur during `WAV` loading
+    #[derive(Debug)]
+    pub enum Error {
+        /// Some error returned from the `hound` crate during sample loading.
+        Hound(hound::Error),
+        /// The bit depth of the given WAV file is unsupported.
+        UnsupportedBitsPerSample(u16),
+        /// There is no obvious way to map the given channels described in the WAV spec to the
+        /// number of channels in the `Frame` type.
+        ///
+        /// Contains the source number of channels and the target number of channels.
+        UnsupportedChannelMapping(u16, u16),
+    }
+
+
+    impl<F> super::Audio for Audio<F>
+        where F: sample::Frame,
+    {
+        type Frame = F;
+        fn data(&self) -> &[Self::Frame] {
+            &self.data[..]
+        }
+    }
+
+    impl<F> Audio<F>
+        where F: sample::Frame,
+              F::Sample: sample::Duplex<f64> + sample::Duplex<i32>,
+              Box<[F::Sample]>: sample::ToBoxedFrameSlice<F>,
+    {
+
+        /// Loads a `Sample` from the `.wav` file at the given `path`.
+        ///
+        /// The PCM data retrieved from the file will be:
+        /// - re-sized from its source bit rate to that of the target and
+        /// - re-sampled upon loading (rather than at playback) to the given target sample rate for
+        /// efficiency.
+        pub fn from_file<P>(path: P, target_sample_hz: f64) -> Result<Self, Error>
+            where P: AsRef<std::path::Path>,
+        {
+            use sample::{Frame, Sample, Signal};
+
+            let path = path.as_ref();
+            let mut wav_reader = try!(hound::WavReader::open(path));
+
+            let spec = wav_reader.spec();
+
+            // Collect the samples in a loop so that we may handle any errors if necessary.
+            let mut samples: Vec<F::Sample> = Vec::new();
+
+            // Reads the samples to their correct format type, and then converts them to the target
+            // `F::Sample` type.
+            type WavReader = hound::WavReader<std::io::BufReader<std::fs::File>>;
+            fn fill_samples<S, H>(samples: &mut Vec<S>, mut wav_reader: WavReader)
+                    -> Result<(), hound::Error>
+                where S: sample::FromSample<i32>,
+                      H: sample::Sample + sample::ToSample<i32> + hound::Sample,
+            {
+                for sample in wav_reader.samples() {
+                    let read_sample: H = try!(sample);
+                    let i32_sample: i32 = sample::Sample::to_sample(read_sample);
+                    samples.push(sample::Sample::to_sample(i32_sample));
+                }
+                Ok(())
+            }
+
+            match spec.sample_format {
+                hound::SampleFormat::Float => match spec.bits_per_sample {
+                    32 => try!(fill_samples::<_, f32>(&mut samples, wav_reader)),
+                    n => return Err(Error::UnsupportedBitsPerSample(n)),
+                },
+                hound::SampleFormat::Int => match spec.bits_per_sample {
+                    8 => try!(fill_samples::<_, i8>(&mut samples, wav_reader)),
+                    16 => try!(fill_samples::<_, i16>(&mut samples, wav_reader)),
+                    32 => try!(fill_samples::<_, i32>(&mut samples, wav_reader)),
+                    // The sample crate uses a specific type for 24 bit samples, so this 24-bit sample
+                    // conversion requires this special case.
+                    24 => {
+                        for sample in wav_reader.samples() {
+                            let read_sample: i32 = try!(sample);
+                            let i24_sample = try!(sample::I24::new(read_sample)
+                                .ok_or(hound::Error::FormatError("Incorrectly formatted 24-bit sample \
+                                                            received from hound::read::WavSamples")));
+                            let i32_sample: i32 = sample::Sample::to_sample(i24_sample);
+                            samples.push(sample::Sample::to_sample(i32_sample));
+                        }
+                    },
+                    n => return Err(Error::UnsupportedBitsPerSample(n)),
+                },
+            }
+
+            let boxed_samples = samples.into_boxed_slice();
+            let boxed_frames: Box<[F]> = match (spec.channels, F::n_channels() as u16) {
+
+                // In the case that the `spec` has a different number of channels to the actual
+                // slice, just collect as many valid frames as we can and discard the final
+                // mismatching frame.
+                (source, target) if source == target => {
+                    let samples = boxed_samples.iter().cloned();
+                    let vec: Vec<F> = sample::signal::from_interleaved_samples(samples)
+                        .collect();
+                    vec.into_boxed_slice()
+                },
+
+                // Sum the left and right channels together when mapping to a mono signal.
+                (2, 1) => {
+                    let samples = boxed_samples.iter().cloned();
+                    let vec: Vec<F> = 
+                        sample::signal::from_interleaved_samples::<_, [F::Sample; 2]>(samples)
+                            .filter_map(|f| {
+                                let mut channels = f.channels();
+                                channels.next()
+                                    .and_then(|l| channels.next().map(|r| (l, r)))
+                                    .map(|(l, r)| {
+                                        let sum = l.add_amp(r.to_signed_sample());
+                                        F::from_fn(|_| sum)
+                                    })
+                            })
+                            .collect();
+                    vec.into_boxed_slice()
+                },
+
+                // Simply copy the single mono channel to both channels in the output stereo
+                // signal.
+                (1, 2) => {
+                    let samples = boxed_samples.iter().cloned();
+                    let vec: Vec<F> = samples.map(|s| F::from_fn(|_| s)).collect();
+                    vec.into_boxed_slice()
+                },
+
+                (source, target) => {
+                    return Err(Error::UnsupportedChannelMapping(source, target))
+                },
+                
+            };
+
+            // Convert the sample rate to our target sample rate.
+            let frames: Vec<F> = boxed_frames.iter().cloned()
+                .from_hz_to_hz(spec.sample_rate as f64, target_sample_hz)
+                .collect();
+
+            Ok(Audio {
+                path: path.to_path_buf(),
+                sample_hz: target_sample_hz,
+                data: frames.into_boxed_slice(),
+            })
+        }
+
+    }
+
+    impl From<hound::Error> for Error {
+        fn from(err: hound::Error) -> Self {
+            Error::Hound(err)
+        }
+    }
+
+    impl std::error::Error for Error {
+        fn description(&self) -> &str {
+            match *self {
+                Error::Hound(ref hound) => std::error::Error::description(hound),
+                Error::UnsupportedBitsPerSample(_n_bits) => "unsupported bits per sample",
+                Error::UnsupportedChannelMapping(_source, _target) => "unsupported channel mapping",
+            }
+        }
+    }
+
+    impl std::fmt::Display for Error {
+        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+            std::fmt::Debug::fmt(self, f)
+        }
+    }
+
+}

+ 2 - 1
src/dynamic.rs

@@ -1,3 +1,4 @@
+use audio;
 use instrument;
 use map;
 use sampler;
@@ -12,7 +13,7 @@ pub type NoteFreqGenerator = instrument::note_freq::DynamicGenerator;
 pub type Sampler<A> = sampler::Sampler<Mode, NoteFreqGenerator, A>;
 
 impl<A> Sampler<A>
-    where A: map::Audio,
+    where A: audio::Audio,
 {
 
     /// Construct a dynamic `Sampler`.

+ 6 - 1
src/lib.rs

@@ -4,10 +4,12 @@ pub extern crate sample;
 extern crate pitch_calc as pitch;
 extern crate time_calc as time;
 
-pub use map::{Audio, Map, Sample};
+pub use audio::Audio;
+pub use map::{Map, Sample};
 pub use mode::Mode;
 pub use sampler::{Frames, Sampler};
 
+pub mod audio;
 pub mod dynamic;
 pub mod map;
 mod mode;
@@ -20,3 +22,6 @@ mod serde;
 pub type Step = i16;
 /// The force with which a note was pressed on a keyboard.
 pub type Velocity = f32;
+
+pub const MIN_STEP: Step = 0;
+pub const MAX_STEP: Step = 127;

+ 7 - 262
src/map.rs

@@ -1,7 +1,6 @@
+use {Step, Velocity, MIN_STEP, MAX_STEP};
+use audio::Audio;
 use pitch;
-use sample;
-use std;
-use {Step, Velocity};
 
 
 /// A type that maps frequncy and velocity ranges to audio samples.
@@ -10,18 +9,6 @@ pub struct Map<A> {
     pub pairs: Vec<SampleOverRange<A>>,
 }
 
-/// The audio data that provides the slice of frames that are to be rendered.
-///
-/// By making this a trait instead of a hard type, we can allow users to use their own `Audio`
-/// types which might require other data (i.e. file paths, names, etc) for unique serialization
-/// implementations.
-pub trait Audio: Clone {
-    /// The type of `Frame` data associated with the audio.
-    type Frame: sample::Frame;
-    /// A reference to the slice of frames used to play the audio.
-    fn data(&self) -> &[Self::Frame];
-}
-
 /// A performable `Sample` with some base playback Hz and Velocity.
 #[derive(Clone, Debug, PartialEq)]
 pub struct Sample<A> {
@@ -52,15 +39,6 @@ pub struct Range<T> {
 }
 
 
-impl<T> Audio for std::sync::Arc<T>
-    where T: Audio,
-{
-    type Frame = T::Frame;
-    fn data(&self) -> &[Self::Frame] {
-        T::data(self)
-    }
-}
-
 impl Range<Step> {
     /// Is the given step greater than or equal to the `min` and smaller than the `max`.
     pub fn is_over(&self, step: Step) -> bool {
@@ -129,7 +107,7 @@ impl<A> Map<A>
     /// Creates a `Map` with a single sample mapped to the entire Step and Velocity range.
     pub fn from_single_sample(sample: Sample<A>) -> Self {
         let range = StepVelRange {
-            step: Range { min: 0, max: 128 },
+            step: Range { min: MIN_STEP, max: MAX_STEP },
             vel: Range { min: 0.0, max: 1.0 },
         };
         let pairs = vec![SampleOverRange { range: range, sample: sample }];
@@ -165,120 +143,16 @@ impl<A> Map<A>
 
 #[cfg(feature="wav")]
 pub mod wav {
-    use hound;
+    use audio;
     use map;
     use pitch;
     use sample;
     use std;
 
-    /// WAV data loaded into memory as a single contiguous slice of PCM frames.
-    #[derive(Clone, Debug, PartialEq)]
-    pub struct Audio<F> {
-        pub path: std::path::PathBuf,
-        pub data: Box<[F]>,
-        pub sample_hz: f64,
-    }
 
     /// An alias for the `wav` `Sample` type.
-    pub type Sample<F> = super::Sample<std::sync::Arc<Audio<F>>>;
-
-    impl<F> super::Audio for Audio<F>
-        where F: sample::Frame,
-    {
-        type Frame = F;
-        fn data(&self) -> &[Self::Frame] {
-            &self.data[..]
-        }
-    }
-
-    impl<F> Audio<F>
-        where F: sample::Frame,
-              F::Sample: sample::Duplex<f64> + sample::Duplex<i32>,
-              Box<[F::Sample]>: sample::ToBoxedFrameSlice<F>,
-    {
+    pub type Sample<F> = super::Sample<std::sync::Arc<audio::wav::Audio<F>>>;
 
-        /// Loads a `Sample` from the `.wav` file at the given `path`.
-        ///
-        /// The PCM data retrieved from the file will be:
-        /// - re-sized from its source bit rate to that of the target and
-        /// - re-sampled upon loading (rather than at playback) to the given target sample rate for
-        /// efficiency.
-        pub fn from_file<P>(path: P, target_sample_hz: f64) -> Result<Self, hound::Error>
-            where P: AsRef<std::path::Path>,
-        {
-            use sample::Signal;
-
-            let path = path.as_ref();
-            let mut wav_reader = try!(hound::WavReader::open(path));
-
-            let spec = wav_reader.spec();
-            // TODO: Return an error instead of panic!ing! OR do some sort of frame /
-            // channel layout conversion.
-            assert!(spec.channels as usize == F::n_channels(),
-                    "The number of channels in the audio file differs from the number of \
-                    channels in the frame");
-
-            // Collect the samples in a loop so that we may handle any errors if necessary.
-            let mut samples: Vec<F::Sample> = Vec::new();
-
-            // Reads the samples to their correct format type, and then converts them to the target
-            // `F::Sample` type.
-            type WavReader = hound::WavReader<std::io::BufReader<std::fs::File>>;
-            fn fill_samples<S, H>(samples: &mut Vec<S>, mut wav_reader: WavReader)
-                    -> Result<(), hound::Error>
-                where S: sample::FromSample<i32>,
-                      H: sample::Sample + sample::ToSample<i32> + hound::Sample,
-            {
-                for sample in wav_reader.samples() {
-                    let read_sample: H = try!(sample);
-                    let i32_sample: i32 = sample::Sample::to_sample(read_sample);
-                    samples.push(sample::Sample::to_sample(i32_sample));
-                }
-                Ok(())
-            }
-
-            match spec.bits_per_sample {
-                8 => try!(fill_samples::<_, i8>(&mut samples, wav_reader)),
-                16 => try!(fill_samples::<_, i16>(&mut samples, wav_reader)),
-                32 => try!(fill_samples::<_, i32>(&mut samples, wav_reader)),
-                // The sample crate uses a specific type for 24 bit samples, so this 24-bit sample
-                // conversion requires this special case.
-                24 => {
-                    for sample in wav_reader.samples() {
-                        let read_sample: i32 = try!(sample);
-                        let i24_sample = try!(sample::I24::new(read_sample)
-                            .ok_or(hound::Error::FormatError("Incorrectly formatted 24-bit sample \
-                                                        received from hound::read::WavSamples")));
-                        let i32_sample: i32 = sample::Sample::to_sample(i24_sample);
-                        samples.push(sample::Sample::to_sample(i32_sample));
-                    }
-                },
-                _ => return Err(hound::Error::Unsupported),
-            }
-
-            let boxed_samples = samples.into_boxed_slice();
-            let boxed_frames: Box<[F]> = match sample::slice::to_boxed_frame_slice(boxed_samples) {
-                Some(slice) => slice,
-                // TODO: Return an error instead of panic!ing! OR do some sort of frame /
-                // channel layout conversion.
-                None => panic!("The number of samples produced from the wav file does not \
-                               match the number of channels ({}) in the given `Frame` type",
-                               F::n_channels()),
-            };
-
-            // Convert the sample rate to our target sample rate.
-            let frames: Vec<F> = boxed_frames.iter().cloned()
-                .from_hz_to_hz(spec.sample_rate as f64, target_sample_hz)
-                .collect();
-
-            Ok(Audio {
-                path: path.to_path_buf(),
-                sample_hz: target_sample_hz,
-                data: frames.into_boxed_slice(),
-            })
-        }
-
-    }
 
     impl<F> Sample<F>
         where F: sample::Frame,
@@ -295,7 +169,7 @@ pub mod wav {
         ///
         /// The PCM data retrieved from the file will be re-sampled upon loading (rather than at
         /// playback) to the given target sample rate for efficiency.
-        pub fn from_wav_file<P>(path: P, target_sample_hz: f64) -> Result<Self, hound::Error>
+        pub fn from_wav_file<P>(path: P, target_sample_hz: f64) -> Result<Self, audio::wav::Error>
             where P: AsRef<std::path::Path>,
         {
             let path = path.as_ref();
@@ -305,141 +179,12 @@ pub mod wav {
             let base_hz = base_letter_octave.to_hz();
             let base_vel = 1.0;
 
-            let audio = std::sync::Arc::new(try!(Audio::from_file(path, target_sample_hz)));
+            let audio = std::sync::Arc::new(try!(audio::wav::Audio::from_file(path, target_sample_hz)));
 
             Ok(map::Sample::new(base_hz, base_vel, audio))
         }
     }
 
-    // impl<F> map::Map<F>
-    //     where F: sample::Frame,
-    //           F::Sample: sample::Duplex<f64> + hound::Sample,
-    //           Box<[F::Sample]>: sample::ToBoxedFrameSlice<F>,
-    // {
-
-    //     /// Loads a `Map` from the given directory.
-    //     ///
-    //     /// All `.wav` files that can be successfully loaded will be loaded into the `Map`.
-    //     ///
-    //     /// If the `.wav` file has a musical note in the file name, that note's playback frequency in
-    //     /// `hz` will be used as the `base_hz`.
-    //     ///
-    //     /// For efficiency, all files will be re-sampled upon loading (rather than at playback) to the
-    //     /// given target sample rate.
-    //     pub fn from_wav_directory<P>(path: P, target_sample_hz: f64) -> Result<Self, hound::Error>
-    //         where P: AsRef<std::path::Path>,
-    //     {
-    //         use sample::Signal;
-    //         use std::cmp::Ordering;
-
-    //         let path = path.as_ref();
-
-    //         struct SampleReader {
-    //             base_letter_octave: Option<pitch::LetterOctave>,
-    //             wav_reader: hound::WavReader<std::io::BufReader<std::fs::File>>,
-    //         }
-
-    //         let mut sample_readers: Vec<SampleReader> = Vec::new();
-
-    //         // Find all .wav files in the given directory and store them as `SampleReader`s.
-    //         for entry in try!(std::fs::read_dir(path)) {
-    //             let file_name = try!(entry).file_name();
-
-    //             // If the entry is a wave file, add it to our list.
-    //             if has_wav_ext(file_name.as_ref()) {
-    //                 let wav_reader = try!(hound::WavReader::open(&file_name));
-    //                 let sample_reader = SampleReader {
-    //                     base_letter_octave: read_base_letter_octave(file_name.as_ref()),
-    //                     wav_reader: wav_reader,
-    //                 };
-    //                 sample_readers.push(sample_reader);
-    //             }
-    //         }
-
-    //         // Sort the readers by their base hz.
-    //         sample_readers.sort_by(|a, b| match (a.base_letter_octave, b.base_letter_octave) {
-    //             (Some(_), None) => Ordering::Less,
-    //             (None, Some(_)) => Ordering::Greater,
-    //             (Some(a), Some(b)) => a.cmp(&b),
-    //             (None, None) => Ordering::Equal,
-    //         });
-
-    //         const DEFAULT_LETTER_OCTAVE: pitch::LetterOctave =
-    //             pitch::LetterOctave(pitch::Letter::C, 1);
-    //         let mut maybe_last_step = None;
-
-    //         // We must imperatively collect the mappings so that we can handle any errors.
-    //         let mut mappings = Vec::with_capacity(sample_readers.len());
-    //         for SampleReader { base_letter_octave, mut wav_reader } in sample_readers {
-    //             let base_vel = 1.0;
-    //             let base_hz = match base_letter_octave {
-    //                 Some(letter_octave) => {
-    //                     maybe_last_step = Some(letter_octave.step());
-    //                     letter_octave.to_hz()
-    //                 },
-    //                 None => {
-    //                     let last_step = maybe_last_step.unwrap_or(DEFAULT_LETTER_OCTAVE.step());
-    //                     let step = last_step + 1.0;
-    //                     maybe_last_step = Some(step);
-    //                     pitch::Step(step).to_hz()
-    //                 },
-    //             };
-
-    //             let audio = {
-    //                 let spec = wav_reader.spec();
-
-    //                 // Collect the samples in a loop so that we may handle any errors if necessary.
-    //                 let mut samples: Vec<F::Sample> = Vec::new();
-    //                 for sample in wav_reader.samples() {
-    //                     samples.push(try!(sample));
-    //                 }
-
-    //                 let boxed_samples = samples.into_boxed_slice();
-    //                 let boxed_frames: Box<[F]> = match sample::slice::to_boxed_frame_slice(boxed_samples) {
-    //                     Some(slice) => slice,
-    //                     // TODO: Return an error instead of panic!ing! OR do some sort of frame /
-    //                     // channel layout conversion.
-    //                     None => panic!("The number of samples produced from the wav file does not \
-    //                                    match the number of channels ({}) in the given `Frame` type",
-    //                                    F::n_channels()),
-    //                 };
-
-    //                 // Convert the sample rate to our target sample rate.
-    //                 let frames: Vec<F> = boxed_frames.iter().cloned()
-    //                     .from_hz_to_hz(spec.sample_rate as f64, target_sample_hz)
-    //                     .collect();
-
-    //                 map::Audio::new(frames.into_boxed_slice())
-    //             };
-
-    //             let sample = map::Sample::new(base_hz, base_vel, audio);
-
-    //             // The `Hz` range that triggers this sample will span from the last sample's Hz (or
-    //             // the minimum if there is no last sample) to the following `to_hz` value.
-    //             //
-    //             // TODO: Investigate a nicer way of evenly spreading samples across the keyboard.
-    //             let to_hz = pitch::Step(base_hz.step() + 0.5).to_hz();
-    //             let to_vel = base_vel;
-    //             mappings.push((to_hz, to_vel, sample));
-    //         }
-
-    //         Ok(Self::from_sequential_mappings(mappings))
-    //     }
-
-    // }
-
-    ///// Utility functions.
-
-    // /// Determines whether the given `Path` leads to a wave file.
-    // fn has_wav_ext(path: &std::path::Path) -> bool {
-    //     let ext = path.extension()
-    //         .and_then(|s| s.to_str())
-    //         .map_or("".into(), std::ascii::AsciiExt::to_ascii_lowercase);
-    //     match &ext[..] {
-    //         "wav" | "wave" => true,
-    //         _ => false,
-    //     }
-    // }
 
     /// Scans the given path for an indication of its pitch.
     fn read_base_letter_octave(path: &std::path::Path) -> Option<pitch::LetterOctave> {

+ 14 - 13
src/mode.rs

@@ -1,12 +1,13 @@
-pub use instrument::mode::{Mono, MonoKind, Poly, Dynamic};
+use audio::Audio;
 use instrument;
-use map::{self, Map};
+use map::Map;
 use pitch;
-use sample::Frame;
 use sampler::PlayingSample;
 use std;
 use Velocity;
 
+pub use instrument::mode::{Mono, MonoKind, Poly, Dynamic};
+
 /// The "mode" with which the Sampler will handle notes.
 pub trait Mode {
 
@@ -18,20 +19,20 @@ pub trait Mode {
                   note_velocity: Velocity,
                   map: &Map<A>,
                   voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio;
+        where A: Audio;
 
     /// Handle a `note_off` event.
     fn note_off<A>(&self,
                    note_hz: pitch::Hz,
                    map: &Map<A>,
                    voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio;
+        where A: Audio;
 }
 
 
 // Helper function for constructing a `PlayingSample`.
 fn play_sample<A>(hz: pitch::Hz, vel: Velocity, map: &Map<A>) -> Option<PlayingSample<A>>
-    where A: map::Audio,
+    where A: Audio,
 {
     play_sample_from_playhead_idx(0, hz, vel, map)
 }
@@ -41,7 +42,7 @@ fn play_sample_from_playhead_idx<A>(idx: usize,
                                     hz: pitch::Hz,
                                     vel: Velocity,
                                     map: &Map<A>) -> Option<PlayingSample<A>>
-    where A: map::Audio,
+    where A: Audio,
 {
     map.sample(hz, vel).map(|sample| PlayingSample::from_playhead_idx(idx, hz, vel, sample))
 }
@@ -54,7 +55,7 @@ impl Mode for Mono {
                   note_vel: Velocity,
                   map: &Map<A>,
                   voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         let Mono(ref kind, ref note_stack) = *self;
 
@@ -88,7 +89,7 @@ impl Mode for Mono {
                    note_hz: pitch::Hz,
                    map: &Map<A>,
                    voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         let Mono(kind, ref note_stack) = *self;
 
@@ -130,7 +131,7 @@ impl Mode for Poly {
                   note_vel: Velocity,
                   map: &Map<A>,
                   voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         let sample = match play_sample(note_hz, note_vel, map) {
             Some(sample) => sample,
@@ -160,7 +161,7 @@ impl Mode for Poly {
                    _note_hz: pitch::Hz,
                    _map: &Map<A>,
                    _voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         // No need to do anything here as voices will be set to `None` when frames yielded by
         // `instrument` run out.
@@ -175,7 +176,7 @@ impl Mode for Dynamic {
                   note_vel: Velocity,
                   map: &Map<A>,
                   voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         match *self {
             Dynamic::Mono(ref mono) => mono.note_on(note_hz, note_vel, map, voices),
@@ -187,7 +188,7 @@ impl Mode for Dynamic {
                    note_hz: pitch::Hz,
                    map: &Map<A>,
                    voices: &mut [Option<PlayingSample<A>>])
-        where A: map::Audio,
+        where A: Audio,
     {
         match *self {
             Dynamic::Mono(ref mono) => mono.note_off(note_hz, map, voices),

+ 22 - 20
src/sampler.rs

@@ -1,3 +1,4 @@
+use audio::Audio;
 use instrument::{self, Instrument};
 use map::{self, Map};
 use pitch;
@@ -10,7 +11,7 @@ use Velocity;
 #[derive(Clone, Debug)]
 pub struct Sampler<M, NFG, A>
     where NFG: instrument::NoteFreqGenerator,
-          A: map::Audio,
+          A: Audio,
 {
     pub instrument: Instrument<M, NFG>,
     pub map: Map<A>,
@@ -27,7 +28,7 @@ pub struct Sampler<M, NFG, A>
 /// `Vec` indices.
 #[derive(Clone)]
 pub struct Voices<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     map: Vec<Option<PlayingSample<A>>>,
 }
@@ -35,7 +36,7 @@ pub struct Voices<A>
 /// A sample that is currently being played back.
 #[derive(Clone)]
 pub struct PlayingSample<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     /// The pitch in hz at which the `note_on` was triggered.
     pub note_on_hz: pitch::Hz,
@@ -51,7 +52,7 @@ pub struct PlayingSample<A>
 /// An owned iterator that wraps an audio file but does not 
 #[derive(Clone)]
 pub struct Playhead<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     /// The position of the playhead over the `Sample`.
     pub idx: usize,
@@ -60,7 +61,7 @@ pub struct Playhead<A>
 
 /// An iterator yielding one frame from the `Sampler` at a time.
 pub struct Frames<'a, A: 'a, NF: 'a>
-    where A: map::Audio,
+    where A: Audio,
 {
     voices: &'a mut Voices<A>,
     instrument_frames: instrument::Frames<'a, NF>,
@@ -68,7 +69,7 @@ pub struct Frames<'a, A: 'a, NF: 'a>
 
 
 impl<A> std::fmt::Debug for Voices<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
         write!(f, "Voices {{ num: {:?} }}", self.map.len())
@@ -77,7 +78,7 @@ impl<A> std::fmt::Debug for Voices<A>
 
 impl<NFG, A> Sampler<instrument::mode::Mono, NFG, A>
     where NFG: instrument::NoteFreqGenerator,
-          A: map::Audio,
+          A: Audio,
 {
     /// Construct a `Sampler` with a `Mono::Legato` playback mode.
     pub fn legato(nfg: NFG, map: Map<A>) -> Self {
@@ -87,7 +88,7 @@ impl<NFG, A> Sampler<instrument::mode::Mono, NFG, A>
 
 impl<NFG, A> Sampler<instrument::mode::Mono, NFG, A>
     where NFG: instrument::NoteFreqGenerator,
-          A: map::Audio,
+          A: Audio,
 {
     /// Construct a `Sampler` with a `Mono::Retrigger` playback mode.
     pub fn retrigger(nfg: NFG, map: Map<A>) -> Self {
@@ -97,7 +98,7 @@ impl<NFG, A> Sampler<instrument::mode::Mono, NFG, A>
 
 impl<NFG, A> Sampler<instrument::mode::Poly, NFG, A>
     where NFG: instrument::NoteFreqGenerator,
-          A: map::Audio,
+          A: Audio,
 {
     /// Construct a `Sampler` with a `Poly` playback mode.
     pub fn poly(nfg: NFG, map: Map<A>) -> Self {
@@ -108,7 +109,7 @@ impl<NFG, A> Sampler<instrument::mode::Poly, NFG, A>
 
 impl<M, NFG, A> Sampler<M, NFG, A>
     where NFG: instrument::NoteFreqGenerator,
-          A: map::Audio,
+          A: Audio,
 {
 
     /// Construct a new `Sampler`.
@@ -215,7 +216,7 @@ impl<M, NFG, A> Sampler<M, NFG, A>
 
     /// Produces an iterator that yields `Frame`s of audio data.
     pub fn frames(&mut self, sample_hz: f64) -> Frames<A, NFG::NoteFreq>
-        where A: map::Audio,
+        where A: Audio,
               <A::Frame as Frame>::Sample: sample::Duplex<f64>,
               <<A::Frame as Frame>::Sample as PcmSample>::Float: sample::FromSample<f32>,
     {
@@ -240,7 +241,7 @@ impl<M, NFG, A> Sampler<M, NFG, A>
         where F: Frame,
               F::Sample: sample::Duplex<f64>,
               <F::Sample as PcmSample>::Float: sample::FromSample<f32>,
-              A: map::Audio<Frame=F>,
+              A: Audio<Frame=F>,
     {
         let mut frames = self.frames(sample_hz);
         sample::slice::map_in_place(output, |f| {
@@ -255,15 +256,16 @@ impl<M, NFG, A> Sampler<M, NFG, A>
 
 #[cfg(feature="serde_serialization")]
 pub mod private {
+    use audio::Audio;
     use instrument::{self, Instrument};
-    use map::{self, Map};
+    use map::Map;
 
     /// A private constructor for use within serde.rs.
     pub fn new<M, NFG, A>(instrument: Instrument<M, NFG>,
                           map: Map<A>,
                           num_voices: usize) -> super::Sampler<M, NFG, A>
         where NFG: instrument::NoteFreqGenerator,
-              A: map::Audio,
+              A: Audio,
     {
         super::Sampler {
             instrument: instrument,
@@ -275,7 +277,7 @@ pub mod private {
 
 
 impl<A> PlayingSample<A>
-    where A: map::Audio,
+    where A: Audio,
 {
 
     /// Construct a new `PlayingSample` from the given note hz, velocity and the associated
@@ -310,7 +312,7 @@ impl<A> PlayingSample<A>
 
 
 impl<A> Playhead<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     /// Wrap the given `Audio` with a `Playhead` starting from 0.
     pub fn new(audio: A) -> Self {
@@ -327,20 +329,20 @@ impl<A> Playhead<A>
 }
 
 impl<A> Iterator for Playhead<A>
-    where A: map::Audio,
+    where A: Audio,
 {
     type Item = A::Frame;
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
         let idx = self.idx;
         self.idx += 1;
-        map::Audio::data(&self.audio).get(idx).map(|&f| f)
+        Audio::data(&self.audio).get(idx).map(|&f| f)
     }
 }
 
 
 impl<'a, A, NF> Frames<'a, A, NF>
-    where A: map::Audio,
+    where A: Audio,
           <A::Frame as Frame>::Sample: sample::Duplex<f64>,
           <<A::Frame as Frame>::Sample as PcmSample>::Float: sample::FromSample<f32>,
           NF: instrument::NoteFreq,
@@ -386,7 +388,7 @@ impl<'a, A, NF> Frames<'a, A, NF>
 }
 
 impl<'a, A, NF> Iterator for Frames<'a, A, NF>
-    where A: map::Audio,
+    where A: Audio,
           <A::Frame as Frame>::Sample: sample::Duplex<f64>,
           <<A::Frame as Frame>::Sample as PcmSample>::Float: sample::FromSample<f32>,
           NF: instrument::NoteFreq,

+ 200 - 42
src/serde.rs

@@ -1,6 +1,171 @@
 extern crate serde;
 
 
+mod audio_range {
+    use audio::Range;
+    use super::serde;
+    use std;
+
+    impl<T> serde::Serialize for Range<T>
+        where T: serde::Serialize,
+    {
+        fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
+            where S: serde::Serializer,
+        {
+            struct Visitor<'a, T: 'a> {
+                t: &'a Range<T>,
+                field_idx: u8,
+            }
+
+            impl<'a, T> serde::ser::MapVisitor for Visitor<'a, T>
+                where T: serde::Serialize,
+            {
+                fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
+                    where S: serde::Serializer,
+                {
+                    match self.field_idx {
+                        0 => {
+                            self.field_idx += 1;
+                            Ok(Some(try!(serializer.serialize_struct_elt("start", &self.t.start))))
+                        },
+                        1 => {
+                            self.field_idx += 1;
+                            Ok(Some(try!(serializer.serialize_struct_elt("end", &self.t.end))))
+                        },
+                        2 => {
+                            self.field_idx += 1;
+                            Ok(Some(try!(serializer.serialize_struct_elt("audio", &self.t.audio))))
+                        },
+                        _ => Ok(None),
+                    }
+                }
+
+                fn len(&self) -> Option<usize> {
+                    Some(3)
+                }
+            }
+
+            serializer.serialize_struct("Range", Visitor { t: self, field_idx: 0 })
+        }
+    }
+
+    impl<T> serde::Deserialize for Range<T>
+        where T: serde::Deserialize,
+    {
+        fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
+            where D: serde::Deserializer,
+        {
+            struct Visitor<T> {
+                t: std::marker::PhantomData<T>,
+            };
+
+            impl<T> serde::de::Visitor for Visitor<T>
+                where T: serde::Deserialize,
+            {
+                type Value = Range<T>;
+
+                fn visit_map<V>(&mut self, mut visitor: V) -> Result<Range<T>, V::Error>
+                    where V: serde::de::MapVisitor,
+                {
+                    let mut start = None;
+                    let mut end = None;
+                    let mut audio = None;
+
+                    enum Field { Start, End, Audio }
+
+                    impl serde::Deserialize for Field {
+                        fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
+                            where D: serde::de::Deserializer,
+                        {
+                            struct FieldVisitor;
+
+                            impl serde::de::Visitor for FieldVisitor {
+                                type Value = Field;
+
+                                fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
+                                    where E: serde::de::Error,
+                                {
+                                    match value {
+                                        "start" => Ok(Field::Start),
+                                        "end" => Ok(Field::End),
+                                        "audio" => Ok(Field::Audio),
+                                        _ => Err(serde::de::Error::custom("expected start, end or audio")),
+                                    }
+                                }
+                            }
+
+                            deserializer.deserialize(FieldVisitor)
+                        }
+                    }
+
+                    loop {
+                        match try!(visitor.visit_key()) {
+                            Some(Field::Start) => { start = Some(try!(visitor.visit_value())); },
+                            Some(Field::End) => { end = Some(try!(visitor.visit_value())); },
+                            Some(Field::Audio) => { audio = Some(try!(visitor.visit_value())); },
+                            None => { break; }
+                        }
+                    }
+
+                    let start = match start {
+                        Some(start) => start,
+                        None => return Err(serde::de::Error::missing_field("start")),
+                    };
+
+                    let end = match end {
+                        Some(end) => end,
+                        None => return Err(serde::de::Error::missing_field("end")),
+                    };
+
+                    let audio = match audio {
+                        Some(audio) => audio,
+                        None => return Err(serde::de::Error::missing_field("audio")),
+                    };
+
+                    try!(visitor.end());
+
+                    Ok(Range {
+                        start: start,
+                        end: end,
+                        audio: audio,
+                    })
+                }
+            }
+
+            static FIELDS: &'static [&'static str] = &["start", "end", "audio"];
+
+            let visitor = Visitor { t: std::marker::PhantomData };
+
+            deserializer.deserialize_struct("Range", FIELDS, visitor)
+        }
+    }
+
+    #[test]
+    fn test() {
+        extern crate serde_json;
+
+        use audio::Audio;
+
+        impl Audio for () {
+            type Frame = [f32; 2];
+            fn data(&self) -> &[Self::Frame] { &[] }
+        }
+
+        let range = Range { start: 0, end: 0, audio: () };
+        let serialized = serde_json::to_string(&range).unwrap();
+
+        println!("{}", serialized);
+        assert_eq!("{\"start\":0,\"end\":0,\"audio\":null}", serialized);
+
+        let deserialized: Range<()> = serde_json::from_str(&serialized).unwrap();
+
+        println!("{:?}", deserialized);
+        assert_eq!(range, deserialized);
+    }
+
+
+}
+
 mod range {
     use super::serde;
     use map::Range;
@@ -286,13 +451,6 @@ mod sample {
     fn test() {
         extern crate serde_json;
 
-        use map;
-
-        impl map::Audio for () {
-            type Frame = [f32; 2];
-            fn data(&self) -> &[Self::Frame] { &[] }
-        }
-
         let sample = Sample { base_hz: 440.0.into(), base_vel: 1.0, audio: () };
         let serialized = serde_json::to_string(&sample).unwrap();
 
@@ -436,14 +594,14 @@ mod sample_over_range {
 
         use map;
 
-        // impl map::Audio for () {
+        // impl Audio for () {
         //     type Frame = [f32; 2];
         //     fn data(&self) -> &[Self::Frame] { &[] }
         // }
 
         let sample = map::Sample { base_hz: 440.0.into(), base_vel: 1.0, audio: () };
-        let range = map::HzVelRange {
-            hz: map::Range { min: 220.0.into(), max: 440.0.into() },
+        let range = map::StepVelRange {
+            step: map::Range { min: 0, max: 127 },
             vel: map::Range { min: 0.0, max: 1.0 },
         };
 
@@ -451,7 +609,7 @@ mod sample_over_range {
         let serialized = serde_json::to_string(&sample_over_range).unwrap();
 
         println!("{}", serialized);
-        assert_eq!("{\"range\":{\"hz\":{\"min\":220,\"max\":440},\"vel\":{\"min\":0,\"max\":1}},\"sample\":{\"base_hz\":440,\"base_vel\":1,\"audio\":null}}", serialized);
+        assert_eq!("{\"range\":{\"step\":{\"min\":0,\"max\":127},\"vel\":{\"min\":0,\"max\":1}},\"sample\":{\"base_hz\":440,\"base_vel\":1,\"audio\":null}}", serialized);
         
         let deserialized: SampleOverRange<()> = serde_json::from_str(&serialized).unwrap();
 
@@ -462,16 +620,16 @@ mod sample_over_range {
 }
 
 
-mod hz_vel_range {
+mod step_vel_range {
     use super::serde;
-    use map::HzVelRange;
+    use map::StepVelRange;
 
-    impl serde::Serialize for HzVelRange {
+    impl serde::Serialize for StepVelRange {
         fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
             where S: serde::Serializer,
         {
             struct Visitor<'a> {
-                t: &'a HzVelRange,
+                t: &'a StepVelRange,
                 field_idx: u8,
             }
 
@@ -482,7 +640,7 @@ mod hz_vel_range {
                     match self.field_idx {
                         0 => {
                             self.field_idx += 1;
-                            Ok(Some(try!(serializer.serialize_struct_elt("hz", &self.t.hz))))
+                            Ok(Some(try!(serializer.serialize_struct_elt("step", &self.t.step))))
                         },
                         1 => {
                             self.field_idx += 1;
@@ -497,26 +655,26 @@ mod hz_vel_range {
                 }
             }
 
-            serializer.serialize_struct("HzVelRange", Visitor { t: self, field_idx: 0 })
+            serializer.serialize_struct("StepVelRange", Visitor { t: self, field_idx: 0 })
         }
     }
 
-    impl serde::Deserialize for HzVelRange {
+    impl serde::Deserialize for StepVelRange {
         fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
             where D: serde::Deserializer,
         {
             struct Visitor;
 
             impl serde::de::Visitor for Visitor {
-                type Value = HzVelRange;
+                type Value = StepVelRange;
 
-                fn visit_map<V>(&mut self, mut visitor: V) -> Result<HzVelRange, V::Error>
+                fn visit_map<V>(&mut self, mut visitor: V) -> Result<StepVelRange, V::Error>
                     where V: serde::de::MapVisitor,
                 {
-                    let mut hz = None;
+                    let mut step = None;
                     let mut vel = None;
 
-                    enum Field { Hz, Vel }
+                    enum Field { Step, Vel }
 
                     impl serde::Deserialize for Field {
                         fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
@@ -531,9 +689,9 @@ mod hz_vel_range {
                                     where E: serde::de::Error,
                                 {
                                     match value {
-                                        "hz" => Ok(Field::Hz),
+                                        "step" => Ok(Field::Step),
                                         "vel" => Ok(Field::Vel),
-                                        _ => Err(serde::de::Error::custom("expected hz or vel")),
+                                        _ => Err(serde::de::Error::custom("expected step or vel")),
                                     }
                                 }
                             }
@@ -544,15 +702,15 @@ mod hz_vel_range {
 
                     loop {
                         match try!(visitor.visit_key()) {
-                            Some(Field::Hz) => { hz = Some(try!(visitor.visit_value())); },
+                            Some(Field::Step) => { step = Some(try!(visitor.visit_value())); },
                             Some(Field::Vel) => { vel = Some(try!(visitor.visit_value())); },
                             None => { break; }
                         }
                     }
 
-                    let hz = match hz {
-                        Some(hz) => hz,
-                        None => return Err(serde::de::Error::missing_field("hz")),
+                    let step = match step {
+                        Some(step) => step,
+                        None => return Err(serde::de::Error::missing_field("step")),
                     };
 
                     let vel = match vel {
@@ -562,15 +720,15 @@ mod hz_vel_range {
 
                     try!(visitor.end());
 
-                    Ok(HzVelRange { hz: hz, vel: vel })
+                    Ok(StepVelRange { step: step, vel: vel })
                 }
             }
 
-            static FIELDS: &'static [&'static str] = &["hz", "vel"];
+            static FIELDS: &'static [&'static str] = &["step", "vel"];
 
             let visitor = Visitor;
 
-            deserializer.deserialize_struct("HzVelRange", FIELDS, visitor)
+            deserializer.deserialize_struct("StepVelRange", FIELDS, visitor)
         }
     }
 
@@ -579,16 +737,16 @@ mod hz_vel_range {
         extern crate serde_json;
         use map;
 
-        let range = HzVelRange {
-            hz: map::Range { min: 220.0.into(), max: 440.0.into() },
+        let range = StepVelRange {
+            step: map::Range { min: 0, max: 127 },
             vel: map::Range { min: 0.0, max: 1.0 },
         };
         let serialized = serde_json::to_string(&range).unwrap();
 
         println!("{}", serialized);
-        assert_eq!("{\"hz\":{\"min\":220,\"max\":440},\"vel\":{\"min\":0,\"max\":1}}", serialized);
+        assert_eq!("{\"step\":{\"min\":0,\"max\":127},\"vel\":{\"min\":0,\"max\":1}}", serialized);
         
-        let deserialized: HzVelRange = serde_json::from_str(&serialized).unwrap();
+        let deserialized: StepVelRange = serde_json::from_str(&serialized).unwrap();
 
         println!("{:?}", deserialized);
         assert_eq!(range, deserialized);
@@ -728,8 +886,8 @@ mod map {
 
 
 mod sampler {
+    use audio::Audio;
     use instrument;
-    use map;
     use super::serde;
     use sampler::{self, Sampler};
     use std;
@@ -738,14 +896,14 @@ mod sampler {
         where M: serde::Serialize,
               NFG: serde::Serialize + instrument::NoteFreqGenerator,
               NFG::NoteFreq: serde::Serialize,
-              A: serde::Serialize + map::Audio,
+              A: serde::Serialize + Audio,
     {
         fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
             where S: serde::Serializer,
         {
             struct Visitor<'a, M: 'a, NFG: 'a, A: 'a>
                 where NFG: instrument::NoteFreqGenerator,
-                      A: map::Audio,
+                      A: Audio,
             {
                 t: &'a Sampler<M, NFG, A>,
                 field_idx: u8,
@@ -755,7 +913,7 @@ mod sampler {
                 where M: serde::Serialize,
                       NFG: serde::Serialize + instrument::NoteFreqGenerator,
                       NFG::NoteFreq: serde::Serialize,
-                      A: serde::Serialize + map::Audio,
+                      A: serde::Serialize + Audio,
             {
                 fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
                     where S: serde::Serializer,
@@ -791,7 +949,7 @@ mod sampler {
         where M: serde::Deserialize,
               NFG: serde::Deserialize + instrument::NoteFreqGenerator,
               NFG::NoteFreq: serde::Deserialize,
-              A: serde::Deserialize + map::Audio,
+              A: serde::Deserialize + Audio,
     {
         fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
             where D: serde::Deserializer,
@@ -806,7 +964,7 @@ mod sampler {
                 where M: serde::Deserialize,
                       NFG: serde::Deserialize + instrument::NoteFreqGenerator,
                       NFG::NoteFreq: serde::Deserialize,
-                      A: serde::Deserialize + map::Audio,
+                      A: serde::Deserialize + Audio,
             {
                 type Value = Sampler<M, NFG, A>;
 
@@ -914,7 +1072,7 @@ mod sampler {
 mod wav_audio {
     extern crate find_folder;
 
-    use map::wav;
+    use audio::wav;
     use sample;
     use super::serde;
     use std;