|
|
1.1 root 1: /*
2: Hatari
3:
4: WAV File output
5:
6: As well as YM file output we also have output in Windows .WAV format. As currently there is no application that
7: can re-play saved sample data from an ST emulator .WAV output seems a good idea. Also it's noticed that ST Sound's
8: playback routine are not as good as the ones currently in Hatari.
9: These .WAV files can then be run through convertors to any other format, such as MP3.
10: We simply save out the WAVE format headers and then write the sample data(at the current rate of playback)
11: as we build it up each frame. When we stop recording we complete the size information in the headers and close up.
12:
13:
14: RIFF Chunk (12 bytes in length total) Byte Number
15: 0 - 3 "RIFF" (ASCII Characters)
16: 4 - 7 Total Length Of Package To Follow (Binary, little endian)
17: 8 - 12 "WAVE" (ASCII Characters)
18:
19: FORMAT Chunk (24 bytes in length total) Byte Number
20: 0 - 3 "fmt_" (ASCII Characters)
21: 4 - 7 Length Of FORMAT Chunk (Binary, always 0x10)
22: 8 - 9 Always 0x01
23: 10 - 11 Channel Numbers (Always 0x01=Mono, 0x02=Stereo)
24: 12 - 15 Sample Rate (Binary, in Hz)
25: 16 - 19 Bytes Per Second
26: 20 - 21 Bytes Per Sample: 1=8 bit Mono, 2=8 bit Stereo or 16 bit Mono, 4=16 bit Stereo
27: 22 - 23 Bits Per Sample
28:
29: DATA Chunk Byte Number
30: 0 - 3 "data" (ASCII Characters)
31: 4 - 7 Length Of Data To Follow
32: 8 - end Data (Samples)
33: */
34:
35: #include "main.h"
36: #include "audio.h"
37: #include "dialog.h"
38: #include "file.h"
39: #include "misc.h"
40: #include "sound.h"
1.1.1.2 ! root 41:
1.1 root 42:
43: //HFILE WavFile;
44: //OFSTRUCT WavFileInfo;
45: BOOL bRecordingWav=FALSE; // Is a WAV file open and recording?
46: int nWavOutputBytes; // Number of samples bytes saved
47:
48: //-----------------------------------------------------------------------
49: /*
50: */
51: BOOL WAVFormat_OpenFile(/*HWND hWnd,*/ char *pszWavFileName)
52: {
53: static char szRiff[] = { "RIFF" };
54: static char szWave[] = { "WAVE" };
55: static char szFmt[] = { "fmt " };
56: static char szData[] = { "data" };
57: static unsigned int Blank=0;
58: static unsigned int FmtLength=0x10;
59: static unsigned short int SOne=0x01;
60: static unsigned int SampleLength;
61: static unsigned int BitsPerSample=8;
62: /* FIXME */
63: /*
64: // Set frequency
65: SampleLength = SoundPlayBackFrequencies[ConfigureParams.Sound.nPlaybackQuality]; // 11Khz, 22Khz or 44Khz
66:
67: // Create our file
68: WavFile = OpenFile(pszWavFileName,&WavFileInfo,OF_CREATE | OF_WRITE);
69: if (WavFile!=HFILE_ERROR) {
70: // Create 'RIFF' chunk
71: _hwrite(WavFile,(char *)szRiff,4); // "RIFF" (ASCII Characters)
72: _hwrite(WavFile,(char *)&Blank,sizeof(int)); // Total Length Of Package To Follow (Binary, little endian)
73: _hwrite(WavFile,(char *)szWave,4); // "WAVE" (ASCII Characters)
74:
75: // Create 'FORMAT' chunk
76: _hwrite(WavFile,(char *)szFmt,4); // "fmt_" (ASCII Characters)
77: _hwrite(WavFile,(char *)&FmtLength,sizeof(int)); // Length Of FORMAT Chunk (Binary, always 0x10)
78: _hwrite(WavFile,(char *)&SOne,sizeof(short int)); // Always 0x01
79: _hwrite(WavFile,(char *)&SOne,sizeof(short int)); // Channel Numbers (Always 0x01=Mono, 0x02=Stereo)
80: _hwrite(WavFile,(char *)&SampleLength,sizeof(int)); // Sample Rate (Binary, in Hz)
81: _hwrite(WavFile,(char *)&SampleLength,sizeof(int)); // Bytes Per Second
82: _hwrite(WavFile,(char *)&SOne,sizeof(short int)); // Bytes Per Sample: 1=8 bit Mono, 2=8 bit Stereo or 16 bit Mono, 4=16 bit Stereo
83: _hwrite(WavFile,(char *)&BitsPerSample,sizeof(short int)); // Bits Per Sample
84:
85: // Create 'DATA' chunk
86: _hwrite(WavFile,(char *)szData,4); // "data" (ASCII Characters)
87: _hwrite(WavFile,(char *)&Blank,sizeof(int)); // Length Of Data To Follow
88:
89: nWavOutputBytes = 0;
90: bRecordingWav = TRUE;
91:
92: // Set status bar
93: StatusBar_SetIcon(STATUS_ICON_SOUND,ICONSTATE_ON);
94: // And inform user
95: if (hWnd)
96: Main_Message("WAV Sound data recording started.",PROG_NAME,MB_OK | MB_ICONINFORMATION);
97: }
98: else
99: bRecordingWav = FALSE;
100:
101: // Ok, or failed?
102: return(bRecordingWav);
103: */
104: }
105:
106: //-----------------------------------------------------------------------
107: /*
108: */
109: void WAVFormat_CloseFile(/*HWND hWnd*/)
110: {
111: int nWavFileBytes;
112: /* FIXME */
113: /*
114: // Turn off icon
115: StatusBar_SetIcon(STATUS_ICON_SOUND,ICONSTATE_OFF);
116:
117: if (bRecordingWav) {
118: // Update headers with sizes
119: nWavFileBytes = (12+24+8+nWavOutputBytes)-8; // File length, less 8 bytes for 'RIFF' and length
120: _llseek(WavFile,4,FILE_BEGIN); // 'Total Length Of Package' element
121: _hwrite(WavFile,(char *)&nWavFileBytes,sizeof(int)); // Total Length Of Package in 'RIFF' chunk
122:
123: _llseek(WavFile,12+24+4,FILE_BEGIN); // 'Length' element
124: _hwrite(WavFile,(char *)&nWavOutputBytes,sizeof(int)); // Length Of Data in 'DATA' chunk
125:
126: // Close file
127: _lclose(WavFile);
128: bRecordingWav = FALSE;
129:
130: // And inform user(this only happens from dialog)
131: if (hWnd)
132: Main_Message("WAV Sound data recording stopped.",PROG_NAME,MB_OK | MB_ICONINFORMATION);
133: }
134: */
135: }
136:
137: //-----------------------------------------------------------------------
138: /*
139: */
140: void WAVFormat_Update(char *pSamples,int Index)
141: {
142: char Char;
143: int i;
144: /* FIXME */
145: /*
146: if (bRecordingWav) {
147: // Output, better if did in two section if wrap
148: for(i=0; i<SAMPLES_PER_FRAME; i++) {
149: // Convert sample to 'signed' byte
150: Char = pSamples[(Index+i)&MIXBUFFER_LENGTH];
151: Char -= 127;
152: // And store
153: _hwrite(WavFile,(char *)&Char,sizeof(unsigned char));
154: }
155:
156: // Add samples to wav file
157: nWavOutputBytes += SAMPLES_PER_FRAME;
158: }
159: */
160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.