Example #1
0
t_CKBOOL MidiInManager::open( MidiIn * min, t_CKINT device_num )
{
    // see if port not already open
    if( device_num >= (t_CKINT)the_mins.capacity() || !the_mins[device_num] )
    {
        // allocate the buffer
        CBufferAdvance * cbuf = new CBufferAdvance;
        if( !cbuf->initialize( BUFFER_SIZE, sizeof(MidiMsg) ) )
        {
            if( !min->m_suppress_output )
                EM_error2( 0, "MidiIn: couldn't allocate CBuffer for port %i...", device_num );
            delete cbuf;
            return FALSE;
        }

        // allocate
        RtMidiIn * rtmin = new RtMidiIn;
        try {
            rtmin->openPort( device_num );
            rtmin->setCallback( cb_midi_input, cbuf );
        } catch( RtError & err ) {
            if( !min->m_suppress_output )
            {
                // print it
                EM_error2( 0, "MidiIn: couldn't open MIDI port %i...", device_num );
                err.getMessage();
                // const char * e = err.getMessage().c_str();
                // EM_error2( 0, "...(%s)", err.getMessage().c_str() );
            }
            delete cbuf;
            return FALSE;
        }

        // resize?
        if( device_num >= (t_CKINT)the_mins.capacity() )
        {
            t_CKINT size = the_mins.capacity() * 2;
            if( device_num >= size ) size = device_num + 1;
            the_mins.resize( size );
            the_bufs.resize( size );
        }

        // put cbuf and rtmin in vector for future generations
        the_mins[device_num] = rtmin;
        the_bufs[device_num] = cbuf;
    }

    // set min
    min->min = the_mins[device_num];
    // found
    min->m_buffer = the_bufs[device_num];
    // get an index into your (you are min here) own buffer, 
    // and a free ticket to your own workshop
    min->m_read_index = min->m_buffer->join( (Chuck_Event *)min->SELF );
    min->m_device_num = (t_CKUINT)device_num;

    // done
    return TRUE;
}
Example #2
0
t_CKBOOL MidiOutManager::open( MidiOut * mout, const std::string & name )
{
    t_CKINT device_num = -1;
    
    try 
    {
        RtMidiOut * rtmout = new RtMidiOut;
        
        t_CKINT count = rtmout->getPortCount();
        for(t_CKINT i = 0; i < count; i++)
        {
            std::string port_name = rtmout->getPortName( i );
            if( port_name == name )
            {
                device_num = i;
                break;
            }
        }
        
        if( device_num == -1 )
        {
            // search by substring
            for(t_CKINT i = 0; i < count; i++)
            {
                std::string port_name = rtmout->getPortName( i );
                if( port_name.find( name ) != std::string::npos )
                {
                    device_num = i;
                    break;
                }
            }
        }
    }
    catch( RtMidiError & err )
    {
        if( !mout->m_suppress_output )
        {
            // print it
            EM_error2( 0, "MidiOut: error locating MIDI port named %s", name.c_str() );
            err.getMessage();
            // const char * e = err.getMessage().c_str();
            // EM_error2( 0, "...(%s)", err.getMessage().c_str() );
        }
        return FALSE;
    }
    
    if(device_num == -1)
    {
        EM_error2( 0, "MidiOut: error locating MIDI port named %s", name.c_str() );
        return FALSE;
    }
    
    t_CKBOOL result = open( mout, device_num );
    
    return result;
}
Example #3
0
t_CKBOOL EM_reset( c_str fname, FILE * fd )
{
    anyErrors = FALSE; fileName = fname ? fname : (c_str)""; lineNum = 1;  EM_lineNum = 1;
    linePos = intList( 0, NULL );

    // if( yyin ) fclose( yyin );
    if( fd ) yyin = fd;
    else yyin = fopen( fname, "r" );
    if (!yyin)
        EM_error2( 0, "no such file or directory" );
    else
        fseek( yyin, 0, SEEK_SET );

    EM_lineNum = 0;
    return (yyin != 0);
}
Example #4
0
//-----------------------------------------------------------------------------
// name: probe()
// desc: ...
//-----------------------------------------------------------------------------
void Digitalio::probe()
{
#ifndef __DISABLE_RTAUDIO__
    RtAudio * rta = NULL;
    RtAudio::DeviceInfo info;
    
    // allocate RtAudio
    try { rta = new RtAudio( ); }
    catch( RtError err )
    {
        // problem finding audio devices, most likely
        EM_error2b( 0, "%s", err.getMessage().c_str() );
        return;
    }

    // get count    
    int devices = rta->getDeviceCount();
    EM_error2b( 0, "found %d device(s) ...", devices );
    // EM_error2( 0, "--------------------------" );
    
    EM_reset_msg();
    
    // loop
    for( int i = 0; i < devices; i++ )
    {
        try { info = rta->getDeviceInfo(i); }
        catch( RtError & error )
        {
            error.printMessage();
            break;
        }
        
        // print
        EM_error2b( 0, "------( audio device: %d )---------------", i+1 );
        print( info );
        // skip
        if( i < devices ) EM_error2( 0, "" );
        
        EM_reset_msg();
    }

    delete rta;
#endif // __DISABLE_RTAUDIO__

    return;
}
Example #5
0
t_CKBOOL MidiOutManager::open( MidiOut * mout, t_CKINT device_num )
{
    // see if port not already open
    if( device_num >= (t_CKINT)the_mouts.capacity() || !the_mouts[device_num] )
    {
        // allocate
        RtMidiOut * rtmout = new RtMidiOut;
        try {
            rtmout->openPort( device_num );
        } catch( RtError & err ) {
            if( !mout->m_suppress_output )
            {
                // print it
                EM_error2( 0, "MidiOut: couldn't open MIDI port %i...", device_num );
                err.getMessage();
                // const char * e = err.getMessage().c_str();
                // EM_error2( 0, "...(%s)", err.getMessage().c_str() );
            }
            return FALSE;
        }

        // resize?
        if( device_num >= (t_CKINT)the_mouts.capacity() )
        {
            t_CKINT size = the_mouts.capacity() * 2;
            if( device_num >= size ) size = device_num + 1;
            the_mouts.resize( size );
        }

        // put rtmout in vector for future generations
        the_mouts[device_num] = rtmout;
    }

    // found (always) (except when it doesn't get here)
    mout->mout = the_mouts[device_num];
    mout->m_device_num = (t_CKUINT)device_num;

    // done
    return TRUE;
}
Example #6
0
//-----------------------------------------------------------------------------
// name: initialize()
// desc: ...
//-----------------------------------------------------------------------------
BOOL__ Digitalio::initialize( DWORD__ num_channels, DWORD__ sampling_rate,
                              DWORD__ bps, DWORD__ buffer_size, 
                              DWORD__ num_buffers )
{
    if( m_init )
        return FALSE;

    m_num_channels_out = num_channels;
    m_num_channels_in = num_channels;
    m_sampling_rate = sampling_rate;
    m_bps = bps;
    m_buffer_size = buffer_size;
    m_num_buffers = num_buffers;
    m_start = 0;
    m_tick_count = 0;
    m_go = 0;
    m_end = 0;

    // allocate RtAudio
    try { m_rtaudio = new RtAudio( ); }
    catch( RtError err )
    {
        // problem finding audio devices, most likely
        EM_error2( 0, "%s", err.getMessageString() );
        return m_init = FALSE;
    }

    // open device
    try {
        m_rtaudio->openStream(
            m_dac_n, m_num_channels_out, m_adc_n, m_num_channels_in,
            RTAUDIO_FLOAT32, sampling_rate,
            (int *)&m_buffer_size, num_buffers );
        if( m_use_cb )
            m_rtaudio->setStreamCallback( &cb, NULL );
    } catch( RtError err ) {
        try {
            m_buffer_size = buffer_size;
            // try output only
            m_rtaudio->openStream(
                m_dac_n, m_num_channels_out, 0, 0,
                RTAUDIO_FLOAT32, sampling_rate,
                (int *)&m_buffer_size, num_buffers );
            if( m_use_cb )
                m_rtaudio->setStreamCallback( &cb, NULL );
        } catch( RtError err ) {
            EM_error2( 0, "%s", err.getMessageString() );
            SAFE_DELETE( m_rtaudio );
            return m_init = FALSE;
        }
    }

    if( m_use_cb )
    {
        m_buffer_in = new SAMPLE[m_buffer_size * num_channels];
        m_buffer_out = new SAMPLE[m_buffer_size * num_channels];
        memset( m_buffer_in, 0, m_buffer_size * sizeof(SAMPLE) * num_channels );
        memset( m_buffer_out, 0, m_buffer_size * sizeof(SAMPLE) * num_channels );
        m_read_ptr = NULL;
        m_write_ptr = NULL;
    }
    
    m_in_ready = FALSE;
    m_out_ready = FALSE;

    return m_init = TRUE;
}
Example #7
0
//-----------------------------------------------------------------------------
// name: initialize()
// desc: ...
//-----------------------------------------------------------------------------
BOOL__ Digitalio::initialize( DWORD__ num_dac_channels,
                              DWORD__ num_adc_channels,
                              DWORD__ sampling_rate,
                              DWORD__ bps, DWORD__ buffer_size, 
                              DWORD__ num_buffers, DWORD__ block,
                              Chuck_VM * vm_ref, BOOL__ rt_audio,
                              void * callback, void * data,
                              BOOL__ force_srate )
{
    if( m_init )
        return FALSE;

    m_num_channels_out = num_dac_channels;
    m_num_channels_in = num_adc_channels;
    m_sampling_rate = sampling_rate;
    m_bps = bps;
    m_buffer_size = buffer_size;
    m_num_buffers = num_buffers;
    m_start = 0;
    m_tick_count = 0;
    m_go = 0;
    m_end = 0;
    m_block = block;

    DWORD__ num_channels;
    unsigned int bufsize = m_buffer_size;

    // log
    EM_log( CK_LOG_FINE, "initializing RtAudio..." );
    // push indent
    EM_pushlog();
        
    // if rt_audio is false, then set block to FALSE to avoid deadlock
    if( !rt_audio ) m_block = FALSE;

#ifndef __DISABLE_RTAUDIO__    
    // if real-time audio
    if( rt_audio )
    {
        // allocate RtAudio
        try { m_rtaudio = new RtAudio( ); }
        catch( RtError err )
        {
            // problem finding audio devices, most likely
            EM_error2( 0, "%s", err.getMessage().c_str() );
            return m_init = FALSE;
        }
        
        // convert 1-based ordinal to 0-based ordinal (added 1.3.0.0)
        // note: this is to preserve previous devices numbering after RtAudio change
        if( m_num_channels_out > 0 )
        {
            // check output device number; 0 used to mean "default"
            bool useDefault = ( m_dac_n == 0 );

            // default (refactor 1.3.1.2)
            if( useDefault )
            {
                // get the default
                m_dac_n = m_rtaudio->getDefaultOutputDevice();
            }
            else
            {
                m_dac_n -= 1;
            }

            // get device info
            RtAudio::DeviceInfo device_info = m_rtaudio->getDeviceInfo(m_dac_n);
                
            // ensure correct channel count if default device is requested
            if( useDefault )
            {
                // check
                if( device_info.outputChannels < m_num_channels_out )
                {
                    // find first device with at least the requested channel count
                    m_dac_n = -1;
                    int num_devices = m_rtaudio->getDeviceCount();
                    for( int i = 0; i < num_devices; i++ )
                    {
                        device_info = m_rtaudio->getDeviceInfo(i);
                        if(device_info.outputChannels >= m_num_channels_out)
                        {
                            m_dac_n = i;
                            break;
                        }
                    }
                    
                    // check for error
                    if( m_dac_n == -1 )
                    {
                        EM_error2( 0, "no audio output device with requested channel count (%i)...", m_num_channels_out );
                        return m_init = FALSE;
                    }
                }
            }

            // index of closest sample rate
            long closestIndex = -1;
            // difference of closest so far
            long closestDiff = LONG_MAX;
            // the next highest
            long nextHighest = -1;
            // diff to next highest so far
            long diffToNextHighest = LONG_MAX;
            // check if request sample rate in support rates (added 1.3.1.2)
            for( long i = 0; i < device_info.sampleRates.size(); i++ )
            {
                // difference
                long diff = device_info.sampleRates[i] - sampling_rate;
                // check // ge: changed from abs to labs, 2015.11
                if( ::labs(diff) < closestDiff )
                {
                    // remember index
                    closestIndex = i;
                    // update diff
                    closestDiff = ::labs(diff);
                }

                // for next highest
                if( diff > 0 && diff < diffToNextHighest )
                {
                    // remember index
                    nextHighest = i;
                    // update diff
                    diffToNextHighest = diff;
                }
            }
            
            // see if we found exact match (added 1.3.1.2)
            if( closestDiff != 0 )
            {
                // check
                if( force_srate )
                {
                    // request sample rate not found, error out
                    EM_error2( 0, "unsupported sample rate (%d) requested...", sampling_rate );
                    EM_error2( 0, "| (try --probe to enumerate available sample rates)" );
                    return m_init = FALSE;
                }

                // use next highest if available
                if( nextHighest >= 0 )
                {
                    // log
                    EM_log( CK_LOG_SEVERE, "new sample rate (next highest): %d -> %d",
                            sampling_rate, device_info.sampleRates[nextHighest] );
                    // update sampling rate
                    m_sampling_rate = sampling_rate = device_info.sampleRates[nextHighest];
                }
                else if( closestIndex >= 0 ) // nothing higher
                {
                    // log
                    EM_log( CK_LOG_SEVERE, "new sample rate (closest): %d -> %d",
                            sampling_rate, device_info.sampleRates[closestIndex] );
                    // update sampling rate
                    m_sampling_rate = sampling_rate = device_info.sampleRates[closestIndex];
                }
                else
                {
                    // nothing to do (will fail and throw error message when opening)
                }
            }
        }
        
        // convert 1-based ordinal to 0-based ordinal
        if( m_num_channels_in > 0 )
        {
            if( m_adc_n == 0 )
            {
                m_adc_n = m_rtaudio->getDefaultInputDevice();
                
                // ensure correct channel count if default device is requested
                RtAudio::DeviceInfo device_info = m_rtaudio->getDeviceInfo(m_adc_n);
                
                // check if input channels > 0
                if( device_info.inputChannels < m_num_channels_in )
                {
                    // find first device with at least the requested channel count
                    m_adc_n = -1;
                    int num_devices = m_rtaudio->getDeviceCount();
                    for(int i = 0; i < num_devices; i++)
                    {
                        device_info = m_rtaudio->getDeviceInfo(i);
                        if(device_info.inputChannels >= m_num_channels_in)
                        {
                            m_adc_n = i;
                            break;
                        }
                    }

                    // changed 1.3.1.2 (ge): for input, if nothing found, we just gonna try to open half-duplex
                    if( m_adc_n == -1 )
                    {
                        // set to 0
                        m_num_channels_in = 0;
                        // problem finding audio devices, most likely
                        // EM_error2( 0, "unable to find audio input device with requested channel count (%i)...", m_num_channels_in);
                        // return m_init = FALSE;
                    }
                }
            }
            else
            {
                m_adc_n -= 1;
            }
        }

        // open device
        try {
            // log
            EM_log( CK_LOG_FINE, "trying %d input %d output...", 
                    m_num_channels_in, m_num_channels_out );
            
            RtAudio::StreamParameters output_parameters;
            output_parameters.deviceId = m_dac_n;
            output_parameters.nChannels = m_num_channels_out;
            output_parameters.firstChannel = 0;
            
            RtAudio::StreamParameters input_parameters;
            input_parameters.deviceId = m_adc_n;
            input_parameters.nChannels = m_num_channels_in;
            input_parameters.firstChannel = 0;
            
            RtAudio::StreamOptions stream_options;
            stream_options.flags = 0;
            stream_options.numberOfBuffers = num_buffers;
            stream_options.streamName = "ChucK";
            stream_options.priority = 0;
            
            // open RtAudio
            m_rtaudio->openStream(
                m_num_channels_out > 0 ? &output_parameters : NULL, 
                m_num_channels_in > 0 ? &input_parameters : NULL,
                CK_RTAUDIO_FORMAT, sampling_rate, &bufsize, 
                m_use_cb ? ( block ? &cb : &cb2 ) : NULL, vm_ref, 
                &stream_options );
        } catch( RtError err ) {
            // log
            EM_log( CK_LOG_INFO, "exception caught: '%s'...", err.getMessage().c_str() );
            EM_error2( 0, "%s", err.getMessage().c_str() );
            SAFE_DELETE( m_rtaudio );
            return m_init = FALSE;
        }
        
        // check bufsize
        if( bufsize != (int)m_buffer_size )
        {
            EM_log( CK_LOG_SEVERE, "new buffer size: %d -> %i", m_buffer_size, bufsize );
            m_buffer_size = bufsize;
        }

        // pop indent
        EM_poplog();
    }
#endif // __DISABLE_RTAUDIO__

#if defined(__CHIP_MODE__)
    if( !MoAudio::init( sampling_rate, buffer_size, 2 ) )
    {
        EM_error2( 0, "%s", "(chuck)error: unable to initialize MoAudio..." );
        return m_init = FALSE;
    }
#endif // __CHIP_MODE__

    if( m_use_cb )
    {
        num_channels = num_dac_channels > num_adc_channels ? 
                       num_dac_channels : num_adc_channels;
        // log
        EM_log( CK_LOG_SEVERE, "allocating buffers for %d x %d samples...",
                m_buffer_size, num_channels );
        // allocate buffers
        m_buffer_in = new SAMPLE[m_buffer_size * num_channels];
        m_buffer_out = new SAMPLE[m_buffer_size * num_channels];
        memset( m_buffer_in, 0, m_buffer_size * sizeof(SAMPLE) * num_channels );
        memset( m_buffer_out, 0, m_buffer_size * sizeof(SAMPLE) * num_channels );
        m_read_ptr = NULL;
        m_write_ptr = NULL;
    }
    
    m_in_ready = FALSE;
    m_out_ready = FALSE;

    return m_init = TRUE;
}