Init之后就需要createBuffers。下面是createBuffers代码。
AsioError CUsbAsio::createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks)
{
//bufferInfos, 需要分配内存,即将inputBuffers/outputBuffers分配好后指向bufferInfos->buffers;
//numChannels, 声道数
//bufferSize, 需要分配的buffer大小
//callback, 分配完之后设置asioTime
ASIOBufferInfo *info = bufferInfos;
bool notEnoughMem = false;
activeInputs = 0;
activeOutputs = 0;
blockFrames = bufferSize;
for(int i=0; i<numChannels; i++)
{
//set Input buffer
if(info->isInput)
{
//检查Asio buffer info 的channel数是否正确
if(info->channelNum<0 || info->channelNum >= m_NumInputs)
goto error;
inMap[activeInputs] = info->channelNum;
//分配buffer, *2是因为交换数据,需要2个buffer
inputBuffers[activeInputs= = new char [bufferSize * m_NumSampleSize *2];
memset(inputBuffers[acitive], 0 , bufferSize * m_NumSampleSize *2);
if(inputBuffers[activeInputs])
{
info->buffers[0] = inputBuffers;
info->buffers[1] = inputBuffers + bufferSize*m_NumSampleSize;
}else{
//new false, out of memory
notEnoughMem = true;
info->buffers[0] = NULL;
info->buffers[1] = NULL;
}
activeInput++;
if(activeInput > m_NumInputs)
goto error;
}else //set output buffer
{
if(info->channelNum<0 || info->channelNum>=m_NumInputs)
outMap[activeOutputs] = info->channelNum;
outputBuffers[activeOutputs] = new char[bufferSize * m_NumSampleSize *2];
memset(outputBuffers, 0, bufferSize*m_NumSampleSize*2);
if(outputBuffers[activeOutputs])
{
info->buffers[0] = outputBuffers;
info->buffers[1] = outputBuffers+bufferSize*m_NumSampleSize;
}else{//out of memory
notEnoughMem = true;
info->buffers[0]=NULL;
info->buffers[1]= NULL;
}
activeOutputs++;
if(avtiveOutputs > info->channleNum)
goto error;
}
}
if(notEnoughMem)
{
disposeBuffers();
return ASE_NoMemory;
}
//set AsioTime
this->callbacks = callbacks;
if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0))
{
timeInfoMode = true;
asioTime.timeInfo.speed = 1;
asioTime.timeInfo.systemTime.hi = asioTime.timeInfo.systemTime.lo = 0;
asioTime.timeInfo.samplePosition.hi = asioTime.timeInfo.samplePosition.lo = 0;
asioTime.timeInfo.sampleRate = sampleRate;
asioTime.timeInfo.flag = kSystemTimeValid|kSamplePositionValid|kSampleRateValid;
asioTime.timeCode.speed = 1;
asioTime.timeCode.timeCodeSamples.lo = asioTime.timeCode.timeCodeSamples.hi = 0;
asioTime.timeCode.flags = kTcValid|kTcRunning;
}else
{
timeInfoMode = false;
}
m_BufferSwitchEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
return ASE_OK;
error:
disposeBuffers();
return ASE_InvalidParameter;
}
ASIOError CUsbAsio::disposeBuffers()
{
callbacks = NULL;
stop();
for(int i=0; i<activeInputs; i++)
{
if(inputBuffers[i])
delete inputBuffers[i];
inputBuffers[i] = NULL;
}
activeInputs = 0;
for(int i=0; i<activeOutputs; i++)
{
if(outputBuffers[i])
delete outputBuffers[i];
outoutBuffers[i] = NULL;
}
activeBuffers = 0;
if(m_BufferSwitchEvent)
CloseHandle(m_BufferSwitchEvent);
m_BufferSwitchEvent = NULL;
return ASE_OK;
}