This commit is contained in:
parent
98c0065807
commit
3e0452053a
|
@ -1035,7 +1035,7 @@ void BackupDevice::loadfile()
|
||||||
{
|
{
|
||||||
if (advsc.isLoaded())
|
if (advsc.isLoaded())
|
||||||
{
|
{
|
||||||
info.type = advsc.getSaveType() + 1; // skip autodetect description in save_types[] struct
|
info.type = advsc.getSaveType();
|
||||||
if (info.type != 0xFF && info.type != 0xFE)
|
if (info.type != 0xFF && info.type != 0xFE)
|
||||||
{
|
{
|
||||||
u32 adv_size = save_types[info.type+1].size;
|
u32 adv_size = save_types[info.type+1].size;
|
||||||
|
|
|
@ -1,417 +1,208 @@
|
||||||
/*
|
/* mic.cpp - this file is part of DeSmuME
|
||||||
Copyright (C) 2008-2009 DeSmuME team
|
*
|
||||||
|
* Copyright (C) 2009-2011 DeSmuME Team
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
This file is free software: you can redistribute it and/or modify
|
#ifndef WIN32
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This file is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
The NDS microphone produces 8-bit sound sampled at 16khz.
|
|
||||||
The sound data must be read sample-by-sample through the
|
|
||||||
ARM7 SPI device (touchscreen controller, channel 6).
|
|
||||||
|
|
||||||
Note : I added these notes because the microphone isn't
|
|
||||||
documented on GBATek.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mic.h"
|
||||||
#include "NDSSystem.h"
|
#include "NDSSystem.h"
|
||||||
#include "../types.h"
|
|
||||||
#include "../debug.h"
|
|
||||||
#include "../mic.h"
|
|
||||||
#include "../movie.h"
|
|
||||||
#include "readwrite.h"
|
#include "readwrite.h"
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
int MicDisplay;
|
#define MIC_NULL_SAMPLE_VALUE 0
|
||||||
int SampleLoaded=0;
|
#define MIC_MAX_BUFFER_SAMPLES 320
|
||||||
|
#define MIC_BUFFER_SIZE (sizeof(u8) * MIC_MAX_BUFFER_SAMPLES)
|
||||||
|
#define NUM_INTERNAL_NOISE_SAMPLES 32
|
||||||
|
|
||||||
#define MIC_CHECKERR(hr) if(hr != MMSYSERR_NOERROR) return FALSE;
|
static u8 *micSampleBuffer = NULL; // Pointer to the internal sample buffer.
|
||||||
|
static u8 *micReadPosition = NULL; // Pointer to the read position of the internal sample buffer.
|
||||||
|
static u8 *micWritePosition = NULL; // Pointer to the write position of the internal sample buffer.
|
||||||
|
static unsigned int micBufferFillCount; // The number of readable samples in the internal sample buffer.
|
||||||
|
|
||||||
#define MIC_BUFSIZE 4096
|
static void Mic_BufferClear(void)
|
||||||
|
|
||||||
static BOOL Mic_Inited = FALSE;
|
|
||||||
|
|
||||||
static u8 Mic_TempBuf[MIC_BUFSIZE];
|
|
||||||
static u8 Mic_Buffer[2][MIC_BUFSIZE];
|
|
||||||
static u16 Mic_BufPos;
|
|
||||||
static u8 Mic_WriteBuf;
|
|
||||||
static u8 Mic_PlayBuf;
|
|
||||||
|
|
||||||
static int micReadSamplePos=0;
|
|
||||||
|
|
||||||
static HWAVEIN waveIn;
|
|
||||||
static WAVEHDR waveHdr;
|
|
||||||
|
|
||||||
static int CALLBACK waveInProc(HWAVEIN wavein, UINT msg, DWORD instance, DWORD_PTR param1, DWORD_PTR param2)
|
|
||||||
{
|
{
|
||||||
LPWAVEHDR lpWaveHdr;
|
if (micSampleBuffer == NULL) {
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if(!Mic_Inited)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if(msg == WIM_DATA)
|
|
||||||
{
|
|
||||||
lpWaveHdr = (LPWAVEHDR)param1;
|
|
||||||
|
|
||||||
memcpy(Mic_Buffer[Mic_WriteBuf], lpWaveHdr->lpData, MIC_BUFSIZE);
|
|
||||||
Mic_WriteBuf ^= 1;
|
|
||||||
|
|
||||||
hr = waveInAddBuffer(waveIn, lpWaveHdr, sizeof(WAVEHDR));
|
|
||||||
if(hr != MMSYSERR_NOERROR)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* samplebuffer = NULL;
|
|
||||||
static int samplebuffersize = 0;
|
|
||||||
static FILE* fp = NULL;
|
|
||||||
|
|
||||||
EMUFILE_MEMORY newWavData;
|
|
||||||
|
|
||||||
static bool dataChunk(EMUFILE* inf)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
// seek to just after the RIFF header
|
|
||||||
inf->fseek(12,SEEK_SET);
|
|
||||||
|
|
||||||
// search for a format chunk
|
|
||||||
for (;;) {
|
|
||||||
char chunk_id[4];
|
|
||||||
u32 chunk_length;
|
|
||||||
|
|
||||||
if(inf->eof()) return found;
|
|
||||||
if(inf->fread(chunk_id, 4) != 4) return found;
|
|
||||||
if(!read32le(&chunk_length, inf)) return found;
|
|
||||||
|
|
||||||
// if we found a data chunk, excellent!
|
|
||||||
if (memcmp(chunk_id, "data", 4) == 0) {
|
|
||||||
found = true;
|
|
||||||
u8* temp = new u8[chunk_length];
|
|
||||||
if(inf->fread(temp,chunk_length) != chunk_length) {
|
|
||||||
delete[] temp;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
newWavData.fwrite(temp,chunk_length);
|
|
||||||
delete[] temp;
|
|
||||||
chunk_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inf->fseek(chunk_length,SEEK_CUR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool formatChunk(EMUFILE* inf)
|
|
||||||
{
|
|
||||||
// seek to just after the RIFF header
|
|
||||||
inf->fseek(12,SEEK_SET);
|
|
||||||
|
|
||||||
// search for a format chunk
|
|
||||||
for (;;) {
|
|
||||||
char chunk_id[4];
|
|
||||||
u32 chunk_length;
|
|
||||||
|
|
||||||
inf->fread(chunk_id, 4);
|
|
||||||
if(!read32le(&chunk_length, inf)) return false;
|
|
||||||
|
|
||||||
// if we found a format chunk, excellent!
|
|
||||||
if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_length >= 16) {
|
|
||||||
|
|
||||||
// read format chunk
|
|
||||||
u16 format_tag;
|
|
||||||
u16 channel_count;
|
|
||||||
u32 samples_per_second;
|
|
||||||
//u32 bytes_per_second = read32_le(chunk + 8);
|
|
||||||
//u16 block_align = read16_le(chunk + 12);
|
|
||||||
u16 bits_per_sample;
|
|
||||||
|
|
||||||
if(read16le(&format_tag,inf)!=1) return false;
|
|
||||||
if(read16le(&channel_count,inf)!=1) return false;
|
|
||||||
if(read32le(&samples_per_second,inf)!=1) return false;
|
|
||||||
inf->fseek(6,SEEK_CUR);
|
|
||||||
if(read16le(&bits_per_sample,inf)!=1) return false;
|
|
||||||
|
|
||||||
chunk_length -= 16;
|
|
||||||
|
|
||||||
// format_tag must be 1 (WAVE_FORMAT_PCM)
|
|
||||||
// we only support mono 8bit
|
|
||||||
if (format_tag != 1 ||
|
|
||||||
channel_count != 1 ||
|
|
||||||
bits_per_sample != 8) {
|
|
||||||
MessageBox(0,"not a valid RIFF WAVE file; must be 8bit mono pcm",0,0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inf->fseek(chunk_length,SEEK_CUR);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LoadSample(const char *name)
|
|
||||||
{
|
|
||||||
SampleLoaded = 0;
|
|
||||||
if(!name) return true;
|
|
||||||
|
|
||||||
EMUFILE_FILE inf(name,"rb");
|
|
||||||
if(inf.fail()) return false;
|
|
||||||
|
|
||||||
//wav reading code adapted from AUDIERE (LGPL)
|
|
||||||
|
|
||||||
// read the RIFF header
|
|
||||||
u8 riff_id[4];
|
|
||||||
u32 riff_length;
|
|
||||||
u8 riff_datatype[4];
|
|
||||||
|
|
||||||
inf.fread(riff_id, 4);
|
|
||||||
read32le(&riff_length,&inf);
|
|
||||||
inf.fread(riff_datatype, 4);
|
|
||||||
|
|
||||||
if (inf.size() < 12 ||
|
|
||||||
memcmp(riff_id, "RIFF", 4) != 0 ||
|
|
||||||
riff_length == 0 ||
|
|
||||||
memcmp(riff_datatype, "WAVE", 4) != 0) {
|
|
||||||
MessageBox(0,"not a valid RIFF WAVE file",0,0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!formatChunk(&inf))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!dataChunk(&inf)) {
|
|
||||||
MessageBox(0,"not a valid WAVE file. some unknown problem.",0,0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] samplebuffer;
|
|
||||||
samplebuffersize = (int)newWavData.size();
|
|
||||||
samplebuffer = new char[samplebuffersize];
|
|
||||||
memcpy(samplebuffer,newWavData.buf(),samplebuffersize);
|
|
||||||
new(&newWavData) EMUFILE_MEMORY();
|
|
||||||
|
|
||||||
SampleLoaded=1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Mic_DeInit_Physical()
|
|
||||||
{
|
|
||||||
if(!Mic_Inited)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
INFO("win32 microphone DEinit OK\n");
|
|
||||||
|
|
||||||
Mic_Inited = FALSE;
|
|
||||||
|
|
||||||
waveInReset(waveIn);
|
|
||||||
waveInClose(waveIn);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Mic_Init_Physical()
|
|
||||||
{
|
|
||||||
if(Mic_Inited)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
Mic_Inited = FALSE;
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
WAVEFORMATEX wfx;
|
|
||||||
|
|
||||||
memset(Mic_TempBuf, 0x80, MIC_BUFSIZE);
|
|
||||||
memset(Mic_Buffer[0], 0x80, MIC_BUFSIZE);
|
|
||||||
memset(Mic_Buffer[1], 0x80, MIC_BUFSIZE);
|
|
||||||
Mic_BufPos = 0;
|
|
||||||
|
|
||||||
Mic_WriteBuf = 0;
|
|
||||||
Mic_PlayBuf = 1;
|
|
||||||
|
|
||||||
memset(&wfx, 0, sizeof(wfx));
|
|
||||||
wfx.cbSize = 0;
|
|
||||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
wfx.nChannels = 1;
|
|
||||||
wfx.nSamplesPerSec = 16000;
|
|
||||||
wfx.nBlockAlign = 1;
|
|
||||||
wfx.nAvgBytesPerSec = 16000;
|
|
||||||
wfx.wBitsPerSample = 8;
|
|
||||||
|
|
||||||
hr = waveInOpen(&waveIn, WAVE_MAPPER, &wfx, (DWORD_PTR)waveInProc, 0, CALLBACK_FUNCTION);
|
|
||||||
MIC_CHECKERR(hr)
|
|
||||||
|
|
||||||
memset(&waveHdr, 0, sizeof(waveHdr));
|
|
||||||
waveHdr.lpData = (LPSTR)Mic_TempBuf;
|
|
||||||
waveHdr.dwBufferLength = MIC_BUFSIZE;
|
|
||||||
|
|
||||||
hr = waveInPrepareHeader(waveIn, &waveHdr, sizeof(WAVEHDR));
|
|
||||||
MIC_CHECKERR(hr)
|
|
||||||
|
|
||||||
hr = waveInAddBuffer(waveIn, &waveHdr, sizeof(WAVEHDR));
|
|
||||||
MIC_CHECKERR(hr)
|
|
||||||
|
|
||||||
hr = waveInStart(waveIn);
|
|
||||||
MIC_CHECKERR(hr)
|
|
||||||
|
|
||||||
Mic_Inited = TRUE;
|
|
||||||
INFO("win32 microphone init OK\n");
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Mic_Init() {
|
|
||||||
|
|
||||||
micReadSamplePos = 0;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mic_Reset()
|
|
||||||
{
|
|
||||||
micReadSamplePos = 0;
|
|
||||||
|
|
||||||
if(!Mic_Inited)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//reset physical
|
memset(micSampleBuffer, MIC_NULL_SAMPLE_VALUE, MIC_BUFFER_SIZE);
|
||||||
memset(Mic_TempBuf, 0x80, MIC_BUFSIZE);
|
micReadPosition = micSampleBuffer;
|
||||||
memset(Mic_Buffer[0], 0x80, MIC_BUFSIZE);
|
micWritePosition = micSampleBuffer;
|
||||||
memset(Mic_Buffer[1], 0x80, MIC_BUFSIZE);
|
micBufferFillCount = 0;
|
||||||
Mic_BufPos = 0;
|
|
||||||
|
|
||||||
Mic_WriteBuf = 0;
|
|
||||||
Mic_PlayBuf = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mic_DeInit()
|
BOOL Mic_Init(void)
|
||||||
{
|
{
|
||||||
|
BOOL result = FALSE;
|
||||||
|
|
||||||
|
u8 *newBuffer = (u8 *)malloc(MIC_BUFFER_SIZE);
|
||||||
|
if (newBuffer == NULL) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
micSampleBuffer = newBuffer;
|
||||||
|
Mic_BufferClear();
|
||||||
|
result = TRUE;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8 random[32] =
|
void Mic_DeInit(void)
|
||||||
{
|
{
|
||||||
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF,
|
free(micSampleBuffer);
|
||||||
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01,
|
micSampleBuffer = NULL;
|
||||||
} ;
|
}
|
||||||
|
|
||||||
|
void Mic_Reset(void)
|
||||||
|
{
|
||||||
u8 Mic_ReadSample()
|
*micReadPosition = MIC_NULL_SAMPLE_VALUE;
|
||||||
{
|
micWritePosition = micReadPosition;
|
||||||
u8 ret;
|
micBufferFillCount = 0;
|
||||||
u8 tmp;
|
}
|
||||||
if(CommonSettings.micMode == TCommonSettings::Physical)
|
|
||||||
{
|
static bool Mic_GetActivate(void)
|
||||||
if(movieMode == MOVIEMODE_INACTIVE)
|
{
|
||||||
{
|
return NDS_getFinalUserInput().mic.micButtonPressed;
|
||||||
//normal mic behavior
|
}
|
||||||
tmp = (u8)Mic_Buffer[Mic_PlayBuf][Mic_BufPos >> 1];
|
|
||||||
}
|
static bool Mic_IsBufferFull(void)
|
||||||
else
|
{
|
||||||
{
|
return (micBufferFillCount >= MIC_MAX_BUFFER_SAMPLES);
|
||||||
//since we're not recording Mic_Buffer to the movie, use silence
|
}
|
||||||
tmp = 0x80;
|
|
||||||
}
|
static bool Mic_IsBufferEmpty(void)
|
||||||
}
|
{
|
||||||
else
|
return (micBufferFillCount == 0);
|
||||||
{
|
}
|
||||||
if(NDS_getFinalUserInput().mic.micButtonPressed)
|
|
||||||
{
|
static u8 Mic_DefaultBufferRead(void)
|
||||||
if(SampleLoaded)
|
{
|
||||||
{
|
u8 theSample = MIC_NULL_SAMPLE_VALUE;
|
||||||
//use a sample
|
|
||||||
//TODO: what if a movie is active?
|
if (micSampleBuffer == NULL) {
|
||||||
// for now I'm going to hope that if anybody records a movie with a sample loaded,
|
return theSample;
|
||||||
// either they know what they're doing and plan to distribute the sample,
|
}
|
||||||
// or they're playing a game where it doesn't even matter or they never press the mic button.
|
|
||||||
tmp = samplebuffer[micReadSamplePos >> 1];
|
theSample = *micReadPosition;
|
||||||
micReadSamplePos++;
|
|
||||||
if(micReadSamplePos == samplebuffersize*2)
|
if (Mic_IsBufferEmpty()) {
|
||||||
micReadSamplePos=0;
|
return theSample;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
micReadPosition++;
|
||||||
//use the "random" values
|
micBufferFillCount--;
|
||||||
if(CommonSettings.micMode == TCommonSettings::InternalNoise)
|
|
||||||
tmp = random[micReadSamplePos >> 1];
|
// Move the pointer back to start if we reach the end of the memory block.
|
||||||
else tmp = rand();
|
if (micReadPosition >= (micSampleBuffer + MIC_BUFFER_SIZE)) {
|
||||||
micReadSamplePos++;
|
micReadPosition = micSampleBuffer;
|
||||||
if(micReadSamplePos == ARRAY_SIZE(random)*2)
|
}
|
||||||
micReadSamplePos=0;
|
|
||||||
}
|
return theSample;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
u8 Mic_ReadSample(void)
|
||||||
tmp = 0x80;
|
{
|
||||||
|
// All mic modes other than Physical must have the mic hotkey pressed in order
|
||||||
//reset mic button buffer pos if not pressed
|
// to work.
|
||||||
micReadSamplePos=0;
|
if (CommonSettings.micMode != TCommonSettings::Physical && !Mic_GetActivate()) {
|
||||||
}
|
return MIC_NULL_SAMPLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Mic_BufPos & 0x1)
|
return Mic_DefaultBufferRead();
|
||||||
{
|
}
|
||||||
ret = ((tmp & 0x1) << 7);
|
|
||||||
}
|
static void Mic_DefaultBufferWrite(u8 theSample)
|
||||||
else
|
{
|
||||||
{
|
if (micSampleBuffer == NULL || Mic_IsBufferFull()) {
|
||||||
ret = ((tmp & 0xFE) >> 1);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MicDisplay = tmp;
|
*micWritePosition = theSample;
|
||||||
|
micWritePosition++;
|
||||||
Mic_BufPos++;
|
micBufferFillCount++;
|
||||||
if(Mic_BufPos >= (MIC_BUFSIZE << 1))
|
|
||||||
{
|
// Move the pointer back to start if we reach the end of the memory block.
|
||||||
Mic_BufPos = 0;
|
if (micWritePosition >= (micSampleBuffer + MIC_BUFFER_SIZE)) {
|
||||||
Mic_PlayBuf ^= 1;
|
micWritePosition = micSampleBuffer;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
|
static u8 Mic_GenerateInternalNoiseSample(void)
|
||||||
|
{
|
||||||
|
const u8 noiseSample[NUM_INTERNAL_NOISE_SAMPLES] =
|
||||||
|
{
|
||||||
|
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0x8E, 0xFF,
|
||||||
|
0xF4, 0xE1, 0xBF, 0x9A, 0x71, 0x58, 0x5B, 0x5F, 0x62, 0xC2, 0x25, 0x05, 0x01, 0x01, 0x01, 0x01
|
||||||
|
};
|
||||||
|
static unsigned int i = 0;
|
||||||
|
|
||||||
|
if (++i >= NUM_INTERNAL_NOISE_SAMPLES) {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return noiseSample[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 Mic_GenerateWhiteNoiseSample(void)
|
||||||
|
{
|
||||||
|
return (u8)(rand() & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 Mic_GenerateNullSample(void)
|
||||||
|
{
|
||||||
|
return MIC_NULL_SAMPLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mic_DoNoise(BOOL noise)
|
||||||
|
{
|
||||||
|
u8 (*generator) (void) = NULL;
|
||||||
|
|
||||||
|
if (micSampleBuffer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noise) {
|
||||||
|
generator = &Mic_GenerateNullSample;
|
||||||
|
} else if (CommonSettings.micMode == TCommonSettings::InternalNoise) {
|
||||||
|
generator = &Mic_GenerateInternalNoiseSample;
|
||||||
|
} else if (CommonSettings.micMode == TCommonSettings::Random) {
|
||||||
|
generator = &Mic_GenerateWhiteNoiseSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generator == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (micBufferFillCount < MIC_MAX_BUFFER_SAMPLES) {
|
||||||
|
Mic_DefaultBufferWrite(generator());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe a bit paranoid...
|
|
||||||
void mic_savestate(EMUFILE* os)
|
void mic_savestate(EMUFILE* os)
|
||||||
{
|
{
|
||||||
//version
|
write32le(-1,os);
|
||||||
write32le(1,os);
|
|
||||||
assert(MIC_BUFSIZE == 4096); // else needs new version
|
|
||||||
|
|
||||||
os->fwrite((char*)Mic_Buffer[0], MIC_BUFSIZE);
|
|
||||||
os->fwrite((char*)Mic_Buffer[1], MIC_BUFSIZE);
|
|
||||||
write16le(Mic_BufPos,os);
|
|
||||||
write8le(Mic_WriteBuf,os); // seems OK to save...
|
|
||||||
write8le(Mic_PlayBuf,os);
|
|
||||||
write32le(micReadSamplePos,os);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mic_loadstate(EMUFILE* is, int size)
|
bool mic_loadstate(EMUFILE* is, int size)
|
||||||
{
|
{
|
||||||
u32 version;
|
is->fseek(size, SEEK_CUR);
|
||||||
if(read32le(&version,is) != 1) return false;
|
return TRUE;
|
||||||
if(version > 1 || version == 0) { is->fseek(size-4, SEEK_CUR); return true; }
|
|
||||||
|
|
||||||
is->fread((char*)Mic_Buffer[0], MIC_BUFSIZE);
|
|
||||||
is->fread((char*)Mic_Buffer[1], MIC_BUFSIZE);
|
|
||||||
read16le(&Mic_BufPos,is);
|
|
||||||
read8le(&Mic_WriteBuf,is);
|
|
||||||
read8le(&Mic_PlayBuf,is);
|
|
||||||
read32le(&micReadSamplePos,is);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue