Author: bpoussin Date: 2012-08-29 16:38:16 +0200 (Wed, 29 Aug 2012) New Revision: 490 Url: http://forge.codelutin.com/repositories/revision/sammoa/490 Log: Ajout d'un nouveau recorder qui fonctionne :) Il reste a mettre en configuration quelques variables pour pouvoir l'instancier avec les bonnes valeurs (ce que veut l'utilisateur) Il faut aussi ajouter une meilleur compression Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java Copied: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java (from rev 479, trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/AudioRecorderDefault.java) =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/audio/SammoaAudioRecorder.java 2012-08-29 14:38:16 UTC (rev 490) @@ -0,0 +1,228 @@ +/* + * #%L + * SAMMOA :: Application + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 UMS 3462, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ +package fr.ulr.sammoa.application.device.audio; + +import com.google.common.base.Preconditions; +import fr.ulr.sammoa.application.device.DeviceState; +import fr.ulr.sammoa.application.device.DeviceStateEvent; +import fr.ulr.sammoa.application.device.DeviceStateListener; +import fr.ulr.sammoa.application.device.DeviceTechnicalException; +import java.io.File; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.TargetDataLine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created: 16/05/12 + * + * @author fdesbois <desbois@codelutin.com> + */ +public class SammoaAudioRecorder implements AudioRecorder { + + private static final Logger log = LoggerFactory.getLogger(SammoaAudioRecorder.class); + + protected AudioFormat audioFormat; + + protected AudioFileFormat.Type outputType = AudioFileFormat.Type.WAVE; + + protected DeviceState state; + + protected Set<DeviceStateListener> listeners; + + protected AudioRecorderThread currentRecorder; + + public SammoaAudioRecorder( + float sampleRate, // 8000,11025,16000,22050,44100 + int sampleSizeInBits // 8,16 + ) { + int channels = 1; // 1,2 + boolean signed = true; //true,false + boolean bigEndian = false; //true,false + + audioFormat = new AudioFormat( + sampleRate, + sampleSizeInBits, + channels, + signed, + bigEndian); + } + + @Override + public DeviceState getState() { + DeviceState result; + if (currentRecorder == null) { + result = DeviceState.READY; + } else { + result = DeviceState.RUNNING; + } + return result; + } + + public void setState(DeviceState state, DeviceTechnicalException error) { + DeviceState oldValue = getState(); + this.state = state; + + // Fire on listeners + DeviceStateEvent event = new DeviceStateEvent(this, oldValue, state); + event.setError(error); + for (DeviceStateListener listener : listeners) { + listener.stateChanged(event); + } + } + + @Override + public AudioFileFormat.Type getOutputType() { + return outputType; + } + + @Override + public void addDeviceStateListener(DeviceStateListener listener) { + listeners.add(listener); + } + + @Override + public void removeDeviceStateListener(DeviceStateListener listener) { + listeners.remove(listener); + } + + @Override + public Set<DeviceStateListener> getDeviceStateListeners() { + return listeners; + } + + @Override + public void open() throws DeviceTechnicalException { + // rien a faire + } + + @Override + public void start() { + // rien a faire + } + + @Override + public void record(File outputFile, long delaySeconds) { + Preconditions.checkArgument(outputFile != null); + + try { + // stop last started if necessary + stop(); + // start new recorder thread + currentRecorder = new AudioRecorderThread( + audioFormat, outputType, outputFile, delaySeconds); + currentRecorder.start(); + } catch (Exception eee) { + eee.printStackTrace(); + log.error("Can't record audio", eee); + } + } + + @Override + public void stopRecord(long delaySeconds) { + stop(); + } + + @Override + public void stop() { + if (currentRecorder != null) { + currentRecorder.stopRecord(); + currentRecorder = null; + } + } + + @Override + public void close() throws DeviceTechnicalException { + stop(); + } + + static protected class AudioRecorderThread extends Thread{ + protected TargetDataLine targetDataLine; + protected AudioFileFormat.Type fileType; + protected File filename; + protected long delayToClose; + protected AudioInputStream stream; + + public AudioRecorderThread( + AudioFormat audioFormat, AudioFileFormat.Type fileType, + File filename, long delayToClose) throws LineUnavailableException { + this.fileType = fileType; + this.filename = filename; + this.delayToClose = delayToClose; + + + DataLine.Info dataLineInfo = new DataLine.Info( + TargetDataLine.class, audioFormat); + + targetDataLine = (TargetDataLine) + AudioSystem.getLine(dataLineInfo); + + AudioFormat.Encoding targetEncoding = AudioFormat.Encoding.ULAW; + targetDataLine.open(audioFormat); + targetDataLine.start(); + stream = new AudioInputStream(targetDataLine); + stream = AudioSystem.getAudioInputStream(targetEncoding, stream); + + } + + /** + * Arrete l'enregistrement N seconde apres la demande, N etant + * le parametre delayToClose passer lors de la construction du thread + */ + public void stopRecord() { + System.out.println("Arret demande ..."); + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + targetDataLine.stop(); + targetDataLine.close(); + System.out.println("... arret reel"); + } + }, delayToClose * 1000); + } + + @Override + public void run(){ + try{ + System.out.println("Write audio to: " + filename); + log.debug("Write audio to: " + filename); + AudioSystem.write(stream, fileType, filename); + }catch (Exception eee) { + eee.printStackTrace(); + log.error("Can't record audio", eee); + } + + } + } +}