|
|
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.8 ! root 9: char YMFormat_rcsid[] = "Hatari $Id: ymFormat.c,v 1.12 2005/07/15 19:30:32 thothy 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:
23: BOOL bRecordingYM = FALSE;
24: int nYMVBLS = 0;
25: unsigned char *pYMWorkspace = NULL, *pYMData;
26:
1.1.1.2 root 27:
28: /*-----------------------------------------------------------------------*/
1.1 root 29: /*
30: Start recording YM registers to workspace
31: */
32: BOOL YMFormat_BeginRecording(char *pszYMFileName)
33: {
1.1.1.2 root 34: /* Free any previous data, don't save */
1.1 root 35: YMFormat_FreeRecording();
36:
1.1.1.6 root 37: /* Make sure we have a proper filename to use */
38: if (!pszYMFileName || strlen(pszYMFileName)<=0)
39: {
40: return FALSE;
1.1 root 41: }
42:
1.1.1.6 root 43: /* Create YM workspace */
1.1.1.7 root 44: pYMWorkspace = (unsigned char *)malloc(YM_RECORDSIZE);
1.1.1.6 root 45:
46: if (!pYMWorkspace)
47: {
48: /* Failed to allocate memory, cannot record */
49: bRecordingYM = FALSE;
50: return FALSE;
1.1 root 51: }
52:
1.1.1.6 root 53: /* Get workspace pointer and store 4 byte header */
54: pYMData = pYMWorkspace;
55: *pYMData++ = 'Y';
56: *pYMData++ = 'M';
57: *pYMData++ = '3';
58: *pYMData++ = '!';
59:
60: bRecordingYM = TRUE; /* Ready to record */
61: nYMVBLS = 0; /* Number of VBLs of information */
62:
63: /* And inform user */
1.1.1.7 root 64: Log_AlertDlg(LOG_INFO, "YM sound data recording has been started.");
1.1.1.6 root 65:
66: return TRUE;
1.1 root 67: }
68:
1.1.1.2 root 69:
70: /*-----------------------------------------------------------------------*/
1.1 root 71: /*
72: End recording YM registers and save as '.YM' file
73: */
1.1.1.7 root 74: void YMFormat_EndRecording(void)
1.1 root 75: {
76: /* Have recorded information? */
77: if (pYMWorkspace && nYMVBLS) {
78: /* Convert YM to correct format(list of register 1, then register 2...) */
79: if (YMFormat_ConvertToStreams()) {
80: /* Save YM File */
1.1.1.3 root 81: if ( strlen(ConfigureParams.Sound.szYMCaptureFileName)>0 ) {
1.1.1.8 ! root 82: File_Save(ConfigureParams.Sound.szYMCaptureFileName, pYMWorkspace,(size_t)(nYMVBLS*NUM_PSG_SOUND_REGISTERS)+4, FALSE);
1.1.1.7 root 83: /* And inform user */
84: Log_AlertDlg(LOG_INFO, "YM sound data recording has been stopped.");
1.1 root 85: }
86: }
87: }
88:
89: /* And free */
90: YMFormat_FreeRecording();
91: }
92:
1.1.1.2 root 93:
94: /*-----------------------------------------------------------------------*/
1.1 root 95: /*
96: Free up any resources used by YM recording
97: */
98: void YMFormat_FreeRecording(void)
99: {
1.1.1.2 root 100: /* Free workspace */
1.1 root 101: if (pYMWorkspace)
1.1.1.7 root 102: free(pYMWorkspace);
1.1 root 103: pYMWorkspace = NULL;
104:
1.1.1.2 root 105: /* Stop recording */
1.1 root 106: bRecordingYM = FALSE;
107: }
108:
1.1.1.2 root 109:
110: /*-----------------------------------------------------------------------*/
1.1 root 111: /*
112: Store a VBLs worth of YM registers to workspace - call each VBL
113: */
114: void YMFormat_UpdateRecording(void)
115: {
116: int i;
117:
1.1.1.2 root 118: /* Can record this VBL information? */
1.1 root 119: if (bRecordingYM) {
1.1.1.2 root 120: /* Copy VBL registers to workspace */
1.1 root 121: for(i=0; i<(NUM_PSG_SOUND_REGISTERS-1); i++)
122: *pYMData++ = PSGRegisters[i];
1.1.1.2 root 123: /* Handle register '13'(PSG_REG_ENV_SHAPE) correctly - store 0xFF is did not write to this frame */
1.1 root 124: if (bEnvelopeFreqFlag)
125: *pYMData++ = PSGRegisters[PSG_REG_ENV_SHAPE];
126: else
127: *pYMData++ = 0xff;
128:
1.1.1.2 root 129: /* Increase VBL count */
1.1 root 130: nYMVBLS++;
1.1.1.2 root 131: /* If run out of workspace, just save */
1.1 root 132: if (nYMVBLS>=YM_MAX_VBLS)
1.1.1.7 root 133: YMFormat_EndRecording();
1.1 root 134: }
135: }
136:
1.1.1.2 root 137:
138: /*-----------------------------------------------------------------------*/
1.1 root 139: /*
140: Convert YM data to stream for output
141:
142: Data is:
143: 4 Byte header 'YM3!'
144: VBL Count x 14 PSG registers
145: BUT
146: We need data in a register stream, eg Reg 0, VBL 1, VBL 2, VBL n and then next register...
147:
148: Convert to new workspace and return TRUE if all OK
149: */
150: BOOL YMFormat_ConvertToStreams(void)
151: {
152: unsigned char *pNewYMWorkspace;
1.1.1.7 root 153: unsigned char *pTmpYMData, *pNewYMData;
154: unsigned char *pTmpYMStream, *pNewYMStream;
1.1 root 155: int Reg, Count;
156:
1.1.1.2 root 157: /* Allocate new workspace to convert data to */
1.1.1.7 root 158: pNewYMWorkspace = (unsigned char *)malloc(YM_RECORDSIZE);
1.1 root 159: if (pNewYMWorkspace) {
1.1.1.2 root 160: /* Convert data, first copy over header */
1.1.1.7 root 161: pTmpYMData = pYMWorkspace;
1.1 root 162: pNewYMData = pNewYMWorkspace;
1.1.1.7 root 163: *pNewYMData++ = *pTmpYMData++;
164: *pNewYMData++ = *pTmpYMData++;
165: *pNewYMData++ = *pTmpYMData++;
166: *pNewYMData++ = *pTmpYMData++;
1.1 root 167:
1.1.1.2 root 168: /* Now copy over each stream */
1.1 root 169: for(Reg=0; Reg<NUM_PSG_SOUND_REGISTERS; Reg++) {
1.1.1.2 root 170: /* Get pointer to source / destination */
1.1.1.7 root 171: pTmpYMStream = pTmpYMData + Reg;
1.1 root 172: pNewYMStream = pNewYMData + (Reg*nYMVBLS);
173:
1.1.1.2 root 174: /* Copy recording VBLs worth */
1.1 root 175: for(Count=0; Count<nYMVBLS; Count++) {
1.1.1.7 root 176: *pNewYMStream++ = *pTmpYMStream;
177: pTmpYMStream += NUM_PSG_SOUND_REGISTERS;
1.1 root 178: }
179: }
180:
1.1.1.2 root 181: /* Delete old workspace and assign new */
1.1.1.7 root 182: free(pYMWorkspace);
1.1 root 183: pYMWorkspace = pNewYMWorkspace;
184:
185: return(TRUE);
186: }
187: else
188: return(FALSE);
189: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.