package utils;

import java.io.File;

import org.apache.log4j.Logger;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;

import com.musicg.dsp.Resampler;
import com.musicg.wave.Wave;

import utils.audio.AudioMethods;

public class AudioUtils {
		
	private static final Logger logger = Logger.getLogger(AudioUtils.class);
	
	private final AudioMethods audioMethods;
	private final Resampler resampler;
	
	public AudioUtils() {
		this.audioMethods = new AudioMethods();
		this.resampler = new Resampler();
	}
	
	/**
	 * Retrieves the duration of an MP3 file in seconds.
	 * 
	 * @param mp3File File pointing at the MP3 file.
	 * 
	 * @return double containing the duration or -1 in case the duration could not be retrieved.
	 */
	public final double getMp3DurationInSeconds(File mp3File) {

		double errorCode = -1;
		
		if (mp3File == null) {
			logger.error("getMp3DurationInSeconds: Null MP3 file.");
			return errorCode;
		}
		
		if (!mp3File.exists() || !mp3File.isFile()) {
			logger.error("getMp3DurationInSeconds: Invalid MP3 file: "+mp3File.getAbsolutePath());
			return errorCode;
		}
		
		try {
			AudioFile audioFile = AudioFileIO.read(mp3File);
			
			double duration = ((double)mp3File.length()) / (audioFile.getAudioHeader().getBitRateAsNumber() / 8);
			
			return duration / 1000;
		} 
		catch (Exception e) {
			logger.error("getMp3DurationInSeconds: Could not retrieve duration from "+mp3File.getAbsolutePath(), e);
			return errorCode;
		}		
	}
	
	public final byte[] toWave(File file) throws Exception {

		String wavFile = audioMethods.encodeWAVNRenameKeepOriginal(file.getAbsolutePath(), true);

		if (wavFile == null || !new File(wavFile).exists()) {
			System.out.println("Could not process: "+wavFile);
			return null;
		}

		Wave wave = new Wave(wavFile);

		int sourceRate = wave.getWaveHeader().getSampleRate();		

		byte[] wavstream = resampler.reSample(wave.getBytes(), wave.getWaveHeader().getBitsPerSample(), sourceRate, 8000);

		new File(wavFile).delete();

		return wavstream;
	}
}
