static int Init( vlc_object_t *p_this, struct filter_sys_t * p_data, unsigned int i_nb_channels, uint32_t i_physical_channels, unsigned int i_rate ) { double d_x = var_InheritInteger( p_this, "headphone-dim" ); double d_z = d_x; double d_z_rear = -d_x/3; double d_min = 0; unsigned int i_next_atomic_operation; int i_source_channel_offset; unsigned int i; if( var_InheritBool( p_this, "headphone-compensate" ) ) { /* minimal distance to any speaker */ if( i_physical_channels & AOUT_CHAN_REARCENTER ) { d_min = d_z_rear; } else { d_min = d_z; } } /* Number of elementary operations */ p_data->i_nb_atomic_operations = i_nb_channels * 2; if( i_physical_channels & AOUT_CHAN_CENTER ) { p_data->i_nb_atomic_operations += 2; } p_data->p_atomic_operations = (atomic_operation_t *)malloc( sizeof(struct atomic_operation_t) * p_data->i_nb_atomic_operations ); // sunqueen modify if( p_data->p_atomic_operations == NULL ) return -1; /* For each virtual speaker, computes elementary wave propagation time * to each ear */ i_next_atomic_operation = 0; i_source_channel_offset = 0; if( i_physical_channels & AOUT_CHAN_LEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z , d_min , 2.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_RIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , d_z , d_min , 2.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_MIDDLELEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , 0 , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_MIDDLERIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , 0 , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARLEFT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARRIGHT ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x , d_z_rear , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_REARCENTER ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , 0 , -d_z , d_min , 1.5 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_CENTER ) { /* having two center channels increases the spatialization effect */ ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); i_next_atomic_operation += 2; ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , -d_x / 5.0 , d_z , d_min , 0.75 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } if( i_physical_channels & AOUT_CHAN_LFE ) { ComputeChannelOperations( p_data , i_rate , i_next_atomic_operation , i_source_channel_offset , 0 , d_z_rear , d_min , 5.0 / i_nb_channels ); i_next_atomic_operation += 2; i_source_channel_offset++; } /* Initialize the overflow buffer * we need it because the process induce a delay in the samples */ p_data->i_overflow_buffer_size = 0; for( i = 0 ; i < p_data->i_nb_atomic_operations ; i++ ) { if( p_data->i_overflow_buffer_size < p_data->p_atomic_operations[i].i_delay * 2 * sizeof (int16_t) ) { p_data->i_overflow_buffer_size = p_data->p_atomic_operations[i].i_delay * 2 * sizeof (int16_t); } } p_data->p_overflow_buffer = (uint8_t *)malloc( p_data->i_overflow_buffer_size ); // sunqueen modify if( p_data->p_overflow_buffer == NULL ) { free( p_data->p_atomic_operations ); return -1; } memset( p_data->p_overflow_buffer, 0, p_data->i_overflow_buffer_size ); /* end */ return 0; }
int TaudioFilterHeadphone::aout_filter_sys_t::Init(const TsampleFormat &fmt,const TmixerSettings *cfg) { double d_x = cfg->headphone_dim;//config_GetInt ( p_filter , "headphone-dim" ); double d_z = d_x; double d_z_rear = -d_x/3; unsigned int i_next_atomic_operation; int i_source_channel_offset; /* Number of elementary operations */ i_nb_atomic_operations = fmt.nchannels * 2; p_atomic_operations = (atomic_operation_t*)malloc ( sizeof(atomic_operation_t) * i_nb_atomic_operations ); /* For each virtual speaker, computes elementary wave propagation time * to each ear */ i_next_atomic_operation = 0; i_source_channel_offset = 0; for (unsigned int ch=0; ch<fmt.nchannels; ch++) if ( fmt.speakers[ch] == SPEAKER_FRONT_LEFT) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z , 2.0 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_FRONT_RIGHT ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , d_x , d_z , 2.0 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_BACK_LEFT ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , -d_x , d_z_rear , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_BACK_RIGHT ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , d_x , d_z_rear , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_BACK_CENTER ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , 0 , -d_z , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_FRONT_CENTER ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , 0 , d_z , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_LOW_FREQUENCY ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , 0 , d_z_rear , 5.0 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_SIDE_LEFT ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , -d_x , 0 , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } else if ( fmt.speakers[ch] == SPEAKER_SIDE_RIGHT ) { ComputeChannelOperations ( fmt.freq , i_next_atomic_operation , i_source_channel_offset , d_x , 0 , 1.5 / fmt.nchannels ); i_next_atomic_operation += 2; i_source_channel_offset++; } /* Initialize the overflow buffer * we need it because the process induce a delay in the samples */ i_overflow_buffer_size = 0; for (unsigned int i= 0 ; i < i_nb_atomic_operations ; i++ ) { if ( i_overflow_buffer_size < p_atomic_operations[i].i_delay * ((fmt.nchannels >= 2) ? fmt.nchannels : 2) * sizeof (float) ) { i_overflow_buffer_size = p_atomic_operations[i].i_delay * ((fmt.nchannels >= 2) ? fmt.nchannels : 2) * sizeof (float); } } p_overflow_buffer = (byte_t*)malloc ( i_overflow_buffer_size ); memset ( p_overflow_buffer , 0 , i_overflow_buffer_size ); /* end */ return 0; }