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

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

unix.superglobalmegacorp.com

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