/** * Furnace Tracker - multi-system chiptune tracker * Copyright (C) 2021-2025 tildearrow and contributors * * This program 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 of the License, or * (at your option) any later version. * * This program 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; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "asio.h" #include "../ta-log.h" static TAAudioASIO* callbackInstance=NULL; static void _onBufferSwitch(long index, ASIOBool isDirect) { if (callbackInstance==NULL) return; callbackInstance->onProcess(index); } static void _onSampleRate(ASIOSampleRate rate) { if (callbackInstance==NULL) return; callbackInstance->onSampleRate(*(double*)(&rate)); } static long _onMessage(long type, long value, void* msg, double* opt) { return 0; } void TAAudioASIO::onSampleRate(double rate) { sampleRateChanged(SampleRateChangeEvent(rate)); } void TAAudioASIO::onBufferSize(int bufsize) { bufferSizeChanged(BufferSizeChangeEvent(bufsize)); } void TAAudioASIO::onProcess(int index) { if (audioProcCallback!=NULL) { if (midiIn!=NULL) midiIn->gather(); audioProcCallback(audioProcCallbackUser,inBufs,outBufs,desc.inChans,desc.outChans,desc.bufsize); } // upload here... for (int i=0; i=desc.outChans) continue; float* srcBuf=outBufs[ch]; switch (chanInfo[i].type) { // little-endian case ASIOSTInt16LSB: { short* buf=(short*)bufInfo[i].buffers[index]; for (unsigned int j=0; j8388607) val=-8388607; val<<=8; buf[j]=val; } break; } case ASIOSTFloat32LSB: { float* buf=(float*)bufInfo[i].buffers[index]; for (unsigned int j=0; jASIO_CHANNEL_MAX) maxInChans=ASIO_CHANNEL_MAX; if (maxOutChans>ASIO_CHANNEL_MAX) maxOutChans=ASIO_CHANNEL_MAX; if (desc.inChans>maxInChans) desc.inChans=maxInChans; if (desc.outChans>maxOutChans) desc.outChans=maxOutChans; long minBufSize=0; long maxBufSize=0; long actualBufSize=0; long bufSizeGranularity=0; result=ASIOGetBufferSize(&minBufSize,&maxBufSize,&actualBufSize,&bufSizeGranularity); if (result!=ASE_OK) { logE("could not get buffer size! (%s)",getErrorStr(result)); ASIOExit(); drivers.removeCurrentDriver(); return false; } ASIOSampleRate outRate; result=ASIOGetSampleRate(&outRate); if (result!=ASE_OK) { logE("could not get sample rate! (%s)",getErrorStr(result)); ASIOExit(); drivers.removeCurrentDriver(); return false; } desc.rate=*(double*)(&outRate); totalChans=0; if (desc.inChans>0) { inBufs=new float*[desc.inChans]; for (int i=0; i0) { outBufs=new float*[desc.outChans]; for (int i=0; i TAAudioASIO::listAudioDevices() { std::vector ret; if (!driverNamesInit) { for (int i=0; i