Foros del Web » Programación para mayores de 30 ;) » Java »

En la busqueda de la clase perfecta para audio en java

Estas en el tema de En la busqueda de la clase perfecta para audio en java en el foro de Java en Foros del Web. hola a todos, siguo buscando la clase ideal, es decir una que me permita reproducir sonido de forma instantanea en una aplicacion de escritorio java: ...
  #1 (permalink)  
Antiguo 25/11/2011, 15:04
Avatar de calichecal  
Fecha de Ingreso: junio-2009
Ubicación: Colombia
Mensajes: 288
Antigüedad: 14 años, 10 meses
Puntos: 12
En la busqueda de la clase perfecta para audio en java

hola a todos, siguo buscando la clase ideal, es decir una que me permita reproducir sonido de forma instantanea en una aplicacion de escritorio java:

despues de mucho bregar, encontré una librería(BasicPlayer) que me facilita mucho las cosas pero ahora el problema es la demora en la reproducción:


codigo java:

Código PHP:

import Gui
.MarcoPrincipal;
import java.io.File;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerException;



public class 
ReproduceSonido {
    
   
     
     private 
boolean sonido;
   
     
     private 
String directorio;
     private 
BasicPlayer player;
     private 
File[] vAudios;
     
  public 
ReproduceSonido(){
    
     
sonido=true;
   
     
vAudios=new File[7];
     
     
     
               
String carpetaAudio;
                        if(
MarcoPrincipal.getSo().equals("Linux")){
                        
carpetaAudio="/Audio/";
                        }else{
                        
carpetaAudio=String.valueOf((char)(92))+"Audio"+String.valueOf((char)(92)); 
                        }

     
directorio=MarcoPrincipal.getDirectorioAplicacion()+carpetaAudio;

     
vAudios[0]=new File(this.directorio+"Acierto.wav");
     
vAudios[1]=new File(this.directorio+"Error.wav");
     
vAudios[2]=new File(this.directorio+"Introduccion.wav");
     
vAudios[3]=new File(this.directorio+"PulsaBoton.wav");
     
vAudios[4]=new File(this.directorio+"Contestarprimero.wav");
     
vAudios[5]=new File(this.directorio+"Inicioprueba.wav");
     
vAudios[6]=new File(this.directorio+"Pocotiempo.wav");
  }
  
  

    public 
boolean isSonido() {
        return 
sonido;
    }

    public 
void setSonido(boolean sonido) {
        
this.sonido sonido;
    }
  
  
  
  public 
void start(int indice){
      
    


 if (
sonido) {

            
player = new BasicPlayer();
            try {
                
player.open(this.vAudios[indice]);
                
player.play();
            } catch (
BasicPlayerException ex) { }
            
       
      }
    
  }



En el programa que utiliza esta clase, solo crea una instancia de esta clase, y entonces esta se encarga de cargar en un vector de objetos “File” los 7 audios que utilizo. La clase BasicPlayer crea un hilo para cada audio cade vez que llamo a start(int indice).


El problema es que se demora un segundo en reproducir y teniendo en cuenta que uno de los audios es para cada vez que se haga clip en un JButton necesito que el audio sea casi instantáneo.

Pensé que la demora de un segundo se presentaba por tener que cargar los archivos en objetos “File”, por eso inicializo todo eso en el constructor, pero no es así, todavía se presenta esta demora...

agradezco sus recomendaciones y aportes...

PD: En otros intentos de crear una clase Audio, utilizando la clase Clip ,siempre tuve el inconveniente de que no reproduce todas las veces.
__________________
Hay una fuerza motriz más poderosa que el vapor, la electricidad y la energía atómica: la voluntad. -Einstein-

Última edición por calichecal; 25/11/2011 a las 15:14
  #2 (permalink)  
Antiguo 26/11/2011, 00:49
Avatar de calichecal  
Fecha de Ingreso: junio-2009
Ubicación: Colombia
Mensajes: 288
Antigüedad: 14 años, 10 meses
Puntos: 12
Respuesta: En la busqueda de la clase perfecta para audio en java

hola ,hice otro intento con el objeto Clip, pero a veces no reproduce a pesar de que cada sonido esta en un hilo diferente:


(mantengo la referencia a los hilos(los guardo en una lista), para poder "matar" a los activos en cualquier momento)

código java
Código PHP:

import Gui
.MarcoPrincipal;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;






  





public class 
ReproduceSonido {
    
   
     
     private 
boolean sonido;
     private 
String directorio;
     private 
File[] vAudios;
     private 
LinkedList<hiloSonidolAudios;
     

     
     
     
  public 
ReproduceSonido(){
    
     
sonido=true;
     
vAudios=new File[7];
     
lAudios=new LinkedList<hiloSonido>();
     
     
       
String carpeta;
                        if(
MarcoPrincipal.getSo().equals("Linux")){
                        
carpeta="/Audio/";
                        }else{
                        
carpeta=String.valueOf((char)(92))+"Audio"+String.valueOf((char)(92)); 
                        }
                        
                        
     
directorio=MarcoPrincipal.getDirectorioAplicacion()+carpeta;
     
vAudios[0]=new File(this.directorio+"Acierto.au");
     
vAudios[1]=new File(this.directorio+"Error.au");
     
vAudios[2]=new File(this.directorio+"Introduccion.au");
     
vAudios[3]=new File(this.directorio+"PulsaBoton.au");
     
vAudios[4]=new File(this.directorio+"Contestarprimero.au");
     
vAudios[5]=new File(this.directorio+"Inicioprueba.au");
     
vAudios[6]=new File(this.directorio+"Pocotiempo.au");
     
    
  }

  
  
  

    public 
boolean isSonido() {
        return 
sonido;
    }

    public 
void setSonido(boolean sonido) {
        
this.sonido sonido;
    }
  
// clase anidada para los hilos

       
class hiloSonido extends Thread{
        
           
            private 
Clip sonido;
            private 
boolean seguir;
                 
         
hiloSonido(File archivo){
         
            
seguir=true;
            try {
                
sonido AudioSystem.getClip();
                
sonido.open(AudioSystem.getAudioInputStream(archivo));
                
            } catch (
UnsupportedAudioFileException ex) {
                
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            } catch (
IOException ex) {
               
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            } catch (
LineUnavailableException ex) {
               
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            }
         }
         
        @
Override
         
public void run(){
              
            
sonido.start();
            
            
// Espera mientras se esté reproduciendo.
            
while (seguir && sonido.isRunning())
                try {
                
Thread.sleep(200);
            } catch (
InterruptedException ex) {
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            }
            
            
// por si el ciclo termina por seguir:false
            
if(sonido.isRunning()){
                
sonido.stop();
            }
            
            
// Se cierra el clip.
            
sonido.close();
          
         
         }
        
        public 
void parar(){
            
seguir=false;
        }
         
     }
  
// fin clase anidada para los hilos


// se llama a start cuando se quiere reproducir un audio y solo se le pasa el indice predeterminado para este (no es muy POO que digamos :P)
  
public void start(int indice){
      
        
//remuevo hilos muertos de lista
        
if(!lAudios.isEmpty()){
        
           
LinkedList<hiloSonidoelementsToDelete = new LinkedList<hiloSonido>();
            for (
hiloSonido singleObjectlAudios){
                if(!
singleObject.isAlive()){
                
elementsToDelete.add(singleObject);
                }

            }
        
lAudios.removeAll(elementsToDelete); 
            
        }
      
      
       if (
sonido) {
           
            
hiloSonido hs = new hiloSonido(this.vAudios[indice]);
            
hs.start();
            
lAudios.add(hs);
      }
    
}
  
  public 
void stop(){
 
      
// paro todas las reproducciones y limpio la lista
        
if(!lAudios.isEmpty()){
        
         
            for (
hiloSonido singleObjectlAudios){
                if(
singleObject.isAlive()){
                  
singleObject.parar();
                }

            }
            
lAudios.clear();
            
        }
        
  }
    
  



agradezco cualquier ayuda o idea del porque no reproduce a veces. Es que he hecho como 10 clases y ninguna me sirve.

PD:En el software: el sonido: "PulsaBoton", suena cada vez que algun JButton se oprima, pero cuando estos se oprimen muy seguido es cuando comienzan a fallar las reproducciones.

¿será que me toca meterme con JMF?
__________________
Hay una fuerza motriz más poderosa que el vapor, la electricidad y la energía atómica: la voluntad. -Einstein-

Última edición por calichecal; 26/11/2011 a las 01:06
  #3 (permalink)  
Antiguo 26/11/2011, 14:10
Avatar de calichecal  
Fecha de Ingreso: junio-2009
Ubicación: Colombia
Mensajes: 288
Antigüedad: 14 años, 10 meses
Puntos: 12
Respuesta: En la busqueda de la clase perfecta para audio en java

hola a todos, al fin solucione este problema del sonido y es algo que me sorprende que no sea halla tenido en cuenta en tutoriales y que tiene que ver con el lenguaje Java, no con el pc. A que me refiero:

la típica rutina para reproducir un audio:

Código:
 try {
            
          
            Clip sonido = AudioSystem.getClip();
            
          
            sonido.open(AudioSystem.getAudioInputStream(new File("sonido.wav")));
            
            
            sonido.start();
            
            // Espera mientras se esté reproduciendo.
            while (sonido.isRunning())
                Thread.sleep(1000);
            
           
            sonido.close();
        } catch (Exception e) {
          
        }
El problema que encontre, es que a veces el tipico método isRunning devuelve false, aun cuando del sonido ya se halla iniciado con start, y lo mismo ocurre con isActive, entonces acá es mejor tener un do while.


Código:
  
do{
 Thread.sleep(1000);
 }while (sonido.isRunning());
o con isActive().

y de seguro que nunca fallará.

y todo esto porque: ni idea no puedo ver el codigo del método "start" de la clase "Clip", pero supongo que tiene que ver con la creación de un hilo que se encarga de tomar el contenido del audio por partes, y hacer un poconon de procesos. Pero lo que si es cierto es que el do-while, da tiempo a que el metodo start haga todo su trabajo, incluido el necesario para que isRunning devuelva lo que tiene que ser.


chao.

me respondi solo pero bueno los foros son para eso: ayudar y compartir.


para el que la necesite:

la clase ideal para reproducir en java es:

código java:
Código PHP:


  
public class hiloSonido extends Thread{
        
           
            private 
Clip sonido;
            private 
boolean seguir;
            
        

         public 
hiloSonido(String rutaArchivo){
           
            
seguir=true;
            try {
                
sonido AudioSystem.getClip();
                
sonido.open(AudioSystem.getAudioInputStream(new File(rutaArchivo)));
                
            } catch (
UnsupportedAudioFileException ex) {
              
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            } catch (
IOException ex) {
               
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            } catch (
LineUnavailableException ex) {
               
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            }
         }
         
        @
Override
         
public void run(){
              
            
sonido.start();
              
            
// Espera mientras se esté reproduciendo.
            
do{
                try {
                
Thread.sleep(500);
            } catch (
InterruptedException ex) {
                
Logger.getLogger(ReproduceSonido.class.getName()).log(Level.SEVEREnullex);
            }
                
            }while (
seguir && sonido.isActive());
            
            if(
sonido.isActive()){
                
sonido.stop();
            }
            
            
// Se cierra el clip.
            
sonido.close();
          
         
         }
        
        public 
void parar(){
            
seguir=false;
        }
         
     } 
__________________
Hay una fuerza motriz más poderosa que el vapor, la electricidad y la energía atómica: la voluntad. -Einstein-

Última edición por calichecal; 26/11/2011 a las 14:24

Etiquetas: audio, basicplayer, clase, sonido, string, aplicaciones
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:46.