Annotation of hatari/src/ymFormat.c, revision 1.1.1.11

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - ymFormat.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   YM File output, for use with STSound etc...
                      8: */
1.1.1.11! root        9: const char YMFormat_rcsid[] = "Hatari $Id: ymFormat.c,v 1.21 2008/07/27 18:26:19 npomarede Exp $";
1.1       root       10: 
                     11: #include "main.h"
1.1.1.7   root       12: #include "configuration.h"
1.1       root       13: #include "file.h"
1.1.1.7   root       14: #include "log.h"
1.1       root       15: #include "psg.h"
                     16: #include "sound.h"
                     17: #include "ymFormat.h"
1.1.1.7   root       18: 
1.1       root       19: 
1.1.1.2   root       20: #define YM_MAX_VBLS    (50*60*8)            /* 50=1 second, 50*60=1 minute, 50*60*8=8 minutes, or 24000 */
                     21: #define YM_RECORDSIZE  (4+(YM_MAX_VBLS*NUM_PSG_SOUND_REGISTERS))  /* ~330k for 8 minutes */
1.1       root       22: 
1.1.1.11! root       23: bool bRecordingYM = FALSE;
1.1.1.10  root       24: static int nYMVBLS = 0;
                     25: static Uint8 *pYMData, *pYMWorkspace = NULL;
                     26: static char *pszYMFileName = NULL;
1.1.1.2   root       27: 
                     28: /*-----------------------------------------------------------------------*/
1.1.1.10  root       29: /**
                     30:  * Start recording YM registers to workspace
                     31:  */
1.1.1.11! root       32: bool YMFormat_BeginRecording(const char *filename)
1.1       root       33: {
1.1.1.10  root       34:        /* Free any previous data, don't save */
                     35:        bRecordingYM = FALSE;
                     36:        YMFormat_EndRecording();
                     37: 
                     38:        /* Make sure we have a proper filename to use */
                     39:        if (!filename || strlen(filename) <= 0)
                     40:        {
                     41:                return FALSE;
                     42:        }
                     43:        pszYMFileName = strdup(filename);
                     44:        if (!pszYMFileName)
                     45:        {
                     46:                return FALSE;
                     47:        }
                     48: 
                     49:        /* Create YM workspace */
                     50:        pYMWorkspace = (Uint8 *)malloc(YM_RECORDSIZE);
                     51: 
                     52:        if (!pYMWorkspace)
                     53:        {
                     54:                /* Failed to allocate memory, cannot record */
                     55:                free(pszYMFileName);
                     56:                pszYMFileName = NULL;
                     57:                return FALSE;
                     58:        }
                     59: 
                     60:        /* Get workspace pointer and store 4 byte header */
                     61:        pYMData = pYMWorkspace;
                     62:        *pYMData++ = 'Y';
                     63:        *pYMData++ = 'M';
                     64:        *pYMData++ = '3';
                     65:        *pYMData++ = '!';
1.1.1.6   root       66: 
1.1.1.10  root       67:        bRecordingYM = TRUE;          /* Ready to record */
                     68:        nYMVBLS = 0;                  /* Number of VBLs of information */
1.1.1.6   root       69: 
1.1.1.10  root       70:        /* And inform user */
                     71:        Log_AlertDlg(LOG_INFO, "YM sound data recording has been started.");
1.1.1.6   root       72: 
1.1.1.10  root       73:        return TRUE;
1.1       root       74: }
                     75: 
1.1.1.2   root       76: 
                     77: /*-----------------------------------------------------------------------*/
1.1.1.10  root       78: /**
                     79:  * Convert YM data to stream for output
                     80:  *
                     81:  * Data is:
                     82:  *   4 Byte header 'YM3!'
                     83:  *   VBL Count x 14 PSG registers
                     84:  * BUT
                     85:  *   We need data in a register stream, eg Reg 0, VBL 1, VBL 2, VBL n and then next register...
                     86:  * 
                     87:  * Convert to new workspace and return TRUE if all OK
                     88:  */
1.1.1.11! root       89: static bool YMFormat_ConvertToStreams(void)
1.1       root       90: {
1.1.1.10  root       91:        Uint8 *pNewYMWorkspace;
                     92:        Uint8 *pTmpYMData, *pNewYMData;
                     93:        Uint8 *pTmpYMStream, *pNewYMStream;
                     94:        int Reg, Count;
                     95: 
                     96:        /* Allocate new workspace to convert data to */
                     97:        pNewYMWorkspace = (Uint8 *)malloc(YM_RECORDSIZE);
                     98:        if (pNewYMWorkspace)
                     99:        {
                    100:                /* Convert data, first copy over header */
                    101:                pTmpYMData = pYMWorkspace;
                    102:                pNewYMData = pNewYMWorkspace;
                    103:                *pNewYMData++ = *pTmpYMData++;
                    104:                *pNewYMData++ = *pTmpYMData++;
                    105:                *pNewYMData++ = *pTmpYMData++;
                    106:                *pNewYMData++ = *pTmpYMData++;
                    107: 
                    108:                /* Now copy over each stream */
                    109:                for(Reg=0; Reg<NUM_PSG_SOUND_REGISTERS; Reg++)
                    110:                {
                    111:                        /* Get pointer to source / destination */
                    112:                        pTmpYMStream = pTmpYMData + Reg;
                    113:                        pNewYMStream = pNewYMData + (Reg*nYMVBLS);
                    114: 
                    115:                        /* Copy recording VBLs worth */
                    116:                        for(Count=0; Count<nYMVBLS; Count++)
                    117:                        {
                    118:                                *pNewYMStream++ = *pTmpYMStream;
                    119:                                pTmpYMStream += NUM_PSG_SOUND_REGISTERS;
                    120:                        }
                    121:                }
                    122: 
                    123:                /* Delete old workspace and assign new */
                    124:                free(pYMWorkspace);
                    125:                pYMWorkspace = pNewYMWorkspace;
                    126: 
                    127:                return TRUE;
                    128:        }
                    129:        return FALSE;
1.1       root      130: }
                    131: 
1.1.1.2   root      132: 
                    133: /*-----------------------------------------------------------------------*/
1.1.1.10  root      134: /**
                    135:  * End recording YM registers and save as '.YM' file
                    136:  */
                    137: void YMFormat_EndRecording(void)
1.1       root      138: {
1.1.1.10  root      139:        /* Recording, have recorded information? */
                    140:        if (bRecordingYM && pszYMFileName && pYMWorkspace && nYMVBLS)
                    141:        {
                    142:                /* Convert YM to correct format(list of register 1, then register 2...) */
                    143:                if (YMFormat_ConvertToStreams())
                    144:                {
                    145:                        /* Save YM File */
                    146:                        File_Save(pszYMFileName, pYMWorkspace,(size_t)(nYMVBLS*NUM_PSG_SOUND_REGISTERS)+4, FALSE);
                    147:                        /* And inform user */
                    148:                        Log_AlertDlg(LOG_INFO, "YM sound data recording has been stopped.");
                    149:                }
                    150:                else
1.1.1.11! root      151:                        Log_AlertDlg(LOG_ERROR, "YM sound data conversion failed!");
1.1.1.10  root      152: 
                    153:        }
                    154:        /* And free */
                    155:        if (pYMWorkspace)
                    156:        {
                    157:                free(pYMWorkspace);
                    158:                pYMWorkspace = NULL;
                    159:        }
                    160:        if (pszYMFileName)
                    161:        {
                    162:                free(pszYMFileName);
                    163:                pszYMFileName = NULL;
                    164:        }
                    165:        /* Stop recording */
                    166:        bRecordingYM = FALSE;
1.1       root      167: }
                    168: 
1.1.1.2   root      169: 
                    170: /*-----------------------------------------------------------------------*/
1.1.1.10  root      171: /**
                    172:  * Store a VBLs worth of YM registers to workspace - call each VBL
                    173:  */
1.1       root      174: void YMFormat_UpdateRecording(void)
                    175: {
1.1.1.10  root      176:        int i;
1.1       root      177: 
1.1.1.10  root      178:        /* Can record this VBL information? */
                    179:        if (bRecordingYM)
                    180:        {
                    181:                /* Copy VBL registers to workspace */
                    182:                for(i=0; i<(NUM_PSG_SOUND_REGISTERS-1); i++)
1.1.1.11! root      183:                        *pYMData++ = SoundRegs[i];
1.1.1.10  root      184:                /* Handle register '13'(PSG_REG_ENV_SHAPE) correctly - store 0xFF is did not write to this frame */
                    185:                if (bEnvelopeFreqFlag)
1.1.1.11! root      186:                        *pYMData++ = SoundRegs[PSG_REG_ENV_SHAPE];
1.1.1.10  root      187:                else
                    188:                        *pYMData++ = 0xff;
                    189: 
                    190:                /* Increase VBL count */
                    191:                nYMVBLS++;
                    192:                /* If run out of workspace, just save */
                    193:                if (nYMVBLS>=YM_MAX_VBLS)
                    194:                        YMFormat_EndRecording();
                    195:        }
1.1       root      196: }
                    197: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.