Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-05-2011
rhino0nt rhino0nt is offline
Miembro
 
Registrado: jun 2008
Posts: 25
Poder: 0
rhino0nt Va por buen camino
Aplicación que se congela

Hola a todos.

Antes que nada les agradezco a todos por la ayuda que siempre me han brindado, no se que haría sin el apoyo de este foro para mis proyectos en Win32.

Ahora tengo un problema que me parece un tanto extraño. Actualmente estoy desarrollando un sistema que básicamente muestra un texto y le da al usuario la opción de reproducir el audio correspondiente al texto que se tiene en pantalla en ese momento. Para estoy utilizo los controles de NewAC con archivos MP3 codificados. Lo que hago básicamente es cargar un archivo mp3 que tengo codificado con el uso de las librerías DCPCrypt, lo cargo en un TFileStream, lo decodifico y lo paso a un TMemoryStream.

Al principio utilizaba un par de controles que se encontraban en la forma para reproducir el audio, con NewAC solo se necesita un decodificador de audio de entrada y un reproductor de salida para tener el audio, cargo el stream al decodificador y arranco el reproductor. Hasta ahí no tengo problemas, sin embargo en la optimización me dí cuenta de que cada vez que reproducía un audio, el uso de la memoria se iba incrementando en un tamaño identico al del archivo de audio que se reproducía, y no podía liberar el stream de memoria porque el componente de audio me marcaba error. Así que decidí crear los controles para reproducción de audio en tiempo de ejecución. Cuando el usuario presiona el botón de Reproducir el sistema verifica si existe un control creado y el estatus de este, si se esta reproduciendo lo pausa, y si no existe lo crea y comienza la reproducción. Hay otro botón que detiene la reproducción y hace un FreeAndNil para los controles de audio y para el TMemoryStream, este es el código de la unidad en cuestión un tanto simplificado:
Código:
unit ufmEntrenamiento;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, StdCtrls, Buttons, ExtCtrls, ACS_Classes, ACS_DXAudio, ACS_WinMedia, ACS_smpeg, ACS_Streams, DCPCAST256, DCPSHA1;

type
    procedure bnRepPreguntaClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure DesencriptaStream(psOrigen : String);
    procedure bnDetPreguntaClick(Sender: TObject);
  private
    { Controles utilizados para la reproducción del Audio }
    var srAudioActual : TMemoryStream;
    var auAudio : TMP3In;
    var daAudio: TDXAudioOut;
  public
    { Public declarations }
  end;

var
  fmEntrenamiento: TfmEntrenamiento;

implementation

uses udmInterfaz;

{$R *.dfm}

{Botón para detener la reproducción del Audio.}
procedure TfmEntrenamiento.bnDetPreguntaClick(Sender: TObject);
begin
  if (daAudio.Status = tosPlaying) or (daAudio.Status = tosPaused) then
  begin
    daAudio.Stop;
    FreeAndNil(daAudio);
    FreeAndNil(auAudio);
    FreeAndNil(srAudioActual);
  end;
  bnDetPregunta.Enabled := False;
  bnRepPregunta.ImageIndex := 3;
end;

{Botón para reproducir y pausar el audio.}
procedure TfmEntrenamiento.bnRepPreguntaClick(Sender: TObject);
begin
  if bnRepPregunta.ImageIndex = 3 then
  begin
    if Assigned(daAudio) then
    begin
      daAudio.Resume;
      bnRepPregunta.ImageIndex := 2;
    end
    else
    begin
      auAudio := TMP3In.Create(Self);
      daAudio := TDXAudioOut.Create(Self);
      bnRepPregunta.ImageIndex := 2;
      bnDetPregunta.Enabled := True;
      DesencriptaStream(ExtractFilePath(Application.ExeName) + 'Audios\Prueba.enc');
      auAudio.Stream := srAudioActual;
      daAudio.PrefetchData := False;
      daAudio.Input := auAudio;
      daAudio.Run;
    end;
  end
  else
  begin
    bnRepPregunta.ImageIndex := 3;
    if daAudio.Status = tosPlaying then
    begin
      daAudio.Pause;
    end;
  end;
end;

procedure TfmEntrenamiento.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if daAudio.Status = tosPlaying then
  begin
    daAudio.Stop;
    FreeAndNil(daAudio);
    FreeAndNil(daSalida);
    FreeAndnil(srAudioActual);
  end;
  Action := CAFree;
end;

{Procedimiento para desencriptar el Audio y enviarlo a un TMemoryStream}
procedure TfmEntrenamiento.DesencriptaStream(psOrigen : string);
var
  kyCifrador : TDCP_EncriptadoX;
  vsLlave  : String;
  srOrigen : TFileStream;
  srDestino : TMemoryStream;
begin
  vsLlave := 'Llave';
  try
    srOrigen := TFileStream.Create(psOrigen, fmOpenRead);
    srDestino := TMemoryStream.Create;
    srAudioActual := TMemoryStream.Create;
    kyCifrador := TDCP_EncriptadoX.Create(Self);
    kyCifrador.InitStr(vsLlave, TDCP_EncriptadoX);
    kyCifrador.DecryptStream(srOrigen, srDestino, srOrigen.Size);
    kyCifrador.Burn;
    srAudioActual.CopyFrom(srDestino, 0);
    FreeAndNil(kyCifrador);
    FreeAndNil(srOrigen);
    FreeAndNil(srDestino);
  except on E: Exception do
    ShowMessage(E.Message);
  end;
end;
end.
Mi problema es que de manera aleatoria al estar reproduciendo y deteniendo la reproducción de un archivo de Audio el sistema simplemente se congela, estoy depurando y simplemente no recibo ningún error, no hay excepciones, el depurador me indica que el sistema sigue corriendo pero la aplicación en ese momento está congelada.

¿Estoy haciendo algo mal con los objetos que creo y libero? o ¿Existe alguna manera mejor de hacerlo? y ¿Cómo puedo saber que es lo que está congelando la aplicación?

De antemano Gracias y una discúlpa por un post tan largo.
Responder Con Cita
  #2  
Antiguo 18-05-2011
rhino0nt rhino0nt is offline
Miembro
 
Registrado: jun 2008
Posts: 25
Poder: 0
rhino0nt Va por buen camino
RE: Aplicación que se congela

Pues me respondo a mi mismo por si alguien mas se llega a encontrar con este problema.

Es un error en los componentes NewAC, al parecer se ciclan al consultar el estatus de un Thread. Lo único que se necesita hacer es en lugar de utilizar el procedimiento Stop del componente TDXAudioOut, utilizarlo como Stop(False) para que detenga la reproducción.

Y asunto arreglado.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Error INET/inet_error: read errno = 10054 congela aplicacion procom2010 Firebird e Interbase 6 10-03-2011 14:20:14
SQL Server + Delphi se congela al ejecutar un Procedimeinto Almacenado subzero Varios 3 29-09-2010 01:57:15
Aplicación de Servicio+Aplicación Normal +Socket jake API de Windows 5 21-06-2007 18:53:19
Cómo cerrar otra aplicacion desde mi aplicacion en Delphi 7 Gaby123 API de Windows 5 04-01-2007 22:44:51
Se congela Aplicación JamesBond_Mx Conexión con bases de datos 0 03-06-2004 15:34:48


La franja horaria es GMT +2. Ahora son las 01:03:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi