001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io.audio; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.GraphicsEnvironment; 007import java.io.File; 008import java.io.IOException; 009import java.net.URL; 010 011import javax.sound.sampled.AudioFormat; 012import javax.sound.sampled.AudioInputStream; 013import javax.sound.sampled.AudioSystem; 014import javax.sound.sampled.UnsupportedAudioFileException; 015import javax.swing.JOptionPane; 016 017import org.openstreetmap.josm.gui.MainApplication; 018import org.openstreetmap.josm.spi.preferences.Config; 019import org.openstreetmap.josm.tools.Logging; 020 021/** 022 * Utils functions for audio. 023 * 024 * @author David Earl <david@frankieandshadow.com> 025 * @since 12326 (move to new package) 026 * @since 1462 027 */ 028public final class AudioUtil { 029 030 private AudioUtil() { 031 // Hide default constructor for utils classes 032 } 033 034 /** 035 * Returns calibrated length of recording in seconds. 036 * @param wavFile the recording file (WAV format) 037 * @return the calibrated length of recording in seconds. 038 */ 039 public static double getCalibratedDuration(File wavFile) { 040 try (AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( 041 new URL("file:".concat(wavFile.getAbsolutePath())))) { 042 AudioFormat audioFormat = audioInputStream.getFormat(); 043 long filesize = wavFile.length(); 044 double bytesPerSecond = audioFormat.getFrameRate() /* frames per second */ 045 * audioFormat.getFrameSize() /* bytes per frame */; 046 double naturalLength = filesize / bytesPerSecond; 047 double calibration = Config.getPref().getDouble("audio.calibration", 1.0 /* default, ratio */); 048 return naturalLength / calibration; 049 } catch (UnsupportedAudioFileException | IOException e) { 050 Logging.debug(e); 051 return 0.0; 052 } 053 } 054 055 /** 056 * Shows a popup audio error message for the given exception. 057 * @param ex The exception used as error reason. Cannot be {@code null}. 058 * @since 12328 059 */ 060 public static void audioMalfunction(Exception ex) { 061 String msg = ex.getMessage(); 062 if (msg == null) 063 msg = tr("unspecified reason"); 064 else 065 msg = tr(msg); 066 Logging.error(msg); 067 if (!GraphicsEnvironment.isHeadless()) { 068 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 069 "<html><p>" + msg + "</p></html>", 070 tr("Error playing sound"), JOptionPane.ERROR_MESSAGE); 071 } 072 } 073}