001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030/**
031 *
032 */
033package org.openimaj.audio;
034
035import java.util.List;
036import java.util.Set;
037
038import org.openimaj.feature.DoubleFV;
039import org.openimaj.feature.DoubleFVComparison;
040import org.openimaj.feature.FeatureExtractor;
041import org.openimaj.feature.IdentityFeatureExtractor;
042import org.openimaj.ml.annotation.Annotated;
043import org.openimaj.ml.annotation.IncrementalAnnotator;
044import org.openimaj.ml.annotation.ScoredAnnotation;
045import org.openimaj.ml.annotation.basic.KNNAnnotator;
046import org.openimaj.ml.annotation.bayes.NaiveBayesAnnotator;
047import org.openimaj.ml.annotation.bayes.NaiveBayesAnnotator.Mode;
048
049/**
050 * A classifier/annotator for audio frames. Note that this is a pretty general
051 * annotator that takes {@link DoubleFV}s and String labels. The
052 * {@link DoubleFV}s can be extracted from audio with this class also, as it
053 * also implements FeatureExtractor interface for {@link SampleChunk}s
054 * (returning {@link DoubleFV}s). However, there is no implementation for the
055 * necessary {@link FeatureExtractor#extractFeature(Object)} method, so
056 * subclasses must implement this. The default annotator in use is a general
057 * {@link KNNAnnotator} for {@link DoubleFV}s, however, this can be changed
058 * using {@link #setAnnotator(AudioAnnotatorType)}.
059 * 
060 * @author David Dupplaw (dpd@ecs.soton.ac.uk)
061 * @created 8 Mar 2013
062 */
063public abstract class AudioAnnotator
064                extends
065                IncrementalAnnotator<DoubleFV, String>
066                implements
067                FeatureExtractor<DoubleFV, SampleChunk>
068{
069        /**
070         * An enumeration that allows different trainers to be used and specified on
071         * the command-line.
072         * 
073         * @author David Dupplaw (dpd@ecs.soton.ac.uk)
074         * @created 6 Dec 2012
075         * @version $Author$, $Revision$, $Date$
076         */
077        public enum AudioAnnotatorType
078        {
079                /** KNN Annotator */
080                KNN {
081                        private KNNAnnotator<DoubleFV, String, DoubleFV> k;
082
083                        @Override
084                        public IncrementalAnnotator<DoubleFV, String> getAnnotator()
085                        {
086                                if (this.k == null)
087                                        this.k = new KNNAnnotator<DoubleFV, String, DoubleFV>(
088                                                        new IdentityFeatureExtractor<DoubleFV>(),
089                                                        DoubleFVComparison.EUCLIDEAN);
090                                return this.k;
091                        }
092                },
093
094                /** Naive Bayes annotator */
095                BAYES {
096                        private IncrementalAnnotator<DoubleFV, String> n;
097
098                        @Override
099                        public IncrementalAnnotator<DoubleFV, String> getAnnotator()
100                        {
101                                if (this.n == null)
102                                        this.n = new NaiveBayesAnnotator<DoubleFV, String>(
103                                                        new IdentityFeatureExtractor<DoubleFV>(),
104                                                        Mode.ALL);
105                                return this.n;
106                        }
107                };
108
109                /**
110                 * Returns a annotator that can train a DoubleFV feature with a specific
111                 * String label. The annotators will all have
112                 * {@link IdentityFeatureExtractor} feature extractors so the audio
113                 * features must be extracted before hand.
114                 * 
115                 * @return The annotator
116                 */
117                public abstract IncrementalAnnotator<DoubleFV, String> getAnnotator();
118        }
119
120        /** The specfic annotator being used */
121        private AudioAnnotatorType annotator = AudioAnnotatorType.KNN;
122
123        /**
124         * {@inheritDoc}
125         * 
126         * @see org.openimaj.ml.training.IncrementalTrainer#train(java.lang.Object)
127         */
128        @Override
129        public void train(final Annotated<DoubleFV, String> annotated)
130        {
131                this.getAnnotator().getAnnotator().train(annotated);
132        }
133
134        /**
135         * {@inheritDoc}
136         * 
137         * @see org.openimaj.ml.training.IncrementalTrainer#reset()
138         */
139        @Override
140        public void reset()
141        {
142                this.getAnnotator().getAnnotator().reset();
143        }
144
145        /**
146         * {@inheritDoc}
147         * 
148         * @see org.openimaj.ml.annotation.Annotator#getAnnotations()
149         */
150        @Override
151        public Set<String> getAnnotations()
152        {
153                return this.getAnnotator().getAnnotator().getAnnotations();
154        }
155
156        /**
157         * {@inheritDoc}
158         * 
159         * @see org.openimaj.ml.annotation.Annotator#annotate(java.lang.Object)
160         */
161        @Override
162        public List<ScoredAnnotation<String>> annotate(final DoubleFV object)
163        {
164                return this.getAnnotator().getAnnotator().annotate(object);
165        }
166
167        /**
168         * Get the annotator type in use.
169         * 
170         * @return The annotator type
171         */
172        public AudioAnnotatorType getAnnotator()
173        {
174                return this.annotator;
175        }
176
177        /**
178         * Set the annotator type to use.
179         * 
180         * @param annotator
181         *            The annotator type.
182         */
183        public void setAnnotator(final AudioAnnotatorType annotator)
184        {
185                this.annotator = annotator;
186        }
187}