SndASIO::SndASIO(int channels, int mode, char* driver, int numbuffs, SndObj** inputs, int vecsize, float sr) : SndIO(channels,16,inputs,vecsize, sr){ int i; m_numbuffs = numbuffs; m_mode = mode; m_running = false; m_driver = driver; m_ocurrentbuffer = m_icurrentbuffer = 1; m_icount = m_ocount = 0; memset(&m_driverinfo, 0, sizeof(ASIODriverInfo)); m_asiocallbacks.bufferSwitch = &bufferSwitch; m_asiocallbacks.sampleRateDidChange = &sampleRateChanged; m_asiocallbacks.asioMessage = &asioMessages; m_asiocallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo; // Allocate the memory for BufferInfos if(!(bufferinfos = new ASIOBufferInfo[(m_channels+2)*2])){ m_error = 21; return; } if(!asioDrivers) asioDrivers = new AsioDrivers; if(asioDrivers->loadDriver(m_driver)){ if(ASIOInit(&m_driverinfo) == ASE_OK){ if(ASIOCanSampleRate(m_sr) == ASE_OK) ASIOSetSampleRate(m_sr); else ASIOGetSampleRate((double *)&m_sr); // set buffer size long dump1, dump2, dump3; ASIOGetBufferSize(&dump1, &dump2, &buffsize, &dump3); // get number of channels ASIOGetChannels(&ichannels, &ochannels); if(ichannels < m_channels){ m_channels = (short) ichannels; m_samples = m_vecsize*m_channels; } else ichannels = m_channels; if(ochannels < m_channels){ m_channels = (short) ochannels; m_samples = m_vecsize*m_channels; } else ochannels = m_channels; if(m_mode == SND_OUTPUT) ichannels = 0; if(m_mode == SND_INPUT) ochannels = 0; // Set the channel infos if(!(m_channelinfos = new ASIOChannelInfo[m_channels*2])){ m_error = 22; return; } if((m_mode == SND_IO) || (m_mode == SND_OUTPUT)){ outsndbuff = new float*[m_numbuffs]; for(i = 0; i< m_numbuffs; i++){ if(!(outsndbuff[i] = new float[buffsize*m_channels])){ m_error =14; return; } } for(i = 0; i < m_channels; i++){ bufferinfos[i].isInput = ASIOFalse; bufferinfos[i].channelNum = i; bufferinfos[i].buffers[0] = bufferinfos[i].buffers[1] = 0; m_channelinfos[i].channel = bufferinfos[i].channelNum; m_channelinfos[i].isInput = bufferinfos[i].isInput; ASIOGetChannelInfo(&m_channelinfos[i]); switch(m_channelinfos[i].type){ case ASIOSTInt16LSB: encoding = SHORTSAM; m_bits = 16; break; case ASIOSTInt24LSB: encoding = S24LE; m_bits = 24; break; case ASIOSTInt32LSB: encoding = LONGSAM; m_bits = 32; break; default: encoding = SHORTSAM; break; } } } if((m_mode == SND_IO) || (m_mode == SND_INPUT)){ insndbuff = new float*[m_numbuffs]; for(i = 0; i< m_numbuffs; i++){ if(!(insndbuff[i] = new float[buffsize*m_channels])){ m_error =14; return; } } for(i = 0; i < m_channels; i++){ bufferinfos[i+ochannels].isInput = ASIOTrue; bufferinfos[i+ochannels].channelNum = i; bufferinfos[i+ochannels].buffers[0] = bufferinfos[i+ochannels].buffers[1] = 0; m_channelinfos[i+ochannels].channel = bufferinfos[i+ochannels].channelNum; m_channelinfos[i+ochannels].isInput = bufferinfos[i+ochannels].isInput; ASIOGetChannelInfo(&m_channelinfos[i+ochannels]); switch(m_channelinfos[i+ochannels].type){ case ASIOSTInt16LSB: encoding = SHORTSAM; m_bits = 16; break; case ASIOSTInt24LSB: encoding = S24LE; m_bits = 24; break; case ASIOSTInt32LSB: encoding = LONGSAM; m_bits = 32; break; default: encoding = SHORTSAM; break; } } } if(!(ASIOCreateBuffers(bufferinfos, ichannels+ochannels, buffsize, &m_asiocallbacks)== ASE_OK)){ m_error = 25; return; } if(ASIOOutputReady() == ASE_OK) optimise = true; else optimise = false; // printf("channels: %d\n", m_channels); m_outsndbuff = outsndbuff; m_insndbuff = insndbuff; m_encoding = encoding; m_bufferinfos = bufferinfos; m_ichannels = ichannels; m_ochannels = ochannels; m_buffsize = buffsize; currentbuffer = 0; m_called_read = false; buffs = m_numbuffs; } else { // could not initialise m_error = 24; return; } } else { // if driver could not be loaded m_error = 23; return; } #ifdef DEBUG cout << m_bits; #endif }
JNIEXPORT jboolean JNICALL Java_com_synthbot_jasiohost_AsioDriver_ASIOCanSampleRate (JNIEnv *env, jclass clazz, jdouble sampleRate) { ASIOError errorCode = ASIOCanSampleRate((ASIOSampleRate) sampleRate); return (errorCode == ASE_OK) ? JNI_TRUE : JNI_FALSE; }