Пример #1
0
void DACUpdate(INT16* Buffer, INT32 Length)
{
#if defined FBA_DEBUG
	if (!DebugSnd_DACInitted) bprintf(PRINT_ERROR, _T("DACUpdate called without init\n"));
#endif

	struct dac_info *ptr;

	for (INT32 i = 0; i < NumChips; i++) {
		UpdateStream(i, nBurnSoundLen);
	}

	INT16 *lbuf = lBuffer;
	INT16 *rbuf = rBuffer;

	if (bAddSignal) {
		while (Length--) {
			Buffer[0] = BURN_SND_CLIP((INT32)(lbuf[0] + Buffer[0]));
			Buffer[1] = BURN_SND_CLIP((INT32)(rbuf[0] + Buffer[1]));
			Buffer += 2;
			lbuf[0] = 0; // clear buffer
			rbuf[0] = 0; // clear buffer
			lbuf++;
			rbuf++;
		}
	} else {
		while (Length--) {
			Buffer[0] = lbuf[0];
			Buffer[1] = rbuf[0];
			Buffer += 2;
			lbuf[0] = 0; // clear buffer
			rbuf[0] = 0; // clear buffer
			lbuf++;
			rbuf++;
		}
	}

	for (INT32 i = 0; i < NumChips; i++) {
		ptr = &dac_table[i];
		ptr->nCurrentPosition = 0;
	}
}
Пример #2
0
static void YM2151RenderNormal(INT16* pSoundBuf, INT32 nSegmentLength)
{
#if defined FBA_DEBUG
	if (!DebugSnd_YM2151Initted) bprintf(PRINT_ERROR, _T("YM2151RenderNormal called without init\n"));
#endif

	nBurnPosition += nSegmentLength;

	pYM2151Buffer[0] = pBuffer;
	pYM2151Buffer[1] = pBuffer + nSegmentLength;

	YM2151UpdateOne(0, pYM2151Buffer, nSegmentLength);
	
	for (INT32 n = 0; n < nSegmentLength; n++) {
		INT32 nLeftSample = 0, nRightSample = 0;
		
		if ((YM2151RouteDirs[BURN_SND_YM2151_YM2151_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)(pYM2151Buffer[0][n] * YM2151Volumes[BURN_SND_YM2151_YM2151_ROUTE_1]);
		}
		if ((YM2151RouteDirs[BURN_SND_YM2151_YM2151_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)(pYM2151Buffer[0][n] * YM2151Volumes[BURN_SND_YM2151_YM2151_ROUTE_1]);
		}
		
		if ((YM2151RouteDirs[BURN_SND_YM2151_YM2151_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)(pYM2151Buffer[1][n] * YM2151Volumes[BURN_SND_YM2151_YM2151_ROUTE_2]);
		}
		if ((YM2151RouteDirs[BURN_SND_YM2151_YM2151_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)(pYM2151Buffer[1][n] * YM2151Volumes[BURN_SND_YM2151_YM2151_ROUTE_2]);
		}
		
		nLeftSample = BURN_SND_CLIP(nLeftSample);
		nRightSample = BURN_SND_CLIP(nRightSample);
			
		pSoundBuf[(n << 1) + 0] = nLeftSample;
		pSoundBuf[(n << 1) + 1] = nRightSample;
	}
}
Пример #3
0
void AY8910Render(INT16** buffer, INT16* dest, INT32 length, INT32 bAddSignal)
{
#if defined FBA_DEBUG
#ifdef __GNUC__ 
	if (!DebugSnd_AY8910Initted) bprintf(PRINT_ERROR, _T("AY8910Render called without init\n"));
	if (num >= 7) bprintf(PRINT_ERROR, _T("AY8910Render called with invalid number of chips %i (max is 6)\n"), num);
#endif
#endif

	INT32 i;
	INT16 *buf0 = buffer[0];
	INT16 *buf1 = buffer[1];
	INT16 *buf2 = buffer[2];
	INT16 *buf3, *buf4, *buf5, *buf6, *buf7, *buf8, *buf9, *buf10, *buf11, *buf12, *buf13, *buf14, *buf15, *buf16, *buf17;
	INT32 n;
	
	for (i = 0; i < num; i++) {
		AY8910Update(i, buffer + (i * 3), length);
	}
	
	if (num >= 2) {
		buf3 = buffer[3];
		buf4 = buffer[4];
		buf5 = buffer[5];
	}
	if (num >= 3) {
		buf6 = buffer[6];
		buf7 = buffer[7];
		buf8 = buffer[8];
	}
	if (num >= 4) {
		buf9 = buffer[9];
		buf10 = buffer[10];
		buf11 = buffer[11];
	}
	if (num >= 5) {
		buf12 = buffer[12];
		buf13 = buffer[13];
		buf14 = buffer[14];
	}
	if (num >= 6) {
		buf15 = buffer[15];
		buf16 = buffer[16];
		buf17 = buffer[17];
	}
		
	for (n = 0; n < length; n++) {
		INT32 nLeftSample = 0, nRightSample = 0;
		
		AY8910_ADD_SOUND(BURN_SND_AY8910_ROUTE_1, buf0)
		AY8910_ADD_SOUND(BURN_SND_AY8910_ROUTE_2, buf1)
		AY8910_ADD_SOUND(BURN_SND_AY8910_ROUTE_3, buf2)
		
		if (num >= 2) {
			AY8910_ADD_SOUND(3 + BURN_SND_AY8910_ROUTE_1, buf3)
			AY8910_ADD_SOUND(3 + BURN_SND_AY8910_ROUTE_2, buf4)
			AY8910_ADD_SOUND(3 + BURN_SND_AY8910_ROUTE_3, buf5)
		}
		
		if (num >= 3) {
			AY8910_ADD_SOUND(6 + BURN_SND_AY8910_ROUTE_1, buf6)
			AY8910_ADD_SOUND(6 + BURN_SND_AY8910_ROUTE_2, buf7)
			AY8910_ADD_SOUND(6 + BURN_SND_AY8910_ROUTE_3, buf8)
		}
		
		if (num >= 4) {
			AY8910_ADD_SOUND(9 + BURN_SND_AY8910_ROUTE_1, buf9)
			AY8910_ADD_SOUND(9 + BURN_SND_AY8910_ROUTE_2, buf10)
			AY8910_ADD_SOUND(9 + BURN_SND_AY8910_ROUTE_3, buf11)
		}
		
		if (num >= 5) {
			AY8910_ADD_SOUND(12 + BURN_SND_AY8910_ROUTE_1, buf12)
			AY8910_ADD_SOUND(12 + BURN_SND_AY8910_ROUTE_2, buf13)
			AY8910_ADD_SOUND(12 + BURN_SND_AY8910_ROUTE_3, buf14)
		}
		
		if (num >= 6) {
			AY8910_ADD_SOUND(15 + BURN_SND_AY8910_ROUTE_1, buf15)
			AY8910_ADD_SOUND(15 + BURN_SND_AY8910_ROUTE_2, buf16)
			AY8910_ADD_SOUND(15 + BURN_SND_AY8910_ROUTE_3, buf17)
		}
		
		nLeftSample = BURN_SND_CLIP(nLeftSample);
		nRightSample = BURN_SND_CLIP(nRightSample);
			
		if (bAddSignal) {
			dest[(n << 1) + 0] += nLeftSample;
			dest[(n << 1) + 1] += nRightSample;
		} else {
			dest[(n << 1) + 0] = nLeftSample;
			dest[(n << 1) + 1] = nRightSample;
		}
	}
}
Пример #4
0
void BurnYMF278BUpdate(INT32 nSegmentEnd)
{
#if defined FBA_DEBUG
	if (!DebugSnd_YMF278BInitted) bprintf(PRINT_ERROR, _T("BurnYMF278BUpdate called without init\n"));
#endif

	INT16* pSoundBuf = pBurnSoundOut;
	INT32 nSegmentLength = nSegmentEnd;

//	bprintf(PRINT_NORMAL, _T("    YMF278B render %6i -> %6i\n"), nYMF278BPosition, nSegmentEnd);

	if (nBurnSoundRate == 0) {
		return;
	}

	if (nSegmentEnd < nYMF278BPosition) {
		nSegmentEnd = nYMF278BPosition;
	}

	if (nSegmentLength > nBurnSoundLen) {
		nSegmentLength = nBurnSoundLen;
	}

	YMF278BRender(nSegmentEnd);

	pYMF278BBuffer[0] = pBuffer + 0 * 4096 + 4;
	pYMF278BBuffer[1] = pBuffer + 1 * 4096 + 4;

	for (INT32 n = nFractionalPosition; n < nSegmentLength; n++) {
		INT32 nLeftSample = 0, nRightSample = 0;

		if ((YMF278BRouteDirs[BURN_SND_YMF278B_YMF278B_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)(pYMF278BBuffer[0][n] * YMF278BVolumes[BURN_SND_YMF278B_YMF278B_ROUTE_1]);
		}
		if ((YMF278BRouteDirs[BURN_SND_YMF278B_YMF278B_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)(pYMF278BBuffer[0][n] * YMF278BVolumes[BURN_SND_YMF278B_YMF278B_ROUTE_1]);
		}
		
		if ((YMF278BRouteDirs[BURN_SND_YMF278B_YMF278B_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)(pYMF278BBuffer[1][n] * YMF278BVolumes[BURN_SND_YMF278B_YMF278B_ROUTE_2]);
		}
		if ((YMF278BRouteDirs[BURN_SND_YMF278B_YMF278B_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)(pYMF278BBuffer[1][n] * YMF278BVolumes[BURN_SND_YMF278B_YMF278B_ROUTE_2]);
		}
		
		nLeftSample = BURN_SND_CLIP(nLeftSample);
		nRightSample = BURN_SND_CLIP(nRightSample);
			
		pSoundBuf[(n << 1) + 0] = nLeftSample;
		pSoundBuf[(n << 1) + 1] = nRightSample;
	}

	nFractionalPosition = nSegmentLength;

	if (nSegmentEnd >= nBurnSoundLen) {
		INT32 nExtraSamples = nSegmentEnd - nBurnSoundLen;

		for (INT32 i = 0; i < nExtraSamples; i++) {
			pYMF278BBuffer[0][i] = pYMF278BBuffer[0][nBurnSoundLen + i];
			pYMF278BBuffer[1][i] = pYMF278BBuffer[1][nBurnSoundLen + i];
		}

		nFractionalPosition = 0;

		nYMF278BPosition = nExtraSamples;

	}
}
Пример #5
0
void BurnSampleRender(INT16 *pDest, UINT32 pLen)
{
#if defined FBA_DEBUG
	if (!DebugSnd_SamplesInitted) bprintf(PRINT_ERROR, _T("BurnSampleRender called without init\n"));
#endif

	if (pBurnSoundOut == NULL) return;

	INT32 nFirstSample = 0;
        UINT32 *dest = (UINT32*)pDest;

        if (bAddToStream == 0) {
            memset(dest, 0, pLen * 4); // clear buffer to get rid of unwanted noise at end of short samples - dink
        }

	for (INT32 i = 0; i < nTotalSamples; i++)
	{
		sample_ptr = &samples[i];
		if (sample_ptr->playing == 0) continue;

		INT32 playlen = pLen;
		INT32 loop = sample_ptr->loop;
		INT32 length = sample_ptr->length;
		INT32 position = sample_ptr->position;

		UINT32 *data = (UINT32*)sample_ptr->data;

		if (loop) {
			if (bAddToStream == 0 && nFirstSample == 0) {
				position *= 2;
				length *= 2;
				INT16 *dst = (INT16*)dest;
				INT16 *dat = (INT16*)data;
				
				for (INT32 j = 0; j < playlen; j++, position+=2, dst += 2) {
					INT32 nLeftSample = 0, nRightSample = 0;
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[(position + 0) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[(position + 0) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[(position + 1) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[(position + 1) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					
					nLeftSample = BURN_SND_CLIP(nLeftSample);
					nRightSample = BURN_SND_CLIP(nRightSample);
					
					dst[0] = nLeftSample;
					dst[1] = nRightSample;
				}
			} else {
				position *= 2;
				length *= 2;
				INT16 *dst = (INT16*)dest;
				INT16 *dat = (INT16*)data;
				
				for (INT32 j = 0; j < playlen; j++, position+=2, dst += 2) {
					INT32 nLeftSample = 0, nRightSample = 0;
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[(position + 0) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[(position + 0) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[(position + 1) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[(position + 1) % length] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					
					nLeftSample = BURN_SND_CLIP(nLeftSample + dst[0]);
					nRightSample = BURN_SND_CLIP(nRightSample + dst[1]);
					
					dst[0] = nLeftSample;
					dst[1] = nRightSample;
				}
			}
		} else {
			length = length - position;

			if (length <= 0) {
				if (loop == 0) {
                                       sample_ptr->playing = 0;
                                       continue;
				}
                        }

			data += position;
			if (playlen > length) playlen = length;
			if (bAddToStream == 0 && nFirstSample == 0) {
				INT16 *dst = (INT16*)dest;
				INT16 *dat = (INT16*)data;
				
				for (INT32 j = 0; j < playlen; j++, dst +=2, dat+=2) {
					INT32 nLeftSample = 0, nRightSample = 0;
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[0] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[0] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[1] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[1] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					
					nLeftSample = BURN_SND_CLIP(nLeftSample);
					nRightSample = BURN_SND_CLIP(nRightSample);
					
					dst[0] = nLeftSample;
					dst[1] = nRightSample;
				}
			} else {
				INT16 *dst = (INT16*)dest;
				INT16 *dat = (INT16*)data;

				for (INT32 j = 0; j < playlen; j++, dst +=2, dat+=2) {
					INT32 nLeftSample = 0, nRightSample = 0;
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[0] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[0] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_1]);
					}
					
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
						nLeftSample += (INT32)(dat[1] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					if ((sample_ptr->output_dir[BURN_SND_SAMPLE_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
						nRightSample += (INT32)(dat[1] * sample_ptr->gain[BURN_SND_SAMPLE_ROUTE_2]);
					}
					
					nLeftSample = BURN_SND_CLIP(nLeftSample + dst[0]);
					nRightSample = BURN_SND_CLIP(nRightSample + dst[1]);
					
					dst[0] = nLeftSample;
					dst[1] = nRightSample;
				}
			}
		}

		sample_ptr->position += playlen;
		nFirstSample++;
	}
}
Пример #6
0
void UPD7759Update(INT32 chip, INT16 *pSoundBuf, INT32 nLength)
{
#if defined FBA_DEBUG
    if (!DebugSnd_UPD7759Initted) bprintf(PRINT_ERROR, _T("UPD7759Update called without init\n"));
    if (chip > nNumChips) bprintf(PRINT_ERROR, _T("UPD7759Update called with invalid chip %x\n"), chip);
#endif

    Chip = Chips[chip];

    INT32 ClocksLeft = Chip->clocks_left;
    INT16 Sample = Chip->sample;
    UINT32 Step = Chip->step;
    UINT32 Pos = Chip->pos;

    /* loop until done */
    if (Chip->state != STATE_IDLE)
        while (nLength != 0)
        {
            /* store the current sample */
            INT32 nLeftSample = 0;
            INT32 nRightSample = 0;

            if ((Chip->output_dir & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
                nLeftSample += (INT32)((Sample << 7) * Chip->volume);
            }
            if ((Chip->output_dir & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
                nRightSample += (INT32)((Sample << 7) * Chip->volume);
            }

            nLeftSample = BURN_SND_CLIP(nLeftSample);
            nRightSample = BURN_SND_CLIP(nRightSample);

            pSoundBuf[0] += nLeftSample;
            pSoundBuf[1] += nRightSample;
            pSoundBuf += 2;
            nLength--;

            /* advance by the number of clocks/output sample */
            Pos += Step;

            /* handle clocks, but only in standalone mode */
            while (Chip->rom && Pos >= FRAC_ONE)
            {
                INT32 ClocksThisTime = Pos >> FRAC_BITS;
                if (ClocksThisTime > ClocksLeft)
                    ClocksThisTime = ClocksLeft;

                /* clock once */
                Pos -= ClocksThisTime * FRAC_ONE;
                ClocksLeft -= ClocksThisTime;

                /* if we're out of clocks, time to handle the next state */
                if (ClocksLeft == 0)
                {
                    /* advance one state; if we hit idle, bail */
                    UPD7759AdvanceState();
                    if (Chip->state == STATE_IDLE)
                        break;

                    /* reimport the variables that we cached */
                    ClocksLeft = Chip->clocks_left;
                    Sample = Chip->sample;
                }
            }
        }

    if (SlaveMode && ClocksLeft > 0) UPD7759SlaveModeUpdate();

    Chip->clocks_left = ClocksLeft;
    Chip->pos = Pos;
}
Пример #7
0
static void YM2610UpdateNormal(INT16* pSoundBuf, INT32 nSegmentEnd)
{
#if defined FBA_DEBUG
	if (!DebugSnd_YM2610Initted) bprintf(PRINT_ERROR, _T("YM2610UpdateNormal called without init\n"));
#endif

	INT32 nSegmentLength = nSegmentEnd;

	if (nSegmentEnd < nAY8910Position) {
		nSegmentEnd = nAY8910Position;
	}
	if (nSegmentEnd < nYM2610Position) {
		nSegmentEnd = nYM2610Position;
	}

	if (nSegmentLength > nBurnSoundLen) {
		nSegmentLength = nBurnSoundLen;
	}

	YM2610Render(nSegmentEnd);
	AY8910Render(nSegmentEnd);

	pYM2610Buffer[0] = pBuffer + 4 + 0 * 4096;
	pYM2610Buffer[1] = pBuffer + 4 + 1 * 4096;
	pYM2610Buffer[2] = pBuffer + 4 + 2 * 4096;
	pYM2610Buffer[3] = pBuffer + 4 + 3 * 4096;
	pYM2610Buffer[4] = pBuffer + 4 + 4 * 4096;

	for (INT32 n = nFractionalPosition; n < nSegmentLength; n++) {
		INT32 nAYSample, nLeftSample = 0, nRightSample = 0;

		nAYSample  = pYM2610Buffer[2][n];
		nAYSample += pYM2610Buffer[3][n];
		nAYSample += pYM2610Buffer[4][n];
		
		if (bYM2610UseSeperateVolumes) {
			nLeftSample += (INT32)(nAYSample * YM2610LeftVolumes[BURN_SND_YM2610_AY8910_ROUTE]);
			nLeftSample += (INT32)(pYM2610Buffer[0][n] * YM2610LeftVolumes[BURN_SND_YM2610_YM2610_ROUTE_1]);
			nLeftSample += (INT32)(pYM2610Buffer[1][n] * YM2610LeftVolumes[BURN_SND_YM2610_YM2610_ROUTE_2]);
			
			nRightSample += (INT32)(nAYSample * YM2610RightVolumes[BURN_SND_YM2610_AY8910_ROUTE]);
			nRightSample += (INT32)(pYM2610Buffer[0][n] * YM2610RightVolumes[BURN_SND_YM2610_YM2610_ROUTE_1]);
			nRightSample += (INT32)(pYM2610Buffer[1][n] * YM2610RightVolumes[BURN_SND_YM2610_YM2610_ROUTE_2]);
		} else {
			if ((YM2610RouteDirs[BURN_SND_YM2610_AY8910_ROUTE] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
				nLeftSample += (INT32)(nAYSample * YM2610Volumes[BURN_SND_YM2610_AY8910_ROUTE]);
			}
			if ((YM2610RouteDirs[BURN_SND_YM2610_AY8910_ROUTE] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
				nRightSample += (INT32)(nAYSample * YM2610Volumes[BURN_SND_YM2610_AY8910_ROUTE]);
			}
		
			if ((YM2610RouteDirs[BURN_SND_YM2610_YM2610_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
				nLeftSample += (INT32)(pYM2610Buffer[0][n] * YM2610Volumes[BURN_SND_YM2610_YM2610_ROUTE_1]);
			}
			if ((YM2610RouteDirs[BURN_SND_YM2610_YM2610_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
				nRightSample += (INT32)(pYM2610Buffer[0][n] * YM2610Volumes[BURN_SND_YM2610_YM2610_ROUTE_1]);
			}
		
			if ((YM2610RouteDirs[BURN_SND_YM2610_YM2610_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
				nLeftSample += (INT32)(pYM2610Buffer[1][n] * YM2610Volumes[BURN_SND_YM2610_YM2610_ROUTE_2]);
			}
			if ((YM2610RouteDirs[BURN_SND_YM2610_YM2610_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
				nRightSample += (INT32)(pYM2610Buffer[1][n] * YM2610Volumes[BURN_SND_YM2610_YM2610_ROUTE_2]);
			}
		}
		
		nLeftSample = BURN_SND_CLIP(nLeftSample);
		nRightSample = BURN_SND_CLIP(nRightSample);
			
		if (bYM2610AddSignal) {
			pSoundBuf[(n << 1) + 0] += nLeftSample;
			pSoundBuf[(n << 1) + 1] += nRightSample;
		} else {
			pSoundBuf[(n << 1) + 0] = nLeftSample;
			pSoundBuf[(n << 1) + 1] = nRightSample;
		}
	}

	nFractionalPosition = nSegmentLength;

	if (nSegmentEnd >= nBurnSoundLen) {
		INT32 nExtraSamples = nSegmentEnd - nBurnSoundLen;

		for (INT32 i = 0; i < nExtraSamples; i++) {
			pYM2610Buffer[0][i] = pYM2610Buffer[0][nBurnSoundLen + i];
			pYM2610Buffer[1][i] = pYM2610Buffer[1][nBurnSoundLen + i];
			pYM2610Buffer[2][i] = pYM2610Buffer[2][nBurnSoundLen + i];
			pYM2610Buffer[3][i] = pYM2610Buffer[3][nBurnSoundLen + i];
			pYM2610Buffer[4][i] = pYM2610Buffer[4][nBurnSoundLen + i];
		}

		nFractionalPosition = 0;

		nYM2610Position = nExtraSamples;
		nAY8910Position = nExtraSamples;

		dTime += 100.0 / nBurnFPS;
	}
}
Пример #8
0
static void YM2612UpdateResample(INT16* pSoundBuf, INT32 nSegmentEnd)
{
#if defined FBA_DEBUG
	if (!DebugSnd_YM2612Initted) bprintf(PRINT_ERROR, _T("YM2612UpdateResample called without init\n"));
#endif

	INT32 nSegmentLength = nSegmentEnd;
	INT32 nSamplesNeeded = nSegmentEnd * nBurnYM2612SoundRate / nBurnSoundRate + 1;

	if (nSamplesNeeded < nYM2612Position) {
		nSamplesNeeded = nYM2612Position;
	}

	if (nSegmentLength > nBurnSoundLen) {
		nSegmentLength = nBurnSoundLen;
	}
	nSegmentLength <<= 1;

	YM2612Render(nSamplesNeeded);

	pYM2612Buffer[0] = pBuffer + 0 * 4096 + 4;
	pYM2612Buffer[1] = pBuffer + 1 * 4096 + 4;
	if (nNumChips > 1) {
		pYM2612Buffer[2] = pBuffer + 2 * 4096 + 4;
		pYM2612Buffer[3] = pBuffer + 3 * 4096 + 4;
	}

	for (INT32 i = (nFractionalPosition & 0xFFFF0000) >> 15; i < nSegmentLength; i += 2, nFractionalPosition += nSampleSize) {
		INT32 nLeftSample[4] = {0, 0, 0, 0};
		INT32 nRightSample[4] = {0, 0, 0, 0};
		INT32 nTotalLeftSample, nTotalRightSample;

		INTERPOLATE_ADD_SOUND_LEFT  (BURN_SND_YM2612_YM2612_ROUTE_1, 0)
		INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2612_YM2612_ROUTE_1, 0)
		INTERPOLATE_ADD_SOUND_LEFT  (BURN_SND_YM2612_YM2612_ROUTE_2, 1)
		INTERPOLATE_ADD_SOUND_RIGHT (BURN_SND_YM2612_YM2612_ROUTE_2, 1)
		
		if (nNumChips > 1) {
			INTERPOLATE_ADD_SOUND_LEFT  (2 + BURN_SND_YM2612_YM2612_ROUTE_1, 2)
			INTERPOLATE_ADD_SOUND_RIGHT (2 + BURN_SND_YM2612_YM2612_ROUTE_1, 2)
			INTERPOLATE_ADD_SOUND_LEFT  (2 + BURN_SND_YM2612_YM2612_ROUTE_2, 3)
			INTERPOLATE_ADD_SOUND_RIGHT (2 + BURN_SND_YM2612_YM2612_ROUTE_2, 3)
		}
		
		nTotalLeftSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nLeftSample[0], nLeftSample[1], nLeftSample[2], nLeftSample[3]);
		nTotalRightSample = INTERPOLATE4PS_16BIT((nFractionalPosition >> 4) & 0x0fff, nRightSample[0], nRightSample[1], nRightSample[2], nRightSample[3]);
		
		nTotalLeftSample = BURN_SND_CLIP(nTotalLeftSample);
		nTotalRightSample = BURN_SND_CLIP(nTotalRightSample);
			
		if (bYM2612AddSignal) {
			pSoundBuf[i + 0] = BURN_SND_CLIP(pSoundBuf[i + 0] + nTotalLeftSample);
			pSoundBuf[i + 1] = BURN_SND_CLIP(pSoundBuf[i + 1] + nTotalRightSample);
		} else {
			pSoundBuf[i + 0] = nTotalLeftSample;
			pSoundBuf[i + 1] = nTotalRightSample;
		}
	}
	
	if (nSegmentEnd >= nBurnSoundLen) {
		INT32 nExtraSamples = nSamplesNeeded - (nFractionalPosition >> 16);

		for (INT32 i = -4; i < nExtraSamples; i++) {
			pYM2612Buffer[0][i] = pYM2612Buffer[0][(nFractionalPosition >> 16) + i];
			pYM2612Buffer[1][i] = pYM2612Buffer[1][(nFractionalPosition >> 16) + i];
			if (nNumChips > 1) {
				pYM2612Buffer[2][i] = pYM2612Buffer[2][(nFractionalPosition >> 16) + i];
				pYM2612Buffer[3][i] = pYM2612Buffer[3][(nFractionalPosition >> 16) + i];
			}
		}
Пример #9
0
void saa1099Update(INT32 chip, INT16 *output, INT32 samples)
{
#if defined FBA_DEBUG
	if (!DebugSnd_SAA1099Initted) bprintf(PRINT_ERROR, _T("saa1099Update called without init\n"));
	if (chip > nNumChips) bprintf(PRINT_ERROR, _T("saa1099Update called with invalid chip %x\n"), chip);
#endif

	saa1099_state *saa = &chips[chip];
	INT32 j, ch;

	/* if the channels are disabled we're done */
	if (!saa->all_ch_enable)
	{
		/* init output data */
		memset (output, 0, samples * sizeof(INT16) * 2);
        	return;
	}

	for (ch = 0; ch < 2; ch++)
	{
		switch (saa->noise_params[ch])
		{
			case 0: saa->noise[ch].freq = 31250.0 * 2; break;
			case 1: saa->noise[ch].freq = 15625.0 * 2; break;
			case 2: saa->noise[ch].freq =  7812.5 * 2; break;
			case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break;
		}
	}

	/* fill all data needed */
	for( j = 0; j < samples; j++, output+=2)
	{
		INT32 output_l = 0, output_r = 0;

		/* for each channel */
		for (ch = 0; ch < 6; ch++)
		{
			if (saa->channels[ch].freq == 0.0)
 				saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) / (511.0 - (double)saa->channels[ch].frequency);

			/* check the actual position in the square wave */
			saa->channels[ch].counter -= saa->channels[ch].freq;

			while (saa->channels[ch].counter < 0)
			{
				/* calculate new frequency now after the half wave is updated */
				saa->channels[ch].freq = (double)((2 * 15625) << saa->channels[ch].octave) /
					(511.0 - (double)saa->channels[ch].frequency);

				saa->channels[ch].counter += saa->sample_rate;
				saa->channels[ch].level ^= 1;

				/* eventually clock the envelope counters */
				if (ch == 1 && saa->env_clock[0] == 0)
					saa1099_envelope(saa, 0);
				if (ch == 4 && saa->env_clock[1] == 0)
					saa1099_envelope(saa, 1);
			}

			/* if the noise is enabled */
			if (saa->channels[ch].noise_enable)
			{
				/* if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5) */
				if (saa->noise[ch/3].level & 1)
				{
					/* subtract to avoid overflows, also use only half amplitude */
					output_l -= saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16 / 2;
					output_r -= saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16 / 2;
				}
			}

			/* if the square wave is enabled */
			if (saa->channels[ch].freq_enable)
			{
				/* if the channel level is high */
				if (saa->channels[ch].level & 1)
				{
					output_l += saa->channels[ch].amplitude[ LEFT] * saa->channels[ch].envelope[ LEFT] / 16;
					output_r += saa->channels[ch].amplitude[RIGHT] * saa->channels[ch].envelope[RIGHT] / 16;
				}
			}
		}

		for (ch = 0; ch < 2; ch++)
		{
			/* check the actual position in noise generator */
			saa->noise[ch].counter -= saa->noise[ch].freq;
			while (saa->noise[ch].counter < 0)
			{
				saa->noise[ch].counter += saa->sample_rate;
				if( ((saa->noise[ch].level & 0x4000) == 0) == ((saa->noise[ch].level & 0x0040) == 0) )
					saa->noise[ch].level = (saa->noise[ch].level << 1) | 1;
				else
					saa->noise[ch].level <<= 1;
			}
		}
		/* write sound data to the buffer */
		INT32 nLeftSample = 0, nRightSample = 0;
		
		if ((saa->output_dir[BURN_SND_SAA1099_ROUTE_1] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)((output_l / 6) * saa->gain[BURN_SND_SAA1099_ROUTE_1]);
		}
		if ((saa->output_dir[BURN_SND_SAA1099_ROUTE_1] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)((output_l / 6) * saa->gain[BURN_SND_SAA1099_ROUTE_1]);
		}
		
		if ((saa->output_dir[BURN_SND_SAA1099_ROUTE_2] & BURN_SND_ROUTE_LEFT) == BURN_SND_ROUTE_LEFT) {
			nLeftSample += (INT32)((output_r / 6) * saa->gain[BURN_SND_SAA1099_ROUTE_2]);
		}
		if ((saa->output_dir[BURN_SND_SAA1099_ROUTE_2] & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) {
			nRightSample += (INT32)((output_r / 6) * saa->gain[BURN_SND_SAA1099_ROUTE_2]);
		}
		
		nLeftSample = BURN_SND_CLIP(nLeftSample);
		nRightSample = BURN_SND_CLIP(nRightSample);
		
		output[LEFT] = nLeftSample;
		output[RIGHT] = nRightSample;
	}
}
Пример #10
0
static void UpdateStream(INT32 chip, INT32 length)
{
	dac_info *ptr;
/* char toto[100];
char *titi = &toto[0];
titi=itoa(length);
 			FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"        ",4,60);

			FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)titi,4,60);
*/


	if (lBuffer == NULL) {	// delay buffer allocation for cases when fps is not 60
		if((lBuffer = (INT16*)malloc(nBurnSoundLen * sizeof(INT16)))==NULL)
		{
			while(1);
		}
		memset (lBuffer, 0, nBurnSoundLen * sizeof(INT16));
	}
	if (rBuffer == NULL) {	// delay buffer allocation for cases when fps is not 60
		if((rBuffer = (INT16*)malloc(nBurnSoundLen * sizeof(INT16)))==NULL)
		{
			while(1);
		}
		memset (rBuffer, 0, nBurnSoundLen * sizeof(INT16));
	}

        ptr = &dac_table[chip];
        if (ptr->Initialized == 0) return;

        if (length > nBurnSoundLen) length = nBurnSoundLen;
        length -= ptr->nCurrentPosition;
        if (length <= 0) return;

        INT16 *lbuf = lBuffer + ptr->nCurrentPosition;
	INT16 *rbuf = rBuffer + ptr->nCurrentPosition;

//	INT16 lOut = ((ptr->OutputDir & BURN_SND_ROUTE_LEFT ) == BURN_SND_ROUTE_LEFT ) ? ptr->Output : 0;
//        INT16 rOut = ((ptr->OutputDir & BURN_SND_ROUTE_RIGHT) == BURN_SND_ROUTE_RIGHT) ? ptr->Output : 0;
	INT16 lOut = ptr->Output;
        INT16 rOut = ptr->Output;

        ptr->nCurrentPosition += length;

        if (rOut && lOut) {
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"a",4,10);
			
                while (length--) {
//                      *lbuf++ = *lbuf + lOut;
//			*rbuf++ = *rbuf + rOut;
                        *lbuf++ = BURN_SND_CLIP(*lbuf + lOut);
			*rbuf++ = BURN_SND_CLIP(*rbuf + rOut);
                }
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"b",4,10);

        } else if (lOut) {
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"c",4,10);
			
                while (length--) *lbuf++ = BURN_SND_CLIP(*lbuf + lOut);
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"d",4,10);
        } else if (rOut) {            
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"e",4,10);
                while (length--) *rbuf++ = BURN_SND_CLIP(*rbuf + rOut);
//		FNT_Print256_2bpp((volatile unsigned char *)0x25e20000,(unsigned char *)"f",4,10);
        }
}