void Ambix_converterAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    // do the audio processing....
    // defines are until 10th order 3d (121 channels)!
    
    // resize output buffer if necessare
    int NumSamples = buffer.getNumSamples();
    
    output_buffer.setSize(std::max(getNumOutputChannels(), getNumInputChannels()), NumSamples);
  
    output_buffer.clear(); // in case of 2d where we might throw away some channels
    
    // std::cout << "NumInputChannels: " << getNumInputChannels() << " Buffersize: " << buffer.getNumChannels() << std::endl;
    
    for (int i = 0; i < getNumInputChannels(); i++) // iterate over acn channel numbering
    {
        
        int l = 0; // sometimes called n
        int m = 0; // -l...l
        
        ACNtoLM(i, l, m);
        
        
        int _in_ch_seq = in_ch_seq[i];
        int _out_ch_seq = out_ch_seq[i];
        
        if (in_2d)
        {
            _in_ch_seq = in_2d_ch_seq[ACN3DtoACN2D(i)];
            if (_in_ch_seq > getNumInputChannels())
                _in_ch_seq = -1;
        }
        
        if (out_2d)
        {
            _out_ch_seq = out_2d_ch_seq[ACN3DtoACN2D(i)];
            if (_out_ch_seq > getNumOutputChannels())
                _out_ch_seq = -1;
        }
        
        
        // std::cout << "InputCh: " << i << " IN_CHANNEL: " << _in_ch_seq << " OUT_CHANNEL: " << _out_ch_seq << std::endl;
        
        if (_in_ch_seq != -1 && _out_ch_seq != -1 && _in_ch_seq < getNumInputChannels())
        {
            // copy input channels to output channels!
            output_buffer.copyFrom(_out_ch_seq, 0, buffer, _in_ch_seq, 0, NumSamples);
            
            //  apply normalization conversion gain if different input/output scheme
            if (!ch_norm_flat) {
                output_buffer.applyGain(_out_ch_seq, 0, NumSamples, in_ch_norm[i]);
            }
            
            // do the inversions...
            if (flip_cs_phase || flip_param || flop_param || flap_param)
            {
                
                
                signed int flip, flop, flap, total;
                flip = flop = flap = total = 1;
                
                // taken from paper Symmetries of Spherical Harmonics by Michael Chapman (Ambi Symp 2009),
                
                // mirror left right
                if ( flip_param && (m < 0) ) // m < 0 -> invert
                    flip = -1;
                
                // mirror front back
                if ( flop_param && ( ((m < 0) && !(m % 2)) || ((m >= 0) && (m % 2)) ) ) // m < 0 and even || m >= 0 and odd
                    flop = -1;
                
                // mirror top bottom
                if ( flap_param && ( (l + m) % 2 ) ) // l+m odd   ( (odd, even) or (even, odd) )
                    flap = -1;
                
                // compute total multiplicator
                if (flip_cs_phase)
                    total = acn_cs[i] * flip * flop * flap;
                else
                    total = flip * flop * flap;
                
                output_buffer.applyGain(_out_ch_seq, 0, NumSamples, (float)total);
            }
        } // index not -1
        
    } // iterate over all input channels
    
    
    // In case we have more outputs than inputs, we'll clear any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    /*
    for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
    {
        output_buffer.clear (i, 0, buffer.getNumSamples());
    }
    */
    
    buffer = output_buffer;
}
Exemple #2
0
void Ambix_wideningAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    // backup old coefficients
    memcpy(_cos_coeffs, cos_coeffs, sizeof(float)*AMBI_ORDER*(BESSEL_APPR+1));
    memcpy(_sin_coeffs, sin_coeffs, sizeof(float)*AMBI_ORDER*(BESSEL_APPR+1));
  
  
    // calc new coefficients
    calcParams();
    
    //////////////////////
    // write to the buffer
    if (_buf_write_pos + buffer.getNumSamples() < _buf_size)
    {
        for (int ch = 0; ch < buffer.getNumChannels(); ch++)
        {
            // copy straight into buffer
            ring_buffer.copyFrom(ch, _buf_write_pos, buffer, ch, 0, buffer.getNumSamples());
        }
        // update write position
        _buf_write_pos += buffer.getNumSamples();
        
    } else { // if buffer reaches end
        
        int samples_to_write1 = _buf_size - _buf_write_pos;
        int samples_to_write2 = buffer.getNumSamples() - samples_to_write1;
        
        // std::cout << "spl_write1: " << samples_to_write1 << " spl_write2: " << samples_to_write2 << std::endl;
        
        for (int ch = 0; ch < buffer.getNumChannels(); ch++)
        {
            
            // copy until end
            ring_buffer.copyFrom(ch, _buf_write_pos, buffer, ch, 0, samples_to_write1);
            
            
            // start copy to front
            ring_buffer.copyFrom(ch, 0, buffer, ch, samples_to_write1, samples_to_write2);
        }
        // update write position
        _buf_write_pos = samples_to_write2;
    }
    
    
    // String debug = String::empty;
    
    /////////////////////////
    // compute read positions (tap delay times)
    // Q is computed in calcParams() (SampleRate dependent)
    
    for (int i=0; i < BESSEL_APPR*2+1; i++) {
        _buf_read_pos[i] = _buf_write_pos - i*Q - buffer.getNumSamples();
        if (_buf_read_pos[i] < 0)
            _buf_read_pos[i] = _buf_size + _buf_read_pos[i]; // -1 ?
        
        // debug << _buf_read_pos[i] << " ";
    }
    
    // std::cout << "read pos: " << debug << std::endl;
    
    /////////////////////////
    // do the rotation
    buffer.clear();
    
    int fir_length = 2*BESSEL_APPR+1;
    
    if (single_sided)
        fir_length = BESSEL_APPR+1;
    
    for (int acn_out = 0; acn_out < getTotalNumOutputChannels(); acn_out++) // iterate over output channels
    {
        int l_out = 0;
        int m_out = 0;
        
        ACNtoLM(acn_out, l_out, m_out);
        
        for (int acn_in = 0; acn_in < getTotalNumInputChannels(); acn_in++) // iterate over input channels
        {
            int l_in=0; // degree 0, 1, 2, 3, 4, ...
            int m_in=0; // order ..., -2, -1, 0 , 1, 2, ...
            
            ACNtoLM(acn_in, l_in, m_in);
            
            if (abs(m_out) == abs (m_in) && l_in == l_out) { // if degree and order match do something
                
                int pos_index = 0; // index of _buf_read_pos
                
                ///////////////
                // pass through terms (z symmetric, m=0)
                if (m_out == 0 && m_in == 0) {
                    
                    if (!single_sided)
                        pos_index = BESSEL_APPR;
                    
                    // read from buffer
                    if (_buf_read_pos[pos_index] + buffer.getNumSamples() < _buf_size)
                    {
                        buffer.copyFrom(acn_out, 0, ring_buffer, acn_out, _buf_read_pos[pos_index], buffer.getNumSamples());
                    } else {
                        
                        int samples_to_read1 = _buf_size - _buf_read_pos[pos_index];
                        int samples_to_read2 = buffer.getNumSamples() - samples_to_read1;
                        
                        // copy until end
                        buffer.copyFrom(acn_out, 0, ring_buffer, acn_out, _buf_read_pos[pos_index], samples_to_read1);
                        
                        // start copy from front
                        buffer.copyFrom(acn_out, samples_to_read1, ring_buffer, acn_out, 0, samples_to_read2);
                    }
                    
                }
                ///////////////
                // cosine terms
                else  if (m_in < 0 && m_out < 0) // cosine
                {
                    
                    for (int i=0; i < fir_length; i++) { // ITERATE BESSEL APPR
                        
                        int j = abs(i-BESSEL_APPR);
                        if (single_sided)
                            j=i;
                        
                        float _coeff = _cos_coeffs[l_in-1][j];
                        float coeff = cos_coeffs[l_in-1][j];
                        
                        if (coeff != 0.f) { // skip zero coefficients
                            
                            // read from buffer
                            if (_buf_read_pos[i] + buffer.getNumSamples() < _buf_size)
                            {
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), buffer.getNumSamples(), _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], buffer.getNumSamples(), coeff);

                            } else {
                                
                                int samples_to_read1 = _buf_size - _buf_read_pos[i];
                                int samples_to_read2 = buffer.getNumSamples() - samples_to_read1;
                                
                                // copy until end
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), samples_to_read1, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], samples_to_read1, coeff);

                                
                                // start copy from front
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, samples_to_read1, ring_buffer.getReadPointer(acn_in, 0), samples_to_read2, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, samples_to_read1, ring_buffer, acn_in, 0, samples_to_read2, coeff);

                            }
                        }
                        
                    } // end iterate BESSEL_APPR
                }
                
                ///////////////
                // -sine terms
                else  if (m_in < 0 && m_out > 0) // -sine
                {
                    for (int i=0; i < fir_length; i++) { // ITERATE BESSEL APPR
                        
                        int j = abs(i-BESSEL_APPR);
                        if (single_sided)
                            j=i;
                        
                        float _coeff = -_sin_coeffs[l_in-1][j];
                        float coeff = -sin_coeffs[l_in-1][j];
                        
                        if (coeff != 0.f) { // skip zero coefficients
                            
                            // read from buffer
                            if (_buf_read_pos[i] + buffer.getNumSamples() < _buf_size)
                            {
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), buffer.getNumSamples(), _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], buffer.getNumSamples(), coeff);
                                
                            } else {
                                
                                int samples_to_read1 = _buf_size - _buf_read_pos[i];
                                int samples_to_read2 = buffer.getNumSamples() - samples_to_read1;
                                
                                // copy until end
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), samples_to_read1, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], samples_to_read1, coeff);
                                
                                
                                // start copy from front
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, samples_to_read1, ring_buffer.getReadPointer(acn_in, 0), samples_to_read2, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, samples_to_read1, ring_buffer, acn_in, 0, samples_to_read2, coeff);
                                
                            }
                        }
                        
                    } // end iterate BESSEL_APPR
                }
                
                ///////////////
                // cosine terms
                else  if (m_in > 0 && m_out > 0) // cosine
                {
                    for (int i=0; i < fir_length; i++) { // ITERATE BESSEL APPR
                        
                        int j = abs(i-BESSEL_APPR);
                        if (single_sided)
                            j=i;
                        
                        float _coeff = _cos_coeffs[l_in-1][j];
                        float coeff = cos_coeffs[l_in-1][j];
                        
                        if (coeff != 0.f) { // skip zero coefficients
                            
                            // read from buffer
                            if (_buf_read_pos[i] + buffer.getNumSamples() < _buf_size)
                            {
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), buffer.getNumSamples(), _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], buffer.getNumSamples(), coeff);
                                
                            } else {
                                
                                int samples_to_read1 = _buf_size - _buf_read_pos[i];
                                int samples_to_read2 = buffer.getNumSamples() - samples_to_read1;
                                
                                // copy until end
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), samples_to_read1, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], samples_to_read1, coeff);
                                
                                
                                // start copy from front
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, samples_to_read1, ring_buffer.getReadPointer(acn_in, 0), samples_to_read2, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, samples_to_read1, ring_buffer, acn_in, 0, samples_to_read2, coeff);
                                
                            }
                        }
                        
                    } // end iterate BESSEL_APPR
                }
                
                ///////////////
                // sine terms
                else  if (m_in > 0 && m_out < 0) // sine
                {
                    for (int i=0; i < fir_length; i++) { // ITERATE BESSEL APPR
                        
                        int j = abs(i-BESSEL_APPR);
                        if (single_sided)
                            j=i;
                        
                        float _coeff = _sin_coeffs[l_in-1][j];
                        float coeff = sin_coeffs[l_in-1][j];
                        
                        if (coeff != 0.f) { // skip zero coefficients
                            
                            // read from buffer
                            if (_buf_read_pos[i] + buffer.getNumSamples() < _buf_size)
                            {
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), buffer.getNumSamples(), _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], buffer.getNumSamples(), coeff);
                                
                            } else {
                                
                                int samples_to_read1 = _buf_size - _buf_read_pos[i];
                                int samples_to_read2 = buffer.getNumSamples() - samples_to_read1;
                                
                                // copy until end
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, 0, ring_buffer.getReadPointer(acn_in, _buf_read_pos[i]), samples_to_read1, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, 0, ring_buffer, acn_in, _buf_read_pos[i], samples_to_read1, coeff);
                                
                                
                                // start copy from front
                                if (_coeff != coeff) // interpolate?
                                    buffer.addFromWithRamp(acn_out, samples_to_read1, ring_buffer.getReadPointer(acn_in, 0), samples_to_read2, _coeff, coeff);
                                else
                                    buffer.addFrom(acn_out, samples_to_read1, ring_buffer, acn_in, 0, samples_to_read2, coeff);
                                
                            }
                        }
                        
                    } // end iterate BESSEL_APPR
                }
                
            }
            
        }
        
    }
    
}
Exemple #3
0
void Ambix_mirrorAudioProcessor::calcParams()
{
    for (int i=0; i < gain_factors.size(); i++) {
        gain_factors.set(i, 1.f);
    }
    
    for (int acn = 0; acn < AMBI_CHANNELS; acn++)
    {
        
        float* g = &gain_factors.getReference(acn);
        
        int l = 0; // manchmal auch n
        int m = 0;
        
        ACNtoLM(acn, l, m);
        
        ///////////////
        // Z SYMMETRY
        // z even symmetry
        if (acn == 0)
        {
            *g *= ParamToRMS(z_even_param);
            
            if (z_even_inv_param >= 0.5)
                *g *= -1;
        }
        // (l odd, m odd) || (l even, m even)
        // same as (l+m) even
        else if ( !((l + m) % 2) )
        //else if ( ((l % 2) && (m % 2)) || (!(l % 2) && !(m % 2)) )
        {
            *g *= ParamToRMS(z_even_param);
            
            if (z_even_inv_param >= 0.5)
                *g *= -1;
        }
        
        // z odd symmetry
        if (acn == 0)
        {
            // do nothing
        }
        // (l odd, m even) || (l even, m odd)
        // same as (l+m) odd
        else if ( ((l + m) % 2) )
        //else if ( ((l % 2) && !(m % 2)) ||  (!(l % 2) && (m % 2)))
        {
            *g *= ParamToRMS(z_odd_param);
            
            if (z_odd_inv_param >= 0.5)
                *g *= -1;
        }
        
        /////////////////
        // Y SYMMETRY
        // y even symmetry
        if (m >= 0)
        {
            *g *= ParamToRMS(y_even_param);
            
            if (y_even_inv_param >= 0.5)
                *g *= -1;
        }
        // y odd symmetry
        if (m < 0)
        {
            *g *= ParamToRMS(y_odd_param);
            
            if (y_odd_inv_param >= 0.5)
                *g *= -1;
        }
        
        
        /////////////////
        // X SYMMETRY
        // x even symmetry
        // m < 0 and odd || m >= 0 and even
        if ( ((m < 0) && (m % 2)) || ((m >= 0) && !(m % 2)) )
        {
            *g *= ParamToRMS(x_even_param);
            
            if (x_even_inv_param >= 0.5)
                *g *= -1;
        }
        // x odd symmetry
        // m < 0 and even || m >= 0 and odd
        if ( ((m < 0) && !(m % 2)) || ((m >= 0) && (m % 2)) )
        {
            *g *= ParamToRMS(x_odd_param);
            
            if (x_odd_inv_param >= 0.5)
                *g *= -1;
        }
        
        /////////////////
        // BOOST 2D (RING)
        
        if (l == m || l == -m)
        {
            *g *= ParamToRMS(circular_param);
            
            if (circular_inv_param >= 0.5)
                *g *= -1;
        }
    }
}
Exemple #4
0
void Ambix_rotator_zAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    
    int NumSamples = buffer.getNumSamples();
    
    // resize buffer if necessary
    output_buffer.setSize((std::max)(getNumOutputChannels(), getNumInputChannels()), NumSamples);
    
    // clear output buffer
    output_buffer.clear();
    
    // save old parameters for interpolation (start ramp)
    _cos_z = cos_z;
    _sin_z = sin_z;
    
    // calculate new parameters (end ramp)
    calcParams();
    
    
    // iterate over input and output channels for z axis rotation
    // this should work for arbitary ambisonics orders!
    
    for (int acn_out = 0; acn_out < getNumOutputChannels(); acn_out++)
    {
        int l_out = 0;
        int m_out = 0;
        
        ACNtoLM(acn_out, l_out, m_out);
        
        for (int acn_in = 0; acn_in < getNumInputChannels(); acn_in++)
        {
            int l_in=0; // degree 0, 1, 2, 3, 4, ......
            int m_in=0; // order ...., -2, -1, 0 , 1, 2, ...
            
            ACNtoLM(acn_in, l_in, m_in);
            
            if (abs(m_out) == abs (m_in) && l_in == l_out) { // if degree and order match  do something
                
                if (m_out == 0 && m_in == 0) {
                    // gain 1 -> no interpolation needed
                    output_buffer.copyFrom(acn_out, 0, buffer, acn_in, 0, NumSamples);
                }
                else  if (m_in < 0 && m_out < 0)
                {
                    output_buffer.addFromWithRamp(acn_out, 0, buffer.getReadPointer(acn_in), NumSamples, _cos_z[-m_out], cos_z[-m_out]); // interpolation with ramp done by juce
                }
                else  if (m_in < 0 && m_out > 0)
                {
                    output_buffer.addFromWithRamp(acn_out, 0, buffer.getReadPointer(acn_in), NumSamples, -_sin_z[m_out], -sin_z[m_out]);
                }
                else  if (m_in > 0 && m_out > 0)
                {
                    output_buffer.addFromWithRamp(acn_out, 0, buffer.getReadPointer(acn_in), NumSamples, _cos_z[m_out], cos_z[m_out]);
                }
                else  if (m_in > 0 && m_out < 0)
                {
                    output_buffer.addFromWithRamp(acn_out, 0, buffer.getReadPointer(acn_in), NumSamples, _sin_z[m_in], sin_z[m_in]);
                }
                
            }
            
        }
        
    }
    
    // return output buffer
    buffer = output_buffer;
}