Add wasm tacle-bench targets
This commit is contained in:
585
targets/wasm-tacle/sequential/audiobeam/audiobeam.c
Executable file
585
targets/wasm-tacle/sequential/audiobeam/audiobeam.c
Executable file
@ -0,0 +1,585 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeam
|
||||
|
||||
Author: Eugene Weinstein
|
||||
|
||||
Function: Audio beam former
|
||||
|
||||
Source: StreamIt
|
||||
http://groups.csail.mit.edu/cag/streamit/
|
||||
|
||||
Changes: no functional changes
|
||||
|
||||
License: see license.txt
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Include section
|
||||
*/
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmalloc.h"
|
||||
#include "audiobeam.h"
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
void audiobeam_init();
|
||||
int audiobeam_return();
|
||||
void audiobeam_main( void );
|
||||
int main( void );
|
||||
void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays
|
||||
prep_delays[ ], float *delays );
|
||||
float *audiobeam_parse_line( float *float_arr, int num_mic );
|
||||
long int audiobeam_find_max_in_arr( float *arr, int size );
|
||||
long int audiobeam_find_min_in_arr( float *arr, int size );
|
||||
int audiobeam_wrapped_inc_offset( int i, int offset, int max_i );
|
||||
int audiobeam_wrapped_dec_offset( int i, int offset, int max_i );
|
||||
int audiobeam_wrapped_inc( int i, int max_i );
|
||||
int audiobeam_wrapped_dec( int i, int max_i );
|
||||
struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay,
|
||||
int num_mic );
|
||||
struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic );
|
||||
void audiobeam_calc_distances( float *source_location,
|
||||
float audiobeam_mic_locations[ 15 ][ 3 ],
|
||||
float *distances,
|
||||
int num_mic );
|
||||
void audiobeam_calc_delays( float *distances, float *delays, int sound_speed,
|
||||
int sampling_rate, int num_mic );
|
||||
void audiobeam_adjust_delays( float *delays, int num_mic );
|
||||
float *audiobeam_calc_weights_lr ( int num_mic );
|
||||
float *audiobeam_calc_weights_left_only ( int num_mic );
|
||||
float audiobeam_calculate_energy( float *samples, int num_samples );
|
||||
float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays
|
||||
preprocessed_delays[ ],
|
||||
float **sample_queue,
|
||||
int queue_head,
|
||||
long int max_delay,
|
||||
int num_mic,
|
||||
float *weights );
|
||||
int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic,
|
||||
float sampling_rate, float **beamform_results,
|
||||
struct audiobeam_DataQueue *queue,
|
||||
int num_beams, int window, float *weights );
|
||||
int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays,
|
||||
float **beamform_results,
|
||||
float *energies,
|
||||
struct audiobeam_DataQueue *queue,
|
||||
int num_beams, int window,
|
||||
int hamming );
|
||||
void audiobeam_calc_single_pos( float source_location[ 3 ],
|
||||
float audiobeam_mic_locations[ 15 ][ 3 ],
|
||||
int hamming );
|
||||
|
||||
|
||||
/*
|
||||
Declaration of global variables
|
||||
*/
|
||||
|
||||
extern float audiobeam_input[ 5760 ];
|
||||
extern float audiobeam_mic_locations[ 15 ][ 3 ];
|
||||
extern float audiobeam_source_location[ 3 ];
|
||||
extern float audiobeam_origin_location[ 3 ];
|
||||
int audiobeam_input_pos;
|
||||
int audiobeam_checksum;
|
||||
|
||||
|
||||
/*
|
||||
Initialization- and return-value-related functions
|
||||
*/
|
||||
|
||||
void audiobeam_init()
|
||||
{
|
||||
audiobeam_input_pos = 0;
|
||||
audiobeam_checksum = 0;
|
||||
|
||||
unsigned int i;
|
||||
unsigned char *p;
|
||||
volatile char bitmask = 0;
|
||||
|
||||
/*
|
||||
Apply volatile XOR-bitmask to entire input array.
|
||||
*/
|
||||
p = ( unsigned char * ) &audiobeam_input[ 0 ];
|
||||
_Pragma( "loopbound min 23040 max 23040" )
|
||||
for ( i = 0; i < sizeof( audiobeam_input ); ++i, ++p )
|
||||
*p ^= bitmask;
|
||||
|
||||
p = ( unsigned char * ) &audiobeam_mic_locations[ 0 ];
|
||||
_Pragma( "loopbound min 180 max 180" )
|
||||
for ( i = 0; i < sizeof( audiobeam_mic_locations ); ++i, ++p )
|
||||
*p ^= bitmask;
|
||||
|
||||
p = ( unsigned char * ) &audiobeam_source_location[ 0 ];
|
||||
_Pragma( "loopbound min 12 max 12" )
|
||||
for ( i = 0; i < sizeof( audiobeam_source_location ); ++i, ++p )
|
||||
*p ^= bitmask;
|
||||
|
||||
p = ( unsigned char * ) &audiobeam_origin_location[ 0 ];
|
||||
_Pragma( "loopbound min 12 max 12" )
|
||||
for ( i = 0; i < sizeof( audiobeam_origin_location ); ++i, ++p )
|
||||
*p ^= bitmask;
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_return()
|
||||
{
|
||||
return ( audiobeam_checksum + 1 != 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Algorithm core functions
|
||||
*/
|
||||
|
||||
void audiobeam_preprocess_delays( struct audiobeam_PreprocessedDelays
|
||||
prep_delays[ ], float *delays )
|
||||
{
|
||||
int i;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < 15; i++ ) {
|
||||
prep_delays[ i ].delay = delays[ i ];
|
||||
prep_delays[ i ].high = ( int ) audiobeam_ceil( delays[ i ] );
|
||||
prep_delays[ i ].low = ( int ) audiobeam_floor( delays[ i ] );
|
||||
prep_delays[ i ].offset = delays[ i ] - prep_delays[ i ].low;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float *audiobeam_parse_line( float *float_arr, int num_mic )
|
||||
{
|
||||
int i;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < num_mic; i++ )
|
||||
float_arr[ i ] = audiobeam_input[ audiobeam_input_pos++ ];
|
||||
|
||||
return float_arr;
|
||||
}
|
||||
|
||||
|
||||
long int audiobeam_find_max_in_arr( float *arr, int size )
|
||||
{
|
||||
int i;
|
||||
float max = 0;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
if ( arr[ i ] > max )
|
||||
max = arr[ i ];
|
||||
}
|
||||
|
||||
return audiobeam_ceil( max );
|
||||
}
|
||||
|
||||
|
||||
long int audiobeam_find_min_in_arr( float *arr, int size )
|
||||
{
|
||||
int i;
|
||||
float min = arr[ 0 ];
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
if ( arr[ i ] < min )
|
||||
min = arr[ i ];
|
||||
}
|
||||
|
||||
return audiobeam_floor( min );
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_wrapped_inc_offset( int i, int offset, int max_i )
|
||||
{
|
||||
if ( i + offset > max_i )
|
||||
return ( i + offset - max_i - 1 );
|
||||
else
|
||||
return ( i + offset );
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_wrapped_dec_offset( int i, int offset, int max_i )
|
||||
{
|
||||
if ( i - offset < 0 )
|
||||
return ( max_i - ( offset - i ) + 1 );
|
||||
else
|
||||
return ( i - offset );
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_wrapped_inc( int i, int max_i )
|
||||
{
|
||||
return audiobeam_wrapped_inc_offset( i, 1, max_i );
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_wrapped_dec( int i, int max_i )
|
||||
{
|
||||
return audiobeam_wrapped_dec_offset( i, 1, max_i );
|
||||
}
|
||||
|
||||
|
||||
struct audiobeam_DataQueue *audiobeam_init_data_queue( int max_delay,
|
||||
int num_mic )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
struct audiobeam_DataQueue *queue;
|
||||
queue = ( struct audiobeam_DataQueue * ) audiobeam_malloc( sizeof(
|
||||
struct audiobeam_DataQueue ) );
|
||||
queue->sample_queue = ( float ** ) audiobeam_malloc( ( max_delay + 1 )
|
||||
* sizeof( float * ) );
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < ( max_delay + 1 ); i++ ) {
|
||||
( queue->sample_queue )[ i ] = ( float * ) audiobeam_malloc( num_mic
|
||||
* sizeof( float ) );
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( j = 0; j < num_mic; j++ ) {
|
||||
( queue->sample_queue )[ i ][ j ] = 0.0; // Initialize values to 0
|
||||
}
|
||||
}
|
||||
|
||||
queue->head = 0;
|
||||
queue->tail = 0;
|
||||
queue->full = 0;
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
|
||||
struct audiobeam_Delays *audiobeam_init_delays ( int num_angles, int num_mic )
|
||||
{
|
||||
struct audiobeam_Delays *delays;
|
||||
int i;
|
||||
|
||||
delays = ( struct audiobeam_Delays * ) audiobeam_malloc( sizeof(
|
||||
struct audiobeam_Delays ) );
|
||||
|
||||
// Initialize the delays array
|
||||
delays->delay_values = ( float ** ) audiobeam_malloc( num_angles
|
||||
* sizeof( float * ) );
|
||||
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
for ( i = 0; i < ( num_angles ); i++ ) {
|
||||
delays->delay_values[ i ] = ( float * ) audiobeam_malloc( num_mic
|
||||
* sizeof( float ) );
|
||||
}
|
||||
|
||||
return delays;
|
||||
}
|
||||
|
||||
void audiobeam_calc_distances( float *source_location,
|
||||
float audiobeam_mic_locations[ 15 ][ 3 ],
|
||||
float *distances,
|
||||
int num_mic )
|
||||
{
|
||||
int i;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < num_mic; i++ ) {
|
||||
distances[ i ] = ( audiobeam_sqrt( ( audiobeam_mic_locations[ i ][ 0 ]
|
||||
- source_location[ 0 ] ) *
|
||||
( audiobeam_mic_locations[ i ][ 0 ]
|
||||
- source_location[ 0 ] ) +
|
||||
( audiobeam_mic_locations[ i ][ 1 ]
|
||||
- source_location[ 1 ] ) *
|
||||
( audiobeam_mic_locations[ i ][ 1 ]
|
||||
- source_location[ 1 ] ) +
|
||||
( audiobeam_mic_locations[ i ][ 2 ]
|
||||
- source_location[ 2 ] ) *
|
||||
( audiobeam_mic_locations[ i ][ 2 ]
|
||||
- source_location[ 2 ] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void audiobeam_calc_delays( float *distances, float *delays, int sound_speed,
|
||||
int sampling_rate, int num_mic )
|
||||
{
|
||||
int i;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < num_mic; i++ )
|
||||
delays[ i ] = ( distances[ i ] / sound_speed ) * sampling_rate;
|
||||
}
|
||||
|
||||
|
||||
void audiobeam_adjust_delays( float *delays, int num_mic )
|
||||
{
|
||||
int i;
|
||||
long int min_delay = audiobeam_find_min_in_arr ( delays, num_mic ) - 1;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < num_mic; i++ )
|
||||
delays[ i ] -= min_delay;
|
||||
}
|
||||
|
||||
|
||||
float *audiobeam_calc_weights_lr ( int num_mic )
|
||||
{
|
||||
float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) );
|
||||
int index = 0;
|
||||
int y, z;
|
||||
|
||||
int half = num_mic / 4;
|
||||
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
for ( z = 1; z >= -1; z -= 2 ) {
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
for ( y = 0; y < half; y++ ) {
|
||||
weights[ index ] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y
|
||||
/ half );
|
||||
index++;
|
||||
}
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
for ( y = 0; y < half; y++ ) {
|
||||
weights[ index ] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * ( -y )
|
||||
/ half );
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
|
||||
float *audiobeam_calc_weights_left_only ( int num_mic )
|
||||
{
|
||||
float *weights = ( float * ) audiobeam_malloc( num_mic * sizeof( float ) );
|
||||
int index = 0;
|
||||
int y;
|
||||
|
||||
int half = num_mic / 2;
|
||||
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( y = -half; y <= half; y++ ) {
|
||||
weights[ index ] = 0.54 + 0.46 * audiobeam_cos( audiobeam_M_PI * y / half );
|
||||
index++;
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam_calculate_energy( float *samples, int num_samples )
|
||||
{
|
||||
int i;
|
||||
float sum = 0.0;
|
||||
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
for ( i = 0; i < num_samples; i++ )
|
||||
sum += ( samples[ i ] * samples[ i ] );
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam_do_beamforming( struct audiobeam_PreprocessedDelays
|
||||
preprocessed_delays[ ],
|
||||
float **sample_queue,
|
||||
int queue_head,
|
||||
long int max_delay,
|
||||
int num_mic,
|
||||
float *weights )
|
||||
{
|
||||
int i;
|
||||
float sum = 0;
|
||||
int delay_floor;
|
||||
int delay_ceil;
|
||||
int low_index;
|
||||
int high_index;
|
||||
float interpolated_value;
|
||||
|
||||
// add up all the num_mic delayed samples
|
||||
_Pragma( "loopbound min 15 max 15" )
|
||||
for ( i = 0; i < num_mic; i++ ) {
|
||||
delay_floor = preprocessed_delays[ i ].low;
|
||||
delay_ceil = preprocessed_delays[ i ].high;
|
||||
|
||||
// Inline wrap around here
|
||||
// Low index gets index of sample right before desired sample
|
||||
low_index = queue_head + delay_floor;
|
||||
if ( low_index > max_delay )
|
||||
low_index -= ( max_delay + 1 );
|
||||
|
||||
// High index gets index of sample right after desired sample
|
||||
high_index = queue_head + delay_ceil;
|
||||
if ( high_index > max_delay )
|
||||
high_index -= ( max_delay + 1 );
|
||||
|
||||
// i gives the value of the microphone we want. However, since
|
||||
// the array only has microphones first_mic to last_mic, we
|
||||
// need to offset our index by first_mic
|
||||
|
||||
interpolated_value = ( ( ( sample_queue[ high_index ][ i ] -
|
||||
sample_queue[ low_index ][ i ] )
|
||||
* ( preprocessed_delays[ i ].offset ) )
|
||||
+ sample_queue[ low_index ][ i ] );
|
||||
|
||||
// If we have microphone weights, multiply the value by the weight
|
||||
if ( weights != 0 )
|
||||
sum += ( interpolated_value * weights[ i ] );
|
||||
else
|
||||
sum += interpolated_value;
|
||||
}
|
||||
|
||||
return sum;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_process_signal( struct audiobeam_Delays *delays, int num_mic,
|
||||
float sampling_rate, float **beamform_results,
|
||||
struct audiobeam_DataQueue *queue,
|
||||
int num_beams, int window, float *weights )
|
||||
{
|
||||
int i, j;
|
||||
float time_index = 0;
|
||||
float time_index_inc = ( 1.0 / sampling_rate );
|
||||
|
||||
float value;
|
||||
|
||||
int done = 0;
|
||||
|
||||
struct audiobeam_PreprocessedDelays preprocessed_delays[ 15 ];
|
||||
|
||||
audiobeam_preprocess_delays( preprocessed_delays, delays->delay_values[ 0 ] );
|
||||
|
||||
_Pragma( "loopbound min 13 max 13" )
|
||||
for ( i = 0; i < delays->max_delay - 1; i++ ) {
|
||||
if ( audiobeam_input_pos < 5760 )
|
||||
audiobeam_parse_line( ( queue->sample_queue )[ queue->head ], 15 );
|
||||
else
|
||||
return -1;
|
||||
queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay );
|
||||
}
|
||||
_Pragma( "loopbound min 371 max 371" )
|
||||
for ( i = 0; ( i < window ) || ( window < 0 ) ; i++ ) {
|
||||
if ( audiobeam_input_pos < 5760 )
|
||||
audiobeam_parse_line( ( queue->sample_queue )[ queue->head ], 15 );
|
||||
else {
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
for ( j = 0; j < num_beams; j++ ) {
|
||||
value = audiobeam_do_beamforming( preprocessed_delays,
|
||||
( queue->sample_queue ),
|
||||
audiobeam_wrapped_inc( queue->head,
|
||||
delays->max_delay ),
|
||||
delays->max_delay, num_mic, weights );
|
||||
|
||||
|
||||
value = value / num_mic;
|
||||
|
||||
if ( beamform_results != 0 )
|
||||
beamform_results[ j ][ i ] = value;
|
||||
}
|
||||
|
||||
queue->tail = queue->head;
|
||||
queue->head = audiobeam_wrapped_inc( queue->head, delays->max_delay );
|
||||
|
||||
time_index += time_index_inc;
|
||||
}
|
||||
|
||||
return ( done );
|
||||
}
|
||||
|
||||
|
||||
int audiobeam_calc_beamforming_result( struct audiobeam_Delays *delays,
|
||||
float **beamform_results,
|
||||
float *energies,
|
||||
struct audiobeam_DataQueue *queue,
|
||||
int num_beams, int window,
|
||||
int hamming )
|
||||
{
|
||||
int i;
|
||||
int done;
|
||||
float *weights = 0;
|
||||
|
||||
if ( hamming ) {
|
||||
if ( ( 15 % 2 ) == 1 )
|
||||
weights = audiobeam_calc_weights_left_only( 15 );
|
||||
else
|
||||
weights = audiobeam_calc_weights_lr( 15 );
|
||||
}
|
||||
|
||||
done = audiobeam_process_signal( delays, 15, 16000,
|
||||
beamform_results,
|
||||
queue, num_beams, window, weights );
|
||||
|
||||
if ( beamform_results != 0 ) {
|
||||
_Pragma( "loopbound min 1 max 1" )
|
||||
for ( i = 0; i < num_beams; i++ )
|
||||
energies[ i ] = audiobeam_calculate_energy( beamform_results[ i ], window );
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
void audiobeam_calc_single_pos( float source_location[ 3 ],
|
||||
float audiobeam_mic_locations[ 15 ][ 3 ],
|
||||
int hamming )
|
||||
{
|
||||
float mic_distances[ 15 ];
|
||||
struct audiobeam_Delays *delays = audiobeam_init_delays( 1, 15 );
|
||||
struct audiobeam_DataQueue *queue;
|
||||
|
||||
float **beamform_results;
|
||||
float *energies;
|
||||
|
||||
beamform_results = ( float ** ) audiobeam_malloc( 1 * sizeof( float * ) );
|
||||
beamform_results[ 0 ] = ( float * ) audiobeam_malloc( 384 * sizeof( float ) );
|
||||
energies = ( float * ) audiobeam_malloc( 1 * sizeof( float * ) );
|
||||
|
||||
// Calculate distances from source to each of mics
|
||||
audiobeam_calc_distances( source_location, audiobeam_mic_locations,
|
||||
mic_distances, 15 );
|
||||
|
||||
audiobeam_calc_delays( mic_distances,
|
||||
delays->delay_values[ 0 ],
|
||||
342, 16000, 15 );
|
||||
|
||||
audiobeam_adjust_delays( delays->delay_values[ 0 ], 15 );
|
||||
|
||||
delays->max_delay = audiobeam_find_max_in_arr ( delays->delay_values[ 0 ], 15 );
|
||||
|
||||
queue = audiobeam_init_data_queue( delays->max_delay, 15 );
|
||||
|
||||
audiobeam_calc_beamforming_result( delays, beamform_results,
|
||||
energies, queue, 1, -1, hamming );
|
||||
|
||||
audiobeam_checksum += beamform_results[ 0 ][ 0 ] * 1000;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Main functions
|
||||
*/
|
||||
|
||||
void _Pragma( "entrypoint" ) audiobeam_main( void )
|
||||
{
|
||||
char hamming = 1;
|
||||
audiobeam_calc_single_pos( audiobeam_source_location,
|
||||
audiobeam_mic_locations,
|
||||
hamming );
|
||||
}
|
||||
|
||||
|
||||
int main( void )
|
||||
{
|
||||
audiobeam_init();
|
||||
audiobeam_main();
|
||||
|
||||
return ( audiobeam_return() );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user