Annotation of hatari/src/audio.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   Hatari
                      3: */
                      4: 
                      5: #include "main.h"
                      6: #include "audio.h"
                      7: #include "debug.h"
                      8: #include "dialog.h"
                      9: #include "errlog.h"
                     10: #include "memAlloc.h"
                     11: #include "misc.h"
                     12: #include "sound.h"
                     13: #include "view.h"
                     14: 
                     15: #define WRITE_INIT_POS  ((SoundPlayBackFrequencies[OutputAudioFreqIndex]/50)*2)  /* Write 2/50th ahead of write position */
                     16: 
                     17: /* 11Khz, 22Khz, 44Khz playback */
                     18: int SoundPlayBackFrequencies[] = {
                     19:   11025,  /* PLAYBACK_LOW */
                     20:   22050,  /* PLAYBACK_MEDIUM */
                     21:   44100,  /* PLAYBACK_HIGH */
                     22: };
                     23: 
                     24: /* Bytes to download on each odd/even frame - as 11Khz does not divide by 50 exactly */
                     25: int SoundPlayBackFreqFrameLengths[][2] = {
                     26:   221,220,  /* 220.5 */
                     27:   441,441,  /* 441 */
                     28:   882,882,  /* 882 */
                     29: };
                     30: 
                     31: BOOL bDisableDirectSound=FALSE;
                     32: //LPDIRECTSOUND lpDS = NULL;
                     33: //LPDIRECTSOUNDBUFFER  lpDSBPrimBuffer = NULL;
                     34: BOOL bDirectSoundWorking=FALSE;                             /* Is sound OK */
                     35: volatile BOOL bPlayingBuffer = FALSE;                       /* Is playing buffer? Start when start processing ST */
                     36: int WriteOffset=0;                                          /* Write offset into buffer */
                     37: int OutputAudioFreqIndex=FREQ_44Khz;                        /* Playback rate(11Khz,22Khz or 44Khz) */
                     38: float PlayVolume=0.0f;
                     39: BOOL bAquireWritePosition=FALSE;
                     40: int PrimaryBufferSize;                                      /* Size of primary buffer */
                     41: 
                     42: 
                     43: /* FIXME: Rewrite those functions: */
                     44: 
                     45: //-----------------------------------------------------------------------
                     46: /*
                     47:   Create object for Direct Sound. Return TRUE if all OK
                     48:   We use direct access to the primary buffer, set to an unsigned 8-bit mono stream
                     49: */
                     50: void DAudio_Init(void)
                     51: {
                     52: #if 0
                     53:   DSCAPS dscaps;
                     54:   HRESULT dsRetVal;
                     55: 
                     56:   // Is enabled?
                     57:   if (bDisableDirectSound) {
                     58:     // Stop any Direct Sound access
                     59:     ErrLog_File("DirectSound: Disabled\n");
                     60:     bDirectSoundWorking = FALSE;
                     61:     return;
                     62:   }
                     63: 
                     64:   // Create the main DirectSound object, using default driver
                     65:   dsRetVal = DirectSoundCreate(NULL, &lpDS, NULL);
                     66:   if(dsRetVal!=DS_OK) {
                     67:     ErrLog_File("ERROR DirectSound: Unable to 'DirectSoundCreate', error code %d\n",dsRetVal);
                     68:     bDirectSoundWorking = FALSE;
                     69:     return;
                     70:   }
                     71:   ErrLog_File("DirectSound: 'DirectSoundCreate' - OK\n");
                     72: 
                     73:   // Report capabilities of sound card/driver
                     74:   dscaps.dwSize = sizeof(DSCAPS); 
                     75:   dsRetVal = lpDS->GetCaps(&dscaps);
                     76:   if(dsRetVal==DS_OK) {
                     77:     // Report general list which we may use
                     78:     ErrLog_File("DirectSound: Capabilities:-\n");
                     79:     if (dscaps.dwFlags&DSCAPS_EMULDRIVER)
                     80:       ErrLog_File("\tEmulatedDriver(WARNING: This may cause Hatari to play back sounds incorrectly\n");
                     81:     if (dscaps.dwFlags&DSCAPS_PRIMARY16BIT)
                     82:       ErrLog_File("\t16-Bit\n");
                     83:     if (dscaps.dwFlags&DSCAPS_PRIMARY8BIT)
                     84:       ErrLog_File("\t8-Bit\n");
                     85:     if (dscaps.dwFlags&DSCAPS_PRIMARYMONO)
                     86:       ErrLog_File("\tMono\n");
                     87:     if (dscaps.dwFlags&DSCAPS_PRIMARYSTEREO)
                     88:       ErrLog_File("\tStereo\n");
                     89: 
                     90:     // Are good enough?
                     91:     if ( !((dscaps.dwFlags&DSCAPS_PRIMARY8BIT) && (dscaps.dwFlags&DSCAPS_PRIMARYMONO)) ) {
                     92:       // No, MUST have 8-Bit/Mono
                     93:       ErrLog_File("ERROR DirectSound: Your sound card does not support the playback mode required(8-Bit/Mono)\n");
                     94:       bDirectSoundWorking = FALSE;
                     95:       return;
                     96:     }
                     97:   }
                     98: 
                     99:   // Create sound buffer, return if error
                    100:   DAudio_CreateSoundBuffer();
                    101: #endif
                    102: }
                    103: 
                    104: //-----------------------------------------------------------------------
                    105: /*
                    106:   Free object created for Direct Sound
                    107: */
                    108: void DAudio_UnInit(void)
                    109: {
                    110: #if 0
                    111:   // Free Direct Sound
                    112:   DAudio_FreeSoundBuffer();
                    113:   if( lpDS ) {
                    114:     lpDS->Release();  lpDS = NULL;
                    115:   }
                    116: #endif
                    117: }
                    118: 
                    119: //-----------------------------------------------------------------------
                    120: /*
                    121:   Create sound buffer to write samples into
                    122: */
                    123: BOOL DAudio_CreateSoundBuffer(void)
                    124: {
                    125: #if 0
                    126:   WAVEFORMATEX pwfx;
                    127:   DSBUFFERDESC dsbdesc;
                    128:   DSBCAPS dsbcaps;
                    129:     HRESULT dsRetVal;
                    130: 
                    131:     // Set up wave format structure
                    132:     memset(&pwfx, 0, sizeof(WAVEFORMATEX));
                    133:   pwfx.wFormatTag = WAVE_FORMAT_PCM;
                    134:   pwfx.nChannels = 1;                  // Mono
                    135:   pwfx.nSamplesPerSec = SoundPlayBackFrequencies[OutputAudioFreqIndex];
                    136:   pwfx.wBitsPerSample = 8;              // 8 Bit unsigned
                    137:   pwfx.nBlockAlign = (pwfx.nChannels*pwfx.wBitsPerSample)/8;
                    138:   pwfx.nAvgBytesPerSec = pwfx.nSamplesPerSec*pwfx.nBlockAlign;
                    139:   pwfx.cbSize = 0;
                    140:     memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
                    141:     dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
                    142:     // Use direct access for Primary Buffer else sound drivers can cause corrupted sound and
                    143:   // also declare 'STICKFOCUS' otherwise cannot continue sound when loose focus!
                    144:   dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS;
                    145:     // Buffer size is determined by sound hardware. 
                    146:     dsbdesc.dwBufferBytes = 0; 
                    147:     dsbdesc.lpwfxFormat = NULL;              // Must be NULL for primary buffers
                    148: 
                    149:   // Obtain write-primary cooperative level
                    150:   dsRetVal = lpDS->SetCooperativeLevel(hWnd, DSSCL_WRITEPRIMARY);
                    151:   if(dsRetVal!=DS_OK) {
                    152:     ErrLog_File("ERROR DirectSound: Unable to 'SetCooperativeLevel', error code %d\n",dsRetVal);
                    153:     lpDS->Release();  lpDS = NULL;
                    154:     bDirectSoundWorking = FALSE;
                    155:     return(FALSE);
                    156:   }
                    157: 
                    158:   // Create sound buffer
                    159:   dsRetVal = lpDS->CreateSoundBuffer(&dsbdesc,&lpDSBPrimBuffer,NULL);
                    160:   if(dsRetVal!=DS_OK) {
                    161:     ErrLog_File("ERROR DirectSound: Unable to 'CreateSoundBuffer', error code %d\n",dsRetVal);
                    162:     lpDS->Release();  lpDS = NULL;
                    163:     bDirectSoundWorking = FALSE;
                    164:     return(FALSE);
                    165:   }
                    166:   
                    167:   // Succeeded. Set primary buffer to desired format. 
                    168:   dsRetVal = lpDSBPrimBuffer->SetFormat(&pwfx); 
                    169:   if(dsRetVal!=DS_OK) {
                    170:     ErrLog_File("ERROR DirectSound: Unable to 'SetFormat', error code %d\n",dsRetVal);
                    171:     lpDS->Release();  lpDS = NULL;
                    172:     lpDSBPrimBuffer->Release();  lpDSBPrimBuffer = NULL;
                    173:     bDirectSoundWorking = FALSE;
                    174:     return(FALSE);
                    175:   }
                    176: 
                    177:   // Get buffer size
                    178:   dsbcaps.dwSize = sizeof(DSBCAPS); 
                    179:   lpDSBPrimBuffer->GetCaps(&dsbcaps); 
                    180:   PrimaryBufferSize = dsbcaps.dwBufferBytes; 
                    181: 
                    182:   // All OK
                    183:   bDirectSoundWorking = TRUE;
                    184:   // And begin
                    185:   DAudio_ResetBuffer();
                    186: 
                    187:   return(TRUE);
                    188: #endif
                    189: }
                    190: 
                    191: //-----------------------------------------------------------------------
                    192: /*
                    193:   Free sound buffer
                    194: */
                    195: void DAudio_FreeSoundBuffer(void)
                    196: {
                    197: #if 0
                    198:   if (lpDSBPrimBuffer) {
                    199:     // Stop
                    200:     DAudio_StopBuffer();
                    201:     // And free
                    202:     lpDSBPrimBuffer->Release();  lpDSBPrimBuffer = NULL;
                    203:   }
                    204: #endif
                    205: }
                    206: 
                    207: //-----------------------------------------------------------------------
                    208: /*
                    209:   Re-Create sound buffer to write samples into, will stop existing and restart with new frequency
                    210: */
                    211: void DAudio_ReCreateDirectSoundBuffer(void)
                    212: {
                    213: #if 0
                    214:   if (lpDS) {
                    215:     // Stop and delete old buffer
                    216:     DAudio_FreeSoundBuffer();
                    217: 
                    218:     // Clear sample buffer, so plays silence
                    219:     Sound_ClearMixBuffer();
                    220: 
                    221:     // And create new one(will use new 'OutputAudioFreq' value)
                    222:     DAudio_CreateSoundBuffer();
                    223:   }
                    224: #endif
                    225: }
                    226: 
                    227: //-----------------------------------------------------------------------
                    228: /*
                    229:   Set DirectSound playback frequency variable, pass as PLAYBACK_xxxx
                    230: */
                    231: void DAudio_SetOutputAudioFreq(int Frequency)
                    232: {
                    233:   // Set new frequency, index into SoundPlayBackFrequencies[]
                    234:   OutputAudioFreqIndex = Frequency;
                    235: }
                    236: 
                    237: //-----------------------------------------------------------------------
                    238: /*
                    239:   Reset sound buffer, so plays from correct position
                    240: */
                    241: void DAudio_ResetBuffer(void)
                    242: {
                    243:   // Get new 'write' position on next frame
                    244:   bAquireWritePosition = TRUE;
                    245: }
                    246: 
                    247: //-----------------------------------------------------------------------
                    248: /*
                    249:   Stop sound buffer
                    250: */
                    251: void DAudio_StopBuffer(void)
                    252: {
                    253: #if 0
                    254:   // Stop from playing
                    255:   if (lpDSBPrimBuffer)
                    256:     lpDSBPrimBuffer->Stop();
                    257:   bPlayingBuffer = FALSE;
                    258: #endif
                    259: }
                    260: 
                    261: //-----------------------------------------------------------------------
                    262: /*
                    263:   Scale sample value(-128...127) according to 'PlayVolume' setting
                    264: */
                    265: char DAudio_ModifyVolume(char Sample)
                    266: {
                    267:   // If full volume, just use current value
                    268:   if (PlayVolume==1.0f)
                    269:     return(Sample);
                    270: 
                    271:   // Else, scale volume
                    272:   Sample = (char)((float)Sample*PlayVolume);
                    273: 
                    274:   return(Sample);
                    275: }
                    276: 
                    277: //-----------------------------------------------------------------------
                    278: /*
                    279:   Write samples into Direct Sound buffer at 'Offset', taking care to wrap around. Pass NULL to write zero's
                    280: */
                    281: void DAudio_WriteSamplesIntoBuffer(char *pSamples,int Index,int Length,int RampSetting)
                    282: {
                    283: #if 0
                    284:     void *lpWrite1, *lpWrite2;
                    285:   unsigned char *pBuffer;
                    286:     DWORD dwLenBytes1, dwLenBytes2;
                    287:     HRESULT dsRetVal;
                    288:   int i,WriteCursor,CursorDiff;
                    289: 
                    290:   // Modify ramp volume - ramp down if sound not enabled or not in windows mouse mode
                    291:   if ( (((RampSetting==RAMP_DOWN) || (!ConfigureParams.Sound.bEnableSound)) && (PlayVolume>0.0f)) || bWindowsMouseMode ) {
                    292:     PlayVolume -= RAMP_DOWN_VOLUME_LEVEL;
                    293:     if (PlayVolume<=0.0f)
                    294:       PlayVolume = 0.0f;
                    295:   }
                    296:   else if ( (RampSetting==RAMP_UP) && (PlayVolume<1.0f) ) {
                    297:     PlayVolume += RAMP_UP_VOLUME_LEVEL;
                    298:     if (PlayVolume>=1.0f)
                    299:       PlayVolume = 1.0f;
                    300:   }
                    301: 
                    302:   if (lpDSBPrimBuffer) {
                    303:     // Do need to reset 'write' position?
                    304:     if (bAquireWritePosition) {
                    305:       // Get current write position
                    306:       lpDSBPrimBuffer->GetCurrentPosition(NULL,(DWORD *)&WriteCursor);
                    307:       WriteOffset = WriteCursor+WRITE_INIT_POS;    // + little gap
                    308:       bAquireWritePosition = FALSE;
                    309:     }
                    310: 
                    311:     // Lock sound buffer to get pointers
                    312:     lpWrite1 = lpWrite2 = NULL;
                    313:     dwLenBytes1 = dwLenBytes2 = 0;
                    314:     dsRetVal = lpDSBPrimBuffer->Lock( WriteOffset, Length, &lpWrite1, &dwLenBytes1, &lpWrite2, &dwLenBytes2, 0 );
                    315:     if (dsRetVal==DSERR_BUFFERLOST) {
                    316:       // Lost focus of buffer, restore and try to lock again
                    317:       lpDSBPrimBuffer->Restore();
                    318:       dsRetVal = lpDSBPrimBuffer->Lock( WriteOffset, Length, &lpWrite1, &dwLenBytes1, &lpWrite2, &dwLenBytes2, 0 );
                    319:     }
                    320: 
                    321:     // All OK?
                    322:     if (dsRetVal==DS_OK) {
                    323:       // Write first section, convert to 'unsigned' and write '128'(unsigned) if passed NULL
                    324:       if ( (dwLenBytes1>0) && (lpWrite1) ) {
                    325:         if (pSamples) {
                    326:           pBuffer = (unsigned char *)lpWrite1;
                    327:           for(i=0; i<(int)dwLenBytes1; i++) {
                    328:             *pBuffer++ = DAudio_ModifyVolume(pSamples[Index])+128;
                    329:             Index = (Index+1)&4095;
                    330:           }
                    331:         }
                    332:         else
                    333:           memset(lpWrite1,128,dwLenBytes1);
                    334:       }
                    335:       // And second, if needed
                    336:       if ( (dwLenBytes2>0) && (lpWrite2) ) {
                    337:         if (pSamples) {
                    338:           pBuffer = (unsigned char *)lpWrite2;
                    339:           for(i=0; i<(int)dwLenBytes2; i++) {
                    340:             *pBuffer++ = DAudio_ModifyVolume(pSamples[Index])+128;
                    341:             Index = (Index+1)&4095;
                    342:           }
                    343:         }
                    344:         else
                    345:           memset(lpWrite2,128,dwLenBytes2);
                    346:       }
                    347: 
                    348:       // Now unlock the buffer.
                    349:       dsRetVal = lpDSBPrimBuffer->Unlock( (LPVOID)lpWrite1, dwLenBytes1,(LPVOID)lpWrite2, dwLenBytes2 );
                    350:     }
                    351: 
                    352:     // Update write buffer
                    353:     if (pSamples) {
                    354:       WriteOffset += Length;
                    355:       if (WriteOffset>=PrimaryBufferSize)
                    356:         WriteOffset -= PrimaryBufferSize;
                    357:     }
                    358: 
                    359:     // Are we playing?
                    360:     if (!bPlayingBuffer) {
                    361:       lpDSBPrimBuffer->Play( 0, 0, DSBPLAY_LOOPING );
                    362:       DAudio_ResetBuffer();
                    363: 
                    364:       bPlayingBuffer = TRUE;
                    365:     }
                    366:     else {
                    367:       // Check here for play/write pointers getting away from each other and set 'bAquireWritePosition' to reset
                    368:       lpDSBPrimBuffer->GetCurrentPosition(NULL,(DWORD *)&WriteCursor);
                    369:       // If the writecursor is too-far away from where we think it should be cause a reset
                    370:       CursorDiff = WriteOffset-WriteCursor;
                    371:       // Check for overlap
                    372:       if (CursorDiff<0)
                    373:         CursorDiff = (WriteOffset+PrimaryBufferSize)-WriteCursor;
                    374:       // So, does need reset?
                    375:       if (abs(CursorDiff)>(WRITE_INIT_POS*2))
                    376:         DAudio_ResetBuffer();
                    377:     }
                    378:   }
                    379: #endif
                    380: }

unix.superglobalmegacorp.com

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