Annotation of hatari/src/wavFormat.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

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