home *** CD-ROM | disk | FTP | other *** search
- /**************************************************/
- /* */
- /* Common.cpp */
- /* */
- /* Fonctions communes aux modules */
- /* */
- /**************************************************/
-
- /*
- ** $Revision: 1.3 $
- ** $State: Exp $
- ** $Date: 1998/08/16 19:03:33 $
- **
- ** $Log: Common.cpp $
- ** Revision 1.3 1998/08/16 19:03:33 kakace
- ** Version Beta3+
- **
- ** Revision 1.2 1998/08/02 15:16:59 kakace
- ** Fonctionnement OK (Layer 1/2 + Stereo/JStereo)
- **
- ** Revision 1.1 1998/07/24 14:26:50 kakace
- ** Automatic global CheckIn
- **
- ** Revision 1.26 1998/07/24 14:14:22 kakace
- ** Version intermédiaire (CheckIn global)
- **
- ** Revision 1.24 1998/07/02 15:51:55 kakace
- ** Automatic global CheckIn
- **
- */
-
- //----------------------------------------------------------------------------------------------------
-
- /// Includes
-
- #ifndef _INCLUDE_STDLIB_H
- #include <stdlib.h>
- #endif
-
- #ifndef _INCLUDE_IOSTREAM_H
- #include <iostream.h>
- #endif
-
- #ifndef _INCLUDE_IOMANIP_H
- #include <iomanip.h>
- #endif
-
- #ifndef DOS_DOS_H
- #include <dos/dos.h>
- #endif
-
- #ifndef _PEGASECOND_HPP
- #include "PegaseCond.hpp"
- #endif
-
- #ifndef _PEGASE_HPP
- #include "Pegase.hpp"
- #endif
-
- #ifndef _FILEINFOS_CLASS_HPP
- #include "FileInfosC.hpp"
- #endif
-
- #ifndef _INPUTSTREAM_CLASS_HPP
- #include "InputStreamC.hpp"
- #endif
-
- #ifndef _MEMORY_HPP
- #include "memory.hpp"
- #endif
-
- #ifndef _COMMON_HPP
- #include "Common.hpp"
- #endif
-
- #ifndef _ENCODERCONFIG_CLASS_HPP
- #include "EncoderConfigC.hpp"
- #endif
-
- #ifndef _CODER_CLASS_HPP
- #include "CoderC.hpp"
- #endif
-
- #ifndef CLASS_DISPLAY_HPP
- #include "Display.hpp"
- #endif
-
- ///
-
-
- #define CDDA_MULTIPLE 2352 // Longueur des blocs des fichiers CDDA
-
- #define CATCOMP_NUMBERS
- #ifndef PEGASE_H
- #include "Pegase.h"
- #endif
-
-
- //----------------------------------------------------------------------------------------------------
- //======================================== Prototypes privés =========================================
- //----------------------------------------------------------------------------------------------------
-
- e_AudioTypes IdentifyInputFile(FileInfosC &roFileInfo);
- e_IoErrors InitFileInfos(FileInfosC &roFileInfo);
- e_FileListErrors IdentifyFile(AnchorPath *pAnchor, char *cPath, PegaseConfigC &roCfg);
-
- void InitTimer();
- LONG GetElapsedTime();
-
-
- //----------------------------------------------------------------------------------------------------
- //============================================ Fonctions =============================================
- //----------------------------------------------------------------------------------------------------
-
- /// ReadFileList()
- //----------------------------------------------------------------------------------------------------
- //========================================== ReadFileList() ==========================================
- //----------------------------------------------------------------------------------------------------
- /****** Common/ReadFileList *************************************************
- *
- * NAME
- * ReadFileList -- Initialiser la liste chaînée des fichier à traiter.
- *
- * SYNOPSIS
- * error = ReadFileList(cFrom)
- *
- * bool ReadFileList(const char *);
- *
- * FUNCTION
- * Examine la source passée en argument, puis analyse les fichiers qu'elle
- * contient. Lorsqu'un fichier audio est détecté, il est ajouté à la liste
- * globale (sa position étant déterminée par son type).
- * Les fichiers non-audio, ou dont le format n'est pas supporté sont
- * ignorés.
- *
- * La source peut être un nom du fichier, un nom de répertoire ou un motif
- * de recherche. Lorsqu'il s'agit d'un répertoire, tous les fichiers de ce
- * répertoire sont analysés, mais tous les sous-répertoires sont ignorés.
- *
- * INPUTS
- * cFrom - Nom du répertoire à examiner, nom du fichier à charger, ou
- * motif de recherche. S'il s'agit d'un nom de répertoire, tous
- * les fichiers contenus dans ce répertoire sont analysés, et
- * les éventuels sous-répertoires sont ignorés.
- * Un pointeur nul ou une chaîne nulle sont acceptés, la fonction
- * retournant alors "NO_NAME_GIVEN".
- *
- * RESULT
- * error - Code de l'erreur rencontrée.
- * La présence d'une erreur ne signifie pas qu'aucun fichier n'a été
- * ajouté à la liste globale.
- *
- * NOTES
- * Cette fonction utilise les fonctions DOS MatchFirst()/MatchNext() et
- * MatchEnd().
- * Le tampon alloué dynamiquement pour recevoir la copie du nom complet du
- * répertoire parent peut voir sa taille augmenter lorsque c'est nécessaire
- * (gestion dynamique).
- *
- * Si la fonction vient à manquer de mémoire, l'examen des sources est
- * immédiatement stoppée. Par contre, une erreur I/O sur l'un des fichiers
- * n'interdit pas l'examen des autres fichiers audio.
- *
- * BUGS
- * Voir les Autodocs concernant MatchFirst().
- * La fonction ignore les SoftLinks.
- *
- * SEE ALSO
- * class FileInfosC, class PegaseConfigC
- *
- *****************************************************************************
- *
- */
-
- #define INITIAL_PATH_BUFF_SIZE 256 // Taille originale par défaut du tampon dynamique
- // utilisé pour la recopie du nom du répertoire.
- #define INCREASE_BUFF_SIZE_VALUE 64 // Incrément pour l'augmentation de la taille du
- // tampon dynamique.
-
- e_FileListErrors ReadFileList(PegaseConfigC &roGlobalCfg, ULONG iIndex)
- {
- CMatch match;
- LONG iMatch;
- e_FileListErrors iError = NO_ERROR; // Code d'erreur à retourner.
- int EnableDoDir = TRUE; // Drapeau permettant d'entrer dans un répertoire.
- AnchorPath *pAnchor;
-
- // Le nom du répertoire parent retourné est le nom complet du chemin d'accès (après
- // résolution éventuelle de toute assignation).
- // La taille du tampon utilisé pour la recopie de ce nom de répertoire est dynamique.
- // Autrement dit, la fonction est capable d'allouer un tampon plus grand que celui
- // disponible lorsque c'est nécessaire.
-
- ULONG iPathBuffSize = INITIAL_PATH_BUFF_SIZE;
- CString cPath;
-
- // Avorter si le nom du fichier/répertoire/motif est incorrect ou s'il n'y a plus assez
- // de mémoire pour allouer le tampon dynamique.
-
- STRING cFrom = roGlobalCfg[iIndex]; // Rechercher la source (fichier ou répertoire).
-
- if (cFrom == NULL || *cFrom == 0) return (NO_NAME_GIVEN);
-
- // pAnchor->ap_BreakBits = 0;
- // pAnchor->ap_Flags = 0;
- // pAnchor->ap_Strlen = 0;
-
- // Rechercher les fichiers audios (source inspiré de l'Amiga Guru Book p.456)
- // Si l'utilisateur a choisi un nom de répertoire, entrer dans ce répertoire.
- // Passée la première entrée, les répertoires sont ignorés.
-
- for (iMatch = match.First(cFrom); iMatch == 0; iMatch = match.Next() )
- {
- pAnchor = match;
-
- // Si la source passée en argument correspond à un répertoire, y entrer. Dans les autres
- // cas, les répertoires sont ignorés.
-
- if (pAnchor->ap_Info.fib_DirEntryType >= 0
- && pAnchor->ap_Info.fib_DirEntryType != ST_SOFTLINK
- && EnableDoDir != FALSE)
- {
- pAnchor->ap_Flags |= APF_DODIR; // Entrer dans le répertoire.
- }
- else
- {
- pAnchor->ap_Flags &= ~APF_DIDDIR;
-
- // Examiner le fichier trouvé, à condition que ce ne soit pas un SoftLink.
-
- if (pAnchor->ap_Info.fib_DirEntryType < 0) // Ignore les SoftLinks
- {
- int success;
-
- // Obtenir le nom complet du répertoire parent.
-
- if ( (success = DOSLib::NameFromLock(pAnchor->ap_Current->an_Lock, cPath)) )
- {
- IdentifyFile(pAnchor, cPath, roGlobalCfg);
- }
- }
- }
- EnableDoDir = FALSE; // Interdire d'entrer dans les prochains répertoire.
- if (iError == NO_MEMORY) break; // Avorter immédiatement si la mémoire manque.
- }
-
- // Libérer les ressources locales.
-
- if (iMatch != ERROR_NO_MORE_ENTRIES && iError == NO_ERROR)
- iError = MATCHING_ERROR; // Cette erreur n'est pas prioritaire.
-
- return iError;
- }
- ///
- /// IdentifyFile()
- //----------------------------------------------------------------------------------------------------
- //========================================== IdentifyFile() ==========================================
- //----------------------------------------------------------------------------------------------------
- /****** Common/IdentifyFile *************************************************
- *
- * NAME
- * IdentifyFile -- Identifie un fichier.
- *
- * SYNOPSIS
- * Erreur = IdentifyFile(pAnchor, cPath)
- *
- * e_FileListErrors IdentifyFile(AnchorPath *, char *);
- *
- * FUNCTION
- * Identifie le fichier actuellement pointé par la structure AnchorPath.
- * La fonction initialise et chaîne un objet FileInfos décrivant ce fichier
- * s'il s'agit d'un fichier audio. Dans le cas contraire, le fichier est
- * simplement ignoré.
- *
- * Si Pegase a été lancé depuis le Shell, la fonction rend compte de l'
- * analyse du fichier.
- *
- * 14.8.99 :
- * Si le fichier d'entrée arrive par un PIPE, le format est automatiquement
- * choisi comme étant CDDA. Le format des échantillons peut être forcé en
- * utilisant les drapeaux INTEL ou MOTOROLA sur la ligne de commande (le
- * format MOTOROLA étant le format par défaut).
- *
- * INPUTS
- * pAnchor - Structure AnchorPath.
- * cPath - Chemin d'accès au fichier.
- *
- * RESULT
- * Erreur - Code d'erreur (NO_ERROR ou NO_MEMORY)
- *
- *****************************************************************************
- *
- */
-
-
- e_FileListErrors IdentifyFile(AnchorPath *pAnchor, char *cPath, PegaseConfigC &roCfg)
- {
- e_FileListErrors iError = NO_ERROR;
- e_AudioTypes iAudioType = AFT_UNKNOWN;
- e_IoErrors iIOErr = IOERR_NONE;
- FileInfosC *poNode;
-
- if ( (poNode = new FileInfosC(pAnchor->ap_Info.fib_FileName, cPath, roCfg)) )
- {
- poNode->SetFileLength(pAnchor->ap_Info.fib_Size);
-
- display->out() << GetString(MSG_ANALYSING_TXT) << " \"" << pAnchor->ap_Info.fib_FileName << "\" : ";
-
- if (roCfg.GetCDDAFmt() == 0)
- {
- // Examiner le fichier rencontré.
-
- iAudioType = IdentifyInputFile(*poNode);
- iIOErr = poNode->GetIoError();
-
- // Si le fichier a été identifié comme un fichier audio, et s'il n'y a pas eu
- // d'erreurs, initialiser les informations le concernant.
-
- if (iAudioType < AFT_NOT_AUDIO && iIOErr == IOERR_NONE)
- {
- iIOErr = InitFileInfos(*poNode);
- iAudioType = poNode->GetFileType();
- }
- }
- else // MOTOROLA/INTEL ==> CDDA.
- {
- if (roCfg.GetCDDAFmt() == 2)
- {
- iAudioType = AFT_CDDA_INTEL;
- }
- else
- {
- iAudioType = AFT_CDDA;
- roCfg.SetCDDAFmt(1); // Format MOTOROLA par défaut.
- }
-
- poNode->SetFileType(iAudioType);
- iIOErr = InitFileInfos(*poNode);
- }
-
- // Traiter les erreurs, ou chaîner le fichier à la liste globale s'il n'y en a pas eu.
-
- if (iIOErr != IOERR_NONE && iIOErr != IOERR_WARN || iAudioType >= AFT_NOT_AUDIO)
- {
- if (iIOErr == IOERR_INTERNAL && iAudioType < AFT_NOT_AUDIO)
- {
- display->out() << GetString(MSG_UNSUPPORTED_FREQUENCY_ERROR);
- }
- else
- {
- STRING s;
-
- switch(iAudioType)
- {
- case AFT_NOT_AUDIO:
- s = GetString(MSG_NOT_AN_AUDIO_FILE_ERROR);
- break;
-
- case AFT_BAD_AIFF:
- s = GetString(MSG_BAD_AIFF_ERROR);
- break;
-
- case AFT_BAD_MAUD:
- s = GetString(MSG_BAD_MAUD_ERROR);
- break;
-
- case AFT_BAD_WAV:
- s = GetString(MSG_BAD_WAVE_ERROR);
- break;
-
- default:
- s = GetString(MSG_READ_ERROR);
- break;
- }
- display->out() << s << endl;
- }
-
- if (iIOErr == IOERR_NO_MEMORY) iError = NO_MEMORY;
-
- delete poNode; // Détruire l'objet associé au fichier courant en cas d'erreur.
- }
- else
- {
- roCfg.Enqueue(poNode);
- display->out() << poNode->GetAudioName() << endl;
-
- if (iIOErr == IOERR_WARN && poNode->GetError2() == ERROR_BAD_HUNK)
- display->out() << GetString(MSG_WARN_BADIFF_SIZE) << endl;
-
- poNode->SetIoError(IOERR_NONE);
- }
- }
- else iError = NO_MEMORY;
-
- return iError;
- }
- ///
- /// RequestFileList()
- //----------------------------------------------------------------------------------------------------
- //======================================== RequestFileList() =========================================
- //----------------------------------------------------------------------------------------------------
- /****** Common/RequestFileList **********************************************
- *
- * NAME
- * RequestFileList -- Obtenir une liste de fichiers.
- *
- * SYNOPSIS
- * RequestFileList(cDefPath)
- *
- * void RequestFileList(STRING);
- *
- * FUNCTION
- * Ouvre un requester de fichier permettant à l'utilisateur de choisir les
- * fichiers à encoder.
- * La fonction crée un tableau de pointeurs, chacun d'eux adressant un
- * chemin d'accès correspondant à un fichier. Cela permet d'émuler le
- * tableau retourné par ReadArgs() lors de l'examen de la ligne de commande.
- *
- * INPUTS
- * cDefPath - Chemin d'accès par défaut ou NULL.
- *
- * NOTES
- * · La position du requester, de même que ses dimensions, ne sont pas
- * modifiables (codées dans le programme lui-même). Voir le tableau
- * s_Tags[].
- *
- * · Cette fonction pourrait éventuellement tirer parti des nouveautés des
- * versions 38+ de l'asl.library
- *
- *****************************************************************************
- *
- */
-
- extern CPegaseArgs goPegaseArgs;
-
- void RequestFileList()
- {
- // Tags initiaux pour l'ouverture du requester.
-
- static struct TagItem s_Tags[] =
- {
- {ASLFR_Flags1, FRF_DOMULTISELECT|FRF_DOPATTERNS},
- {ASLFR_Flags2, FRF_REJECTICONS},
- {TAG_DONE, NULL}
- };
-
- CFileRequest Req;
- FileRequester *fileReq;
-
- if (Req.Init(s_Tags))
- {
- if ( (fileReq = Req.Request(ASLFR_TitleText, GetString(MSG_FILEREQUEST_TITLE),
- ASLFR_InitialPattern, GlobalConfig.GetPattern(),
- ASLFR_InitialLeftEdge, *goPegaseArgs.pa_FR_XPos,
- ASLFR_InitialTopEdge, *goPegaseArgs.pa_FR_YPos,
- ASLFR_InitialWidth, *goPegaseArgs.pa_FR_Width,
- ASLFR_InitialHeight, *goPegaseArgs.pa_FR_Height,
- (goPegaseArgs.pa_DefSource ? ASLFR_InitialDrawer : TAG_DONE), goPegaseArgs.pa_DefSource,
- TAG_DONE)) )
- {
- char **file;
- ULONG path_length = 0;
- ULONG num_entries = fileReq->fr_NumArgs;
- char *path = fileReq->fr_Drawer;
- CString buff;
-
- if (path == NULL || *path == 0) path = NULL; // Ignorer un nom de répertoire nul.
-
- // Prendre en compte la sélection multiple le cas échéant.
-
- if (num_entries)
- {
- file = (char **) &fileReq->fr_ArgList->wa_Name;
- }
- else
- {
- num_entries = 1;
- file = (char **) &fileReq->fr_File;
- }
-
- // Allouer le tableau de pointeurs, puis copier les chaînes obtenues.
-
- for (int entry_index = 0; entry_index < num_entries; ++entry_index, file += 2)
- {
- buff = path;
- DOSLib::AddPart(buff, *file);
- GlobalConfig.Add(buff);
- }
- }
- }
- }
- ///
-
- //----------------------------------------------------------------------------------------------------
-
- /// IdentifyInputFile()
- /****** Common.cpp/IdentifyInputFile ****************************************
- *
- * NAME
- * IdentifyInputFile -- Identifier un fichier audio.
- *
- * SYNOPSIS
- * type = IdentifyInputFile(roFileInfo)
- *
- * e_AudioTypes IdentifyInputFile(FileInfosC);
- *
- * FUNCTION
- * Cette fonction se charge d'identifier le fichier dont le nom est passé
- * en paramètre. Cette reconnaîssance se fonde sur le contenu des tous
- * premiers octets du fichier, ou sur l'extension du nom de fichier lorsqu'
- * une reconnaîssance plus fine n'est pas possible.
- *
- * Actuellement, les fichiers suivants sont traîtés :
- * IFF_AIFF : Fichier IFF
- * IFF_MAUD : Fichier IFF
- * RIFF : Fichier WAVE
- * #?.raw : Données audio brutes
- * #?.pcm : Données audio brutes
- * #?.cdda : Fichier CDDA
- * 0xE310 : Fichier icône (rejeté)
- * 0x03F3 : Fichier exécutable (rejeté)
- * 'GIF8' : Fichier GIF (rejeté)
- * 0xFFD8.. : Fichier JPEG (rejeté)
- *
- * Les fichiers dont le format n'est pas reconnu immédiatement, ou les
- * fichiers RAW sont promus au type CDDA si leur taille est un multiple
- * entier de 2352.
- *
- * INPUTS
- * roFileInfo - Objet FileInfos décrivant le fichier.
- *
- * RESULT
- * type - Type du fichier. AFT_UNKNOWN est retourné lorsque le type du
- * fichier n'a pu être déterminé, ou lorsqu'une erreur s'est produite.
- * Dans ce dernier cas, roFileInfos.GetIoError() permet d'obtenir un
- * supplément d'information sur cette erreur.
- * Le type AFT_DEFAULT est similaire au type AFT_PCM, à la différence
- * que le fichier n'a pas été identifié comme tel de manière certaine.
- *
- * NOTES
- * Cette fonction crée un certain nombre de tableaux sur la pile. S'
- * assurer qu'elle est appelée avec une taille de pile suffisante.
- *
- *****************************************************************************
- *
- */
-
- static const char PCM_EXTENSION[] = "#?.pcm";
- static const char RAW_EXTENSION[] = "#?.raw";
- static const char CDDA_EXTENSION[] = "#?.cdda";
-
-
- e_AudioTypes
- IdentifyInputFile(FileInfosC &roFileInfo)
- {
- const ULONG BUFFSIZE = 32;
-
- CFile FH;
- CLock NewDir;
- BPTR bpOldDir;
- ULONG a_iIdentBuff[BUFFSIZE];
-
- e_AudioTypes iType;
- STRING cFileName = roFileInfo.NodeName();
- ULONG iFL = roFileInfo.GetFileLength();
-
- extern int CheckExtension(STRING cFileName, STRING cExtension, ULONG iExtLen);
-
- // Si le fichier a une taille impaire, il ne peut pas s'agir d'un fichier audio.
-
- if ( (iFL & 1) != 0 || iFL < 4)
- {
- iType = AFT_NOT_AUDIO;
- }
- else
- { // Changer le répertoire courant pour s'assurer qu'on adresse le bon fichier.
-
- iType = AFT_UNKNOWN;
-
- if ( (NewDir.Lock(roFileInfo.GetPathName(), CLock::READ)) != 0)
- {
- bpOldDir = DOSLib::CurrentDir(NewDir);
-
- // Ouvrir le fichier, et examiner son type.
-
- if ( (FH.Open(cFileName, CFile::OLDFILE)) != NULL)
- {
- if (FH.Read(a_iIdentBuff, BUFFSIZE * 4) > 4)
- {
- if (a_iIdentBuff[0] == 'FORM') // Fichier IFF. Examiner le type exact.
- {
- switch(a_iIdentBuff[2])
- {
- case 'AIFF':
- iType = AFT_AIFF; // AIFF.
- break;
-
- case 'MAUD':
- iType = AFT_MAUD; // MAUD.
- break;
-
- default:
- iType = AFT_NOT_AUDIO; // Non supporté (image par exemple).
- }
- }
- if (a_iIdentBuff[0] == 'RIFF') iType = AFT_WAV;
-
- // Reconnaissance basée sur l'extension du nom de fichier (.pcm, .raw)
-
- if (CheckExtension(cFileName, PCM_EXTENSION, sizeof(PCM_EXTENSION)-1) != FALSE ||
- CheckExtension(cFileName, RAW_EXTENSION, sizeof(RAW_EXTENSION)-1) != FALSE)
- iType = AFT_PCM;
-
- // Les fichiers CDDA doivent avoir une longueur multiple de 2352.
-
- if (CheckExtension(cFileName, CDDA_EXTENSION, sizeof(CDDA_EXTENSION)-1) != FALSE &&
- roFileInfo.GetFileLength() % CDDA_MULTIPLE == 0)
- iType = AFT_CDDA;
-
- // Types spéciaux... (forcément rejetés).
-
- ULONG hdr = a_iIdentBuff[0];
-
- if ( (hdr >> 16) == 0xE310 // Fichier icône.
- || hdr == 0x3F3 // Fichier exécutable.
- || hdr == 'GIF8' // Fichier GIF.
- || hdr == 0xFFD8FFE0 // Fichier JPEG (?)
- )
- {
- iType = AFT_NOT_AUDIO;
- }
- }
- else roFileInfo.SetIoError(IOERR_READ, DOSLib::IoErr());
- }
- else roFileInfo.SetIoError(IOERR_OPEN, DOSLib::IoErr());
-
- DOSLib::CurrentDir(bpOldDir); // Restaurer le répertoire original
- }
- else roFileInfo.SetIoError(IOERR_DOS, DOSLib::IoErr());
-
- // Si le type du fichier est inconnu, on part du principe que c'est un fichier RAW...
-
- if (iType == AFT_UNKNOWN) iType = AFT_DEFAULT;
-
- // Promouvoir les types RAW/PCM en type CDDA si la longueur du fichier fait
- // penser à un fichier CDDA.
-
- if ( (iType == AFT_PCM || iType == AFT_DEFAULT) && (roFileInfo.GetFileLength() % CDDA_MULTIPLE) == 0)
- iType = AFT_CDDA;
- }
-
- roFileInfo.SetFileType(iType); // Définir le type de fichier audio.
- return (iType);
- }
-
-
- // Fonction privée remplaçant avantageusement ParsePattern/MatchPattern
- // Retourne TRUE si le fichier possède bien l'extension passée en argument.
-
- int CheckExtension(STRING cFileName, STRING cExtension, ULONG iExtLen)
- {
- return DOSLib::MatchPatternNoCase(cFileName, cExtension);
- }
- ///
- /// InitFileInfos()
- /****** Common.cpp/InitFileInfos ********************************************
- *
- * NAME
- * InitFileInfos -- Obtenir les infos du fichier.
- *
- * SYNOPSIS
- * Error = InitFileInfos(roFileInfo)
- *
- * e_IoErrors InitFileInfos(FileInfosC &);
- *
- * FUNCTION
- * Examine le fichier afin d'obtenir les informations concernant le nombre
- * d'échantillons, la fréquence d'échantillonage, etc.
- *
- * INPUTS
- * roFileInfo - Informations sur le fichier courant.
- *
- * RESULT
- * Error - Code d'erreur.
- *
- * NOTES
- * Cette fonction crée un objet InputStream afin d'analyser le fichier audio
- * (fréquence d'échantillonage, etc).
- *
- * Le type du fichier audio peut être modifié par cette fonction (notament
- * lorsque le fichier n'est pas dans un format correct conformément au
- * type attendu).
- *
- * SEE ALSO
- * Class InputStreamC
- *
- *****************************************************************************
- *
- */
-
-
- e_IoErrors
- InitFileInfos(FileInfosC &roFileInfo)
- {
- InputStreamC *poInput = NULL; // Handle
-
- poInput = CreateAudioC(roFileInfo);
-
- // Rechercher les informations sur le fichier.
-
- if (poInput == NULL) roFileInfo.SetIoError(IOERR_NO_MEMORY);
- else poInput->GetFileInfos();
-
- // Libérer l'objet InputStream étant donné qu'il n'a servi qu'à obtenir certaines informations
- // sur le fichier.
-
- delete poInput;
-
- return roFileInfo.GetIoError();
- }
- ///
- /// CreateAudioC()
- /****** Common/CreateAudioC *************************************************
- *
- * NAME
- * CreateAudioC -- Créer un objet AudioC
- *
- * SYNOPSIS
- * AudioObject = CreateAudioC(roFileInfo)
- *
- * InputStreamC * CreateAudioC(FileInfosC &);
- *
- * FUNCTION
- * Crée un fichier AudioC correspondant au fichier à traiter.
- *
- * INPUTS
- * roFileInfo - Informations concernant le fichier à traiter.
- *
- * RESULT
- * AudioObject - Objet AudioC ou NULL en cas de problème.
- *
- *****************************************************************************
- *
- */
-
-
- InputStreamC *CreateAudioC(FileInfosC &roFileInfo)
- {
- InputStreamC *poInput = NULL;
-
- switch(roFileInfo.GetFileType())
- {
- // Fichiers RAW/PCM/CDDA/UNKNOWN
-
- case AFT_DEFAULT:
- case AFT_PCM:
- {
- poInput = new RAW_AudioC(roFileInfo);
- break;
- }
-
- case AFT_CDDA:
- case AFT_CDDA_INTEL:
- poInput = new CDDA_AudioC(roFileInfo);
- break;
-
- // Fichiers IFF AIFF/MAUD
-
- case AFT_AIFF:
- poInput = new AIFF_AudioC(roFileInfo);
- break;
-
- case AFT_MAUD:
- poInput = new MAUD_AudioC(roFileInfo);
- break;
-
- // Fichiers RIFF-WAV
-
- case AFT_WAV:
- poInput = new WAV_AudioC(roFileInfo);
- break;
-
- default:
- break;
- }
-
- return poInput;
- }
- ///
-
- //----------------------------------------------------------------------------------------------------
- //=========================================== EncodeFile() ===========================================
- //----------------------------------------------------------------------------------------------------
-
- int EncodeFile(FileInfosC &roFileInfos)
- {
- e_EncoderST iStatus = ESTAT_NOTREADY;
-
- STRING sResultString = NULL;
- int done = TRUE;
-
- // Créer un objet Layer pour l'encodage du fichier courant.
-
- e_Layer iLayerType = roFileInfos.GetLayer();
- CoderC *poEncoder = NULL;
-
- switch (iLayerType)
- {
- case LAYER_I:
- poEncoder = new CoderL1C(roFileInfos);
- break;
-
- case LAYER_II:
- poEncoder = new CoderL2C(roFileInfos);
- break;
- }
-
- if (poEncoder != NULL) iStatus = poEncoder->GetEncoderStatus();
-
- // Si l'encodeur est prêt, commencer l'encodage.
-
- if (iStatus == ESTAT_READY)
- {
- InitTimer();
-
- //-----------------------------
- //===== BOUCLE PRINCIPALE =====
- //-----------------------------
-
- int stop = 0;
- display->ResetAnimVal();
-
- while (poEncoder->GetAudio() && stop == 0)
- {
- if (!poEncoder->Encode()) break;
-
- stop = display->UpdateProgression(poEncoder->GetProgression(), &roFileInfos);
- if (stop & SIGBREAKF_CTRL_D) done = FALSE;
- }
-
- // Afficher les messages d'erreurs éventuels.
-
- e_IoErrors IOErr = roFileInfos.GetIoError();
- ULONG Err2 = roFileInfos.GetError2();
-
- if (IOErr == IOERR_INTERNAL && Err2 == ERROR_BREAK) sResultString = GetString(MSG_BREAK_TXT);
- else if (IOErr == IOERR_WARN && Err2 == ERROR_NO_MORE_ENTRIES)
- {
- LONG iNumSecs = GetElapsedTime();
-
- // Afficher le temps écoulé pendant l'encodage.
-
- if (iNumSecs < 0)
- {
- display->out() << "\n" << GetString(MSG_NO_TIMER_ERRORTXT) << "\n" << endl;
- }
- else
- {
- div_t temp;
- int s;
-
- temp = div(iNumSecs, 60);
- s = temp.rem;
- temp = div(temp.quot, 60);
-
- display->out() << "\n" << GetString(MSG_ELAPSED_TIME_TXT) << " : ";
- display->out().fill('0');
- display->out().width(2);
- display->out() << temp.quot << ":";
- display->out().width(2);
- display->out() << temp.rem << ":";
- display->out().width(2);
- display->out() << s;
-
- u_Time t = roFileInfos.GetTime();
- if (t.iTime != 0x5858)
- {
- int duration = t.sTime.bMinutes * 60 + t.sTime.bSecondes;
- int elapsed = (temp.quot * 60 + temp.rem) * 60 + s;
- double r = (double) elapsed / duration;
- int prec = display->out().precision(2);
-
- display->out() << " (ratio = " << r << ":1)";
- display->out().precision(prec);
- }
- display->out() << endl;
- }
-
- display->out() << GetString(MSG_DONE_TXT) << endl;
- }
- else if (IOErr == IOERR_NO_MEMORY) sResultString = GetString(MSG_OUT_OF_MEMORY_ERROR);
- else if (IOErr != IOERR_NONE) sResultString = GetString(MSG_STREAM_ERROR);
- }
-
- // Traiter les codes d'erreur de l'encodeur.
-
- if (poEncoder)
- {
- e_EncErrCodes iErrCode = poEncoder->GetSecondaryError();
- iStatus = poEncoder->GetEncoderStatus();
-
- if (iStatus == ESTAT_NOTSUPPORTED)
- {
- // Actuellement, la seule erreur possible est : ERR_BAD_FREQUENCY.
-
- sResultString = GetString(MSG_UNSUPPORTED_FREQUENCY_ERROR);
- }
- else if (iStatus == ESTAT_NOTREADY)
- {
- switch (iErrCode)
- {
- case ERR_NOT_INITIALIZED:
- sResultString = GetString(MSG_ENCODER_NOT_READY_ERROR);
- break;
-
- case ERR_ISTREAM_FAILURE:
- sResultString = GetString(MSG_ISTREAM_ERROR);
- break;
-
- default:
- break;
- }
- }
- else if (iStatus == ESTAT_IOERROR)
- {
- switch (iErrCode)
- {
- case ERR_OPEN_OSTREAM:
- sResultString = GetString(MSG_OPEN_OSTREAM_ERROR);
- break;
-
- case ERR_SEEK_OSTREAM:
- sResultString = GetString(MSG_SEEK_OSTREAM_ERROR);
- break;
-
- case ERR_WRITE_OSTREAM:
- sResultString = GetString(MSG_WRITE_OSTREAM_ERROR);
- break;
-
- case ERR_CLOSE_OSTREAM:
- sResultString = GetString(MSG_CLOSE_OSTREAM_ERROR);
- break;
-
- default:
- break;
- }
- }
- else if (iStatus == ESTAT_NOMEMORY)
- {
- // Actuellement, la seule erreur possible est : ERR_INTERNAL_BUFFERS
-
- sResultString = GetString(MSG_OUT_OF_MEMORY_ERROR);
- }
- }
- else
- {
- sResultString = GetString(MSG_OUT_OF_MEMORY_ERROR);
- }
-
- if (sResultString) display->PrintErrorMsg(sResultString);
-
- // Libérer les ressources allouées.
-
- delete poEncoder;
- return done;
- }
-
-
- //----------------------------------------------------------------------------------------------------
- //============================================== Timer ===============================================
- //----------------------------------------------------------------------------------------------------
-
- /// Définitions pour l'utilisation du Timer
-
- #ifndef DEVICES_TIMER_H
- #include <devices/timer.h>
- #endif
-
- #ifndef CLIB_TIMER_PROTOS_H
- #include <clib/timer_protos.h>
- #endif
-
- extern "C"{
- struct Library *TimerBase = NULL;
- };
-
- timerequest TimerIO;
- timeval Time1;
-
- ///
- /// InitTimer()
- /****** Common/InitTimer ****************************************************
- *
- * NAME
- * InitTimer -- Initialiser le Timer.
- *
- * SYNOPSIS
- * InitTimer()
- *
- * void InitTimer();
- *
- * FUNCTION
- * Ouvre le timer.device, puis note l'heure courante afin de pouvoir cal-
- * culer ultérieurement le temps de calcul de l'encodeur.
- *
- * SEE ALSO
- * GetElapsedTime(), EncodeFile()
- *
- *****************************************************************************
- *
- */
-
-
- void InitTimer()
- {
- if (!::OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) &TimerIO, 0))
- {
- TimerBase = (Library *) TimerIO.tr_node.io_Device;
- ::GetSysTime(&Time1);
- }
- }
- ///
- /// GetElapsedTime()
- /****** Common/GetElapsedTime ***********************************************
- *
- * NAME
- * GetElapsedTime -- Calculer une durée.
- *
- * SYNOPSIS
- * NumSecs = GetElapsedTime()
- *
- * LONG GetElapsedTime();
- *
- * FUNCTION
- * Calcule le temps écoulé depuis l'appel de la fonction InitTimer().
- * A l'issue de ce calcul, le timer.device est automatiquement libéré.
- *
- * RESULT
- * NumSecs - Nombre de secondes écoulées, ou -1 en cas d'erreur.
- *
- * SEE ALSO
- * InitTimer(), EncodeFile()
- *
- *****************************************************************************
- *
- */
-
-
- LONG GetElapsedTime()
- {
- timeval Time2;
-
- if (TimerBase)
- {
- ::GetSysTime(&Time2);
- ::SubTime(&Time2, &Time1);
- ::CloseDevice((struct IORequest *) &TimerIO);
-
- return Time2.tv_secs;
- }
- else return (-1);
- }
- ///
-
- //----------------------------------------------------------------------------------------------------
- //====================================== Gestion de la mémoire =======================================
- //----------------------------------------------------------------------------------------------------
-
- /// AllocAlignedBuffer()
- //----------------------------------------------------------------------------------------------------
- //======================================== AllocAlignedBuffer ========================================
- //----------------------------------------------------------------------------------------------------
- //
- // Allouer un tampon de la taille indiquée, aligné sur une adresse multiple de 16.
- //
- // ALGO : Exec retourne toujours une adresse multiple de 8, donc il suffit d'ajouter 8 à l'adresse
- // retournée lorsqu'elle n'est pas multiple de 16 pour obtenir un pointeur sur un bloc aligné.
- // Une entête est insérée avant le bloc de façon à garder une trace du pointeur original (qui
- // devra être passé à FreeBuffer() tôt ou tard).
-
- #ifdef __PPC__
- #define ALIGN 32
- #else
- #define ALIGN 16
- #endif
-
-
- void *AllocAlignedBuffer(ULONG size)
- {
- LONG *p;
- LONG *pa;
-
- if ( (p = (LONG *) AllocBuffer(size + (ALIGN+8)) ) != NULL)
- {
- pa = (LONG *) ( ((LONG)p + (ALIGN+7)) & (~(ALIGN-1)) );
- // pa = Pointeur aligné.
- *(pa - 1) = (LONG)pa - (LONG)p; // Pour contrôle (0 ou 8).
- *(pa - 2) = (LONG)p; // Adresse à passer à FreeBuffer()
-
- return (pa);
- }
-
- return (NULL);
- }
- ///
- /// FreeAlignedBuffer()
- //----------------------------------------------------------------------------------------------------
- //======================================== FreeAlignedBuffer =========================================
- //----------------------------------------------------------------------------------------------------
- //
- // Libérer un bloc aligné sur une adresse multiple de 16.
- // L'assertion permet de vérifier la conformité du pointeur présent dans l'entête de bloc (ceci
- // assure que l'adresse transmise en argument correspond bien à un bloc aligné, et que le pointeur
- // à passer à FreeBuffer() n'a pas été écrasé par mégarde).
-
- void FreeAlignedBuffer(void *buffaddr)
- {
- FreeBuffer((void *) *((LONG *)buffaddr - 2));
- }
- ///
-
-