Package com.meapsoft

Source Code of com.meapsoft.Segmenter

/*
*  Copyright 2006-2007 Columbia University.
*
*  This file is part of MEAPsoft.
*
*  MEAPsoft is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License version 2 as
*  published by the Free Software Foundation.
*
*  MEAPsoft is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with MEAPsoft; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
*  02110-1301 USA
*
*  See the file "COPYING" for the text of the license.
*/

package com.meapsoft;

import gnu.getopt.Getopt;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
* Program to segment input files and output text feature files compatible with
* other MEAPsoft tools.
*
* @author Ron Weiss (ronw@ee.columbia.edu)
*/

public class Segmenter extends MEAPUtil
{
  // Files to use
  String[] audioFiles;

  String outFileName = "out.segments";

  FeatFile outFile;

  // Extractor parts
  STFT stft;

  boolean useBeatOD = true;

  OnsetDetector detector;

  SegmentExtractor extractor;

  boolean onsetAtFirstFrame = false;

  int frameLatency = 200;

  // sensitivity of DpweOnsetDetector. higher is more sensitive
  // I think this goes from 0.0->3.0 ???
  double threshMult = 1.0;

  // length of smoothing window in seconds.
  double smtime = 0.1;

  double tempoMult = 1;

  public Segmenter(String[] inFiles, String outputFile)
  {
    audioFiles = inFiles;

    outFileName = outputFile;
    outFile = new FeatFile(outFileName);
  }

  public Segmenter(String inFile, String outputFile)
  {
    audioFiles = new String[1];
    audioFiles[0] = inFile;

    outFileName = outputFile;
    outFile = new FeatFile(outFileName);
  }

  public Segmenter(String[] inFiles, String outputFile, double thr,
      boolean beatOD, boolean oaff)
  {
    this(inFiles, outputFile);

    threshMult = thr;
    useBeatOD = beatOD;
    onsetAtFirstFrame = oaff;
  }

  public Segmenter(String[] inFiles, String outputFile, double thr,
      double smt, boolean beatOD, boolean oaff)
  {
    this(inFiles, outputFile);

    threshMult = thr;
    useBeatOD = beatOD;
    onsetAtFirstFrame = oaff;
    smtime = smt;
  }

  public Segmenter(String inFile, String outputFile, double thr,
      boolean beatOD, boolean oaff)
  {
    this(inFile, outputFile);

    threshMult = thr;
    useBeatOD = beatOD;
    onsetAtFirstFrame = oaff;
  }

  public Segmenter(String inFile, String outputFile, double thr, double smt,
      boolean beatOD, boolean oaff)
  {
    this(inFile, outputFile);

    threshMult = thr;
    useBeatOD = beatOD;
    onsetAtFirstFrame = oaff;
    smtime = smt;
  }

  public void printUsageAndExit()
  {
    System.out
        .println("Usage: Segmenter [-options] source1.wav source2.mp3 ... \n\n"
            + "  where options include:\n"
            + "    -o output_file  the file to write the output to (defaults to ./out.segments)\n"
            + "    -t D.D  [1.0]   onset detector threshold (event detector), tempo multiplier (beat detector)\n"
            + "    -s D.D  [0.1]   length of smoothing window in seconds for event detector\n"
            + "    -d              use the old style onset detector (defaults to BeatOnsetDetector)\n"
            + "    -0              add an onset at the very beginning of the file\n"
            + "");
    System.exit(0);
  }

  /**
   * Segmenter constructor. Parses command line arguments
   */
  public Segmenter(String[] args)
  {
    if (args.length == 0)
      printUsageAndExit();

    // Parse arguments
    Getopt opt = new Getopt("Segmenter", args, "t:do:s:0");
    opt.setOpterr(false);

    int c = -1;
    while ((c = opt.getopt()) != -1)
    {
      switch (c)
      {
      case 't':
        threshMult = Double.parseDouble(opt.getOptarg());
        tempoMult = threshMult;
        break;
      case 's':
        smtime = Double.parseDouble(opt.getOptarg());
        break;
      case 'd':
        useBeatOD = false;
        break;
      case 'o':
        outFileName = opt.getOptarg();
        break;
      case '0':
        onsetAtFirstFrame = true;
        break;
      case '?':
        printUsageAndExit();
        break;
      default:
        System.out.print("getopt() returned " + c + "\n");
      }
    }

    // parse arguments
    int ind = opt.getOptind();
    if (ind > args.length)
      printUsageAndExit();

    audioFiles = new String[args.length - ind];
    for (int i = ind; i < args.length; i++)
      audioFiles[i - ind] = args[i];

    outFile = new FeatFile(outFileName);
  }

  public FeatFile processAudioFile() throws IOException,
      UnsupportedAudioFileException
  {
    return processAudioFile(outFile.filename);
  }

  public FeatFile processAudioFile(String fn) throws IOException,
      UnsupportedAudioFileException
  {
    // Create Extractor
    // ais = openInputStream(fn);
    // downsample to 8kHz
    AudioReader audioReader = AudioReaderFactory.getAudioReader(
            fn, new AudioFormat(DpweOnsetDetector.sr, bitsPerSamp, 1, signed,
                                bigEndian));

    // One sample per frame because we converted the file to mono.
    long sampleLength = audioReader.getFrameLength();
    // the mp3/flac decoders don't like to tell us the frame
    // length, so we have to make a guess. You might get an
    // error and progress bars will be off.
    if (sampleLength < 0)
    {
      sampleLength = 50000 * DpweOnsetDetector.swin / 2;

    }
    int numFrames = (int) sampleLength / (DpweOnsetDetector.swin / 2);

    // keep track of our progress in segmenting this file:
    progress.setMinimum(0);
    progress.setMaximum(numFrames);
    progress.setValue(0);

    // use 30ms window
    stft = new STFT(audioReader, DpweOnsetDetector.swin,
        DpweOnsetDetector.swin / 2, frameLatency);

    if (useBeatOD)
    {
      if (verbose)
        System.out.println("Using beat detector. TempoMult: " + tempoMult);
     
      // detector = new BeatOnsetDetector(stft, bandThresh, bandFrac);
      detector = new DpweBeatOnsetDetector(stft, numFrames, tempoMult);
    }
    else
    {
      if (verbose)
        System.out.println("Using event detector. threshMult: " + threshMult + " smtime: " + smtime);
      // detector = new OnsetDetector(stft, bandThresh, bandFrac);
      detector = new DpweOnsetDetector(stft, numFrames, threshMult,
          smtime);
    }
    extractor = new SegmentExtractor(stft, fn, outFile, progress);
    detector.addOnsetListener(extractor);

    // Hook things together
    stft.addFrameListener(extractor);

    // insert an onset at frame 0?
    if (onsetAtFirstFrame)
      extractor.newOnset(0, 0);

    // Extract the entire source file
    extractor.run();

    // outFile now contains some chunks.
    outFile.haveReadFile = true;

    return outFile;
  }

  /**
   * Set everything up, process input, and write output.
   */
  public void run()
  {
    // process supplied files
    for (int i = 0; i < audioFiles.length; i++)
    {

      if (verbose)
        System.out.println("Writing segments from " + audioFiles[i]
            + " to " + outFileName + ".");

      long startTime = System.currentTimeMillis();

      try
      {
        processAudioFile(audioFiles[i]);

        if (writeMEAPFile)
          outFile.writeFile();
      }
      catch (Exception e)
      {
        exceptionHandler.handleException(e);
      }

      if (verbose)
        System.out.println("Done.  Took "
            + ((System.currentTimeMillis() - startTime) / 1000.0)
            + "s");
    }
  }

  // Set the tempo multiplier for the beat onset detector.
  public void setTempoMultiplier(double mult)
  {
    tempoMult = mult;
  }

  public FeatFile getSegFile()
  {
    return outFile;
  }

  public static void main(String[] args)
  {
    Segmenter o2or = new Segmenter(args);
    o2or.verbose = true;
    o2or.run();
    System.exit(0);
  }
}
TOP

Related Classes of com.meapsoft.Segmenter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.