Add wasm tacle-bench targets
This commit is contained in:
28
targets/wasm-tacle/sequential/audiobeam/CMakeLists.txt
Normal file
28
targets/wasm-tacle/sequential/audiobeam/CMakeLists.txt
Normal file
@ -0,0 +1,28 @@
|
||||
# ~~~
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
|
||||
# ~~~
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(audiobeam)
|
||||
|
||||
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
|
||||
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
|
||||
|
||||
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
|
||||
|
||||
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/inline/audiobeam.c")
|
||||
else()
|
||||
set(APP_SOURCE_FILE_PATH
|
||||
"generated/modified_sources/default/audiobeam.c"
|
||||
"generated/modified_sources/default/audiobeaminput.c"
|
||||
"generated/modified_sources/default/audiobeamlibm.c"
|
||||
"generated/modified_sources/default/audiobeamlibmalloc.c")
|
||||
endif()
|
||||
|
||||
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)
|
||||
|
||||
|
||||
86
targets/wasm-tacle/sequential/audiobeam/README
Executable file
86
targets/wasm-tacle/sequential/audiobeam/README
Executable file
@ -0,0 +1,86 @@
|
||||
Readme file for Oxygen beamforming source code distribution
|
||||
-----------------------------------------------------------
|
||||
|
||||
This is a very very beta distribution of beamforming source code from
|
||||
MIT LCS.
|
||||
|
||||
There is only one source file, main.c, and one header file,
|
||||
main.h. You can compile everything using the Makefile included in the
|
||||
distribution.
|
||||
|
||||
The input to the program is a text file containing floating
|
||||
point values for the signal read on each of the microphones. For n
|
||||
microphones, each line of the text files represents a temporal sample
|
||||
and should contain n floating point values separated by spaces, e.g.:
|
||||
|
||||
-1.8569790e-004 -9.0919049e-004 3.6711283e-004 -1.0073081e-005 ...
|
||||
|
||||
There are several modes of operation for the program:
|
||||
|
||||
1. The most basic mode is to process the microphone data and to
|
||||
calculate the output based on one beam focused on a particular point
|
||||
in space. The coordinates for the microphones and the focus point are
|
||||
specified inside main.c (eventually to be moved to a separate file).
|
||||
|
||||
2. Far field search mode. This mode assumes a far-field source (which
|
||||
means we have a planar wavefront) and a linear array, and sweeps over
|
||||
180 degrees in the plane of the array. The microphone coordinates are
|
||||
specified in main.c, and the NUM_ANGLES constant defines how many
|
||||
angle values should be tested (a value of 180 means one beam per each
|
||||
degree). The energy of the signal over a particular window
|
||||
(ANGLE_ENERGY_WINDOW_SIZE) is computed for each beam. The direction
|
||||
with maximum energy is considered the direction that the speech signal
|
||||
is coming from, and is printed out by the program.
|
||||
|
||||
3. Near-field hill climbing mode. This mode accepts a starting
|
||||
coordinate and attempts to "hill-climb" through the space seeking the
|
||||
maximum energy. Each of the x, y, and z coordinates are perturbed in
|
||||
the positive and negative directions at each time interval
|
||||
(GRID_ENERGY_WINDOW_SIZE) by a step size (GRID_STEP_SIZE). This
|
||||
perturbation, along with the original coordinate, produces seven
|
||||
coordinates to be tested. The direction with the maximum energy
|
||||
replaces the current reference coordinate. For instance, if we have a
|
||||
starting reference coordinate of (1,1,0) and our step size is 0.01, we
|
||||
will evaluate the energy for the following seven beams:
|
||||
|
||||
(1,1,0)
|
||||
(0.99,1,0)
|
||||
(1.01,1,0)
|
||||
(1,0.99,0)
|
||||
(1,1.01,0)
|
||||
(1,1,-0.01)
|
||||
(1,1,0.01)
|
||||
|
||||
Now let's say the beam (1,1.01,0) has the maximum energy; then this
|
||||
coordinate will replace the original reference coordinate of (1,1,0).
|
||||
|
||||
For methods 2, and 3, we are not outputting anything to disk, we are
|
||||
just printing the result. This is because we have just started to work
|
||||
with these methods, and have not applied them in real systems. This
|
||||
code is currently being ported to RAW.
|
||||
|
||||
To get a list of parameters for the delay_and_sum executable that is
|
||||
generated when the source is compiled, just type ./delay_and_sum .
|
||||
|
||||
There is some sample data included with the program, in the data
|
||||
directory. There is some data for a near-field and far-field
|
||||
source. The README.txt file in each directory specifies the microphone
|
||||
and source position. The data1 file, when processed with a beamformer
|
||||
aligned in the proper direction should produce something like a sinc
|
||||
function (see
|
||||
http://ccrma-www.stanford.edu/~jos/Interpolation/sinc_function.html).
|
||||
|
||||
The data2 file should produce an audio signal of a woman saying "the
|
||||
simplest method". If the beamformer is aligned properly, the noise
|
||||
should be reduced significantly over the source signal from only one
|
||||
of the microphones (use print_datafile.pl to isolate one
|
||||
microphone). You can convert the data file that the program produces
|
||||
to wave files using sox.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---------------------------------
|
||||
Eugene Weinstein
|
||||
ecoder@mit.edu
|
||||
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() );
|
||||
}
|
||||
|
||||
50
targets/wasm-tacle/sequential/audiobeam/audiobeam.h
Executable file
50
targets/wasm-tacle/sequential/audiobeam/audiobeam.h
Executable file
@ -0,0 +1,50 @@
|
||||
#ifndef AUDIOBEAM_MAIN_H
|
||||
#define AUDIOBEAM_MAIN_H
|
||||
|
||||
struct audiobeam_DataQueue {
|
||||
float **sample_queue;
|
||||
int head;
|
||||
int tail;
|
||||
unsigned char full;
|
||||
};
|
||||
|
||||
|
||||
struct audiobeam_Delays {
|
||||
float **delay_values;
|
||||
long int max_delay;
|
||||
};
|
||||
|
||||
|
||||
struct audiobeam_PreprocessedDelays {
|
||||
float delay;
|
||||
int low;
|
||||
int high;
|
||||
float offset;
|
||||
};
|
||||
|
||||
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX 999e999
|
||||
|
||||
#define SOUND_SPEED 342
|
||||
#define SAMPLING_RATE 16000
|
||||
#define CARTESIAN_DISTANCE(x1,y1,z1,x2,y2,z2) (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
|
||||
|
||||
#define NUM_MIC 15
|
||||
#define ANGLE_ENERGY_WINDOW_SIZE 400
|
||||
#define GRID_STEP_SIZE 0.003 // .3cm
|
||||
#define NUM_DIRS 7
|
||||
#define NUM_TILES 16
|
||||
|
||||
#define MIC_HORIZ_SPACE 0.038257
|
||||
#define MIC_VERT_SPACE 0.015001
|
||||
#define TWO23 8388608.0 // 2^23
|
||||
#define BUFFER_SIZE 384 // No of input-tupels (each with NUM_MIC elements)
|
||||
#define NUM_MIC_IN_CHAIN 32
|
||||
#define NUM_BOARDS_IN_CHAIN 16
|
||||
#define INPUT_LENGTH 5760
|
||||
|
||||
#define INTERPOLATE(low_value, high_value, offset) (((high_value-low_value)*(offset)) + low_value)
|
||||
|
||||
#endif
|
||||
|
||||
5784
targets/wasm-tacle/sequential/audiobeam/audiobeaminput.c
Executable file
5784
targets/wasm-tacle/sequential/audiobeam/audiobeaminput.c
Executable file
File diff suppressed because it is too large
Load Diff
425
targets/wasm-tacle/sequential/audiobeam/audiobeamlibm.c
Executable file
425
targets/wasm-tacle/sequential/audiobeam/audiobeamlibm.c
Executable file
@ -0,0 +1,425 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibm.c
|
||||
|
||||
Author: Ian Lance Taylor and J.T. Conklin
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmath.h"
|
||||
|
||||
|
||||
static const int audiobeam_npio2_hw[ ] = {
|
||||
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
|
||||
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
|
||||
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
|
||||
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
|
||||
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
|
||||
0x4242c700, 0x42490f00
|
||||
};
|
||||
|
||||
static const float
|
||||
audiobeam_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
|
||||
audiobeam_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
|
||||
audiobeam_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
|
||||
audiobeam_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
|
||||
audiobeam_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
|
||||
audiobeam_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
|
||||
audiobeam_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
|
||||
|
||||
static const float
|
||||
audiobeam_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
|
||||
audiobeam_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
|
||||
audiobeam_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
|
||||
audiobeam_C4 = -2.7557314297e-07f, /* 0xb493f27c */
|
||||
audiobeam_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
|
||||
audiobeam_C6 = -1.1359647598e-11f; /* 0xad47d74e */
|
||||
|
||||
static const float
|
||||
audiobeam_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
|
||||
audiobeam_S2 = 8.3333337680e-03f, /* 0x3c088889 */
|
||||
audiobeam_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
|
||||
audiobeam_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
|
||||
audiobeam_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
|
||||
audiobeam_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
|
||||
|
||||
static const float
|
||||
audiobeam_two25 = 3.355443200e+07f, /* 0x4c000000 */
|
||||
audiobeam_twom25 = 2.9802322388e-08f; /* 0x33000000 */
|
||||
|
||||
|
||||
int audiobeam___ieee754_rem_pio2f( float x, float *y )
|
||||
{
|
||||
float z, w, t, r, fn;
|
||||
int i, j, n = 0, ix, hx;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD( hx, x );
|
||||
ix = hx & 0x7fffffff;
|
||||
if ( ix <= 0x3f490fd8 ) {
|
||||
y[ 0 ] = x;
|
||||
y[ 1 ] = 0;
|
||||
return 0;
|
||||
}
|
||||
if ( ix < 0x4016cbe4 ) {
|
||||
if ( hx > 0 ) {
|
||||
z = x - audiobeam_pio2_1;
|
||||
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) {
|
||||
y[ 0 ] = z - audiobeam_pio2_1t;
|
||||
y[ 1 ] = ( z - y[ 0 ] ) - audiobeam_pio2_1t;
|
||||
} else {
|
||||
z -= audiobeam_pio2_2;
|
||||
y[ 0 ] = z - audiobeam_pio2_2t;
|
||||
y[ 1 ] = ( z - y[ 0 ] ) - audiobeam_pio2_2t;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
z = x + audiobeam_pio2_1;
|
||||
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) {
|
||||
y[ 0 ] = z + audiobeam_pio2_1t;
|
||||
y[ 1 ] = ( z - y[ 0 ] ) + audiobeam_pio2_1t;
|
||||
} else {
|
||||
z += audiobeam_pio2_2;
|
||||
y[ 0 ] = z + audiobeam_pio2_2t;
|
||||
y[ 1 ] = ( z - y[ 0 ] ) + audiobeam_pio2_2t;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if ( ix <= 0x43490f80 ) {
|
||||
t = audiobeam_fabsf( x );
|
||||
n = ( int ) ( t * audiobeam_invpio2 + audiobeam_half );
|
||||
fn = ( float )n;
|
||||
r = t - fn * audiobeam_pio2_1;
|
||||
w = fn * audiobeam_pio2_1t;
|
||||
if ( n < 32 && ( int )( ix & 0xffffff00 ) != audiobeam_npio2_hw[ n - 1 ] )
|
||||
y[ 0 ] = r - w;
|
||||
else {
|
||||
unsigned int high;
|
||||
j = ix >> 23;
|
||||
y[ 0 ] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( high, y[ 0 ] );
|
||||
i = j - ( ( high >> 23 ) & 0xff );
|
||||
if ( i > 8 ) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_2;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_2t - ( ( t - r ) - w );
|
||||
y[ 0 ] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( high, y[ 0 ] );
|
||||
i = j - ( ( high >> 23 ) & 0xff );
|
||||
if ( i > 25 ) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_3;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_3t - ( ( t - r ) - w );
|
||||
y[ 0 ] = r - w;
|
||||
}
|
||||
}
|
||||
}
|
||||
y[ 1 ] = ( r - y[ 0 ] ) - w;
|
||||
if ( hx < 0 ) {
|
||||
y[ 0 ] = -y[ 0 ];
|
||||
y[ 1 ] = -y[ 1 ];
|
||||
return -n;
|
||||
} else return n;
|
||||
}
|
||||
if ( ix >= 0x7f800000 ) {
|
||||
y[ 0 ] = y[ 1 ] = x - x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___kernel_cosf( float x, float y )
|
||||
{
|
||||
float a, hz, z, r, qx;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
ix &= 0x7fffffff;
|
||||
if ( ix < 0x32000000 ) {
|
||||
if ( ( ( int )x ) == 0 ) return audiobeam_one;
|
||||
}
|
||||
z = x * x;
|
||||
r = z * ( audiobeam_C1 + z * ( audiobeam_C2 + z * ( audiobeam_C3 + z *
|
||||
( audiobeam_C4 + z *
|
||||
( audiobeam_C5 + z * audiobeam_C6 ) ) ) ) );
|
||||
if ( ix < 0x3e99999a )
|
||||
return audiobeam_one - ( ( float )0.5f * z - ( z * r - x * y ) );
|
||||
else {
|
||||
if ( ix > 0x3f480000 )
|
||||
qx = ( float )0.28125f;
|
||||
else
|
||||
AUDIOBEAM_SET_FLOAT_WORD( qx, ix - 0x01000000 );
|
||||
hz = ( float )0.5f * z - qx;
|
||||
a = audiobeam_one - qx;
|
||||
return a - ( hz - ( z * r - x * y ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___kernel_sinf( float x, float y, int iy )
|
||||
{
|
||||
float z, r, v;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
ix &= 0x7fffffff;
|
||||
if ( ix < 0x32000000 ) {
|
||||
if ( ( int )x == 0 ) return x;
|
||||
}
|
||||
z = x * x;
|
||||
v = z * x;
|
||||
r = audiobeam_S2 + z * ( audiobeam_S3 + z * ( audiobeam_S4 + z *
|
||||
( audiobeam_S5 + z * audiobeam_S6 ) ) );
|
||||
if ( iy == 0 ) return x + v * ( audiobeam_S1 + z * r );
|
||||
else return x - ( ( z * ( audiobeam_half * y - v * r ) - y ) - v *
|
||||
audiobeam_S1 );
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___copysignf( float x, float y )
|
||||
{
|
||||
unsigned int ix, iy;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
AUDIOBEAM_GET_FLOAT_WORD( iy, y );
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___cosf( float x )
|
||||
{
|
||||
float y[ 2 ], z = 0.0f;
|
||||
int n, ix;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
|
||||
ix &= 0x7fffffff;
|
||||
if ( ix <= 0x3f490fd8 ) return audiobeam___kernel_cosf( x, z );
|
||||
|
||||
else
|
||||
if ( ix >= 0x7f800000 ) return x - x;
|
||||
|
||||
else {
|
||||
y[ 0 ] = 0.0;
|
||||
y[ 1 ] = 0.0;
|
||||
n = audiobeam___ieee754_rem_pio2f( x, y );
|
||||
switch ( n & 3 ) {
|
||||
case 0:
|
||||
return audiobeam___kernel_cosf( y[ 0 ], y[ 1 ] );
|
||||
case 1:
|
||||
return -audiobeam___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
|
||||
case 2:
|
||||
return -audiobeam___kernel_cosf( y[ 0 ], y[ 1 ] );
|
||||
default:
|
||||
return audiobeam___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___fabsf( float x )
|
||||
{
|
||||
unsigned int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, ix & 0x7fffffff );
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___floorf( float x )
|
||||
{
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( i0, x );
|
||||
j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f;
|
||||
if ( j0 < 23 ) {
|
||||
if ( j0 < 0 ) {
|
||||
if ( audiobeam_huge + x > ( float )0.0f ) {
|
||||
if ( i0 >= 0 )
|
||||
i0 = 0;
|
||||
else
|
||||
if ( ( i0 & 0x7fffffff ) != 0 )
|
||||
i0 = 0xbf800000;
|
||||
}
|
||||
} else {
|
||||
i = ( 0x007fffff ) >> j0;
|
||||
if ( ( i0 & i ) == 0 ) return x;
|
||||
if ( audiobeam_huge + x > ( float )0.0f ) {
|
||||
if ( i0 < 0 ) i0 += ( 0x00800000 ) >> j0;
|
||||
i0 &= ( ~i );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( j0 == 0x80 ) return x + x;
|
||||
else return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, i0 );
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
int audiobeam___isinff ( float x )
|
||||
{
|
||||
int ix, t;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
t = ix & 0x7fffffff;
|
||||
t ^= 0x7f800000;
|
||||
t |= -t;
|
||||
return ~( t >> 31 ) & ( ix >> 30 );
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___scalbnf ( float x, int n )
|
||||
{
|
||||
int k, ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
k = ( ix & 0x7f800000 ) >> 23;
|
||||
if ( k == 0 ) {
|
||||
if ( ( ix & 0x7fffffff ) == 0 ) return x;
|
||||
x *= audiobeam_two25;
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
k = ( ( ix & 0x7f800000 ) >> 23 ) - 25;
|
||||
}
|
||||
if ( k == 0xff ) return x + x;
|
||||
k = k + n;
|
||||
if ( n > 50000 || k > 0xfe )
|
||||
return audiobeam_huge * audiobeam___copysignf( audiobeam_huge,
|
||||
x );
|
||||
if ( n < -50000 )
|
||||
return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny,
|
||||
x );
|
||||
if ( k > 0 ) {
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
|
||||
return x;
|
||||
}
|
||||
if ( k <= -25 )
|
||||
return audiobeam_tiny * audiobeam___copysignf( audiobeam_tiny,
|
||||
x );
|
||||
k += 25;
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
|
||||
return x * audiobeam_twom25;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___ceilf( float x )
|
||||
{
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD( i0, x );
|
||||
j0 = ( ( i0 >> 23 ) & 0xff ) - 0x7f;
|
||||
if ( j0 < 23 ) {
|
||||
if ( j0 < 0 ) {
|
||||
if ( audiobeam_huge + x > ( float )0.0 ) {
|
||||
if ( i0 < 0 )
|
||||
i0 = 0x80000000;
|
||||
else
|
||||
if ( i0 != 0 )
|
||||
i0 = 0x3f800000;
|
||||
}
|
||||
} else {
|
||||
i = ( 0x007fffff ) >> j0;
|
||||
if ( ( i0 & i ) == 0 ) return x;
|
||||
if ( audiobeam_huge + x > ( float )0.0 ) {
|
||||
if ( i0 > 0 ) i0 += ( 0x00800000 ) >> j0;
|
||||
i0 &= ( ~i );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( j0 == 0x80 ) return x + x;
|
||||
else return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD( x, i0 );
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
float audiobeam___ieee754_sqrtf( float x )
|
||||
{
|
||||
float z;
|
||||
int sign = ( int )0x80000000;
|
||||
int ix, s, q, m, t, i;
|
||||
unsigned int r;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD( ix, x );
|
||||
|
||||
if ( ( ix & 0x7f800000 ) == 0x7f800000 )
|
||||
return x * x + x;
|
||||
if ( ix <= 0 ) {
|
||||
if ( ( ix & ( ~sign ) ) == 0 ) return x;
|
||||
else
|
||||
if ( ix < 0 )
|
||||
return ( x - x ) / ( x - x );
|
||||
}
|
||||
m = ( ix >> 23 );
|
||||
if ( m == 0 ) {
|
||||
_Pragma( "loopbound min 0 max 0" )
|
||||
for ( i = 0; ( ix & 0x00800000 ) == 0; i++ )
|
||||
ix <<= 1;
|
||||
m -= i - 1;
|
||||
}
|
||||
m -= 127;
|
||||
ix = ( ix & 0x007fffff ) | 0x00800000;
|
||||
if ( m & 1 )
|
||||
ix += ix;
|
||||
m >>= 1;
|
||||
|
||||
ix += ix;
|
||||
q = s = 0;
|
||||
r = 0x01000000;
|
||||
|
||||
_Pragma( "loopbound min 25 max 25" )
|
||||
while ( r != 0 ) {
|
||||
t = s + r;
|
||||
if ( t <= ix ) {
|
||||
s = t + r;
|
||||
ix -= t;
|
||||
q += r;
|
||||
}
|
||||
ix += ix;
|
||||
r >>= 1;
|
||||
}
|
||||
|
||||
if ( ix != 0 ) {
|
||||
z = audiobeam_one - audiobeam_tiny;
|
||||
if ( z >= audiobeam_one ) {
|
||||
z = audiobeam_one + audiobeam_tiny;
|
||||
if ( z > audiobeam_one )
|
||||
q += 2;
|
||||
else
|
||||
q += ( q & 1 );
|
||||
}
|
||||
}
|
||||
ix = ( q >> 1 ) + 0x3f000000;
|
||||
ix += ( m << 23 );
|
||||
AUDIOBEAM_SET_FLOAT_WORD( z, ix );
|
||||
return z;
|
||||
}
|
||||
59
targets/wasm-tacle/sequential/audiobeam/audiobeamlibm.h
Executable file
59
targets/wasm-tacle/sequential/audiobeam/audiobeamlibm.h
Executable file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: quicksortlibm.c
|
||||
|
||||
Author: Ian Lance Taylor
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See audiobeamlibm.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_LIBM
|
||||
#define AUDIOBEAM_LIBM
|
||||
|
||||
#define audiobeam_M_PI 3.14159265358979323846
|
||||
|
||||
static const float
|
||||
audiobeam_one = 1.0f,
|
||||
audiobeam_tiny = 1.0e-30f,
|
||||
audiobeam_half = 5.0000000000e-01, /* 0x3f000000 */
|
||||
audiobeam_huge = 1.0e30,
|
||||
audiobeam_two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
audiobeam_twon8 = 3.9062500000e-03, /* 0x3b800000 */
|
||||
audiobeam_zero = 0.0;
|
||||
|
||||
#define audiobeam_cos audiobeam___cosf
|
||||
#define audiobeam_fabs audiobeam___fabsf
|
||||
#define audiobeam_fabsf audiobeam___fabsf
|
||||
#define audiobeam_isinf audiobeam___isinff
|
||||
#define audiobeam_sqrt audiobeam___ieee754_sqrtf
|
||||
#define audiobeam_ceil audiobeam___ceilf
|
||||
#define audiobeam_floor audiobeam___floorf
|
||||
|
||||
float audiobeam___copysignf( float x, float y );
|
||||
float audiobeam___cosf( float x );
|
||||
float audiobeam___fabsf( float x );
|
||||
float audiobeam___floorf( float x );
|
||||
int audiobeam___ieee754_rem_pio2f( float x, float *y );
|
||||
float audiobeam___ieee754_sqrtf( float x );
|
||||
int audiobeam___isinff ( float x );
|
||||
float audiobeam___kernel_cosf( float x, float y );
|
||||
float audiobeam___kernel_sinf( float x, float y, int iy );
|
||||
int audiobeam___kernel_rem_pio2f( float *x, float *y, int e0, int nx,
|
||||
int prec, const int *ipio2 );
|
||||
float audiobeam___scalbnf ( float x, int n );
|
||||
float audiobeam___ceilf( float x );
|
||||
float audiobeam___floorf( float x );
|
||||
|
||||
#endif // AUDIOBEAM_LIBM
|
||||
14
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmalloc.c
Executable file
14
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmalloc.c
Executable file
@ -0,0 +1,14 @@
|
||||
#include "audiobeamlibmalloc.h"
|
||||
|
||||
#define AUDIOBEAM_HEAP_SIZE 10000
|
||||
|
||||
static char audiobeam_simulated_heap[ AUDIOBEAM_HEAP_SIZE ];
|
||||
static unsigned int audiobeam_freeHeapPos;
|
||||
|
||||
void *audiobeam_malloc( unsigned int numberOfBytes )
|
||||
{
|
||||
void *currentPos = ( void * )&audiobeam_simulated_heap[ audiobeam_freeHeapPos ];
|
||||
/* Get a 4-byte address for alignment purposes */
|
||||
audiobeam_freeHeapPos += ( ( numberOfBytes + 4 ) & ( unsigned int )0xfffffffc );
|
||||
return currentPos;
|
||||
}
|
||||
27
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmalloc.h
Executable file
27
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmalloc.h
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmalloc.c
|
||||
|
||||
Author: unkown
|
||||
|
||||
Function: Memory allocation.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: see license.txt
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MALLOC_H
|
||||
#define AUDIOBEAM_MALLOC_H
|
||||
|
||||
void *audiobeam_malloc( unsigned int numberOfBytes );
|
||||
|
||||
#endif
|
||||
69
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmath.h
Executable file
69
targets/wasm-tacle/sequential/audiobeam/audiobeamlibmath.h
Executable file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmath.h
|
||||
|
||||
Author: Unknown
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems
|
||||
|
||||
Original name: math_private.h
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from: @(#)fdlibm.h 5.1 93/09/24
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MATH_PRIVATE_H_
|
||||
#define AUDIOBEAM_MATH_PRIVATE_H_
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
|
||||
/* A union which permits us to convert between a float and a 32 bit
|
||||
int. */
|
||||
|
||||
typedef union {
|
||||
float value;
|
||||
unsigned int word;
|
||||
} audiobeam_ieee_float_shape_type;
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define AUDIOBEAM_GET_FLOAT_WORD(i,d) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
}
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define AUDIOBEAM_SET_FLOAT_WORD(d,i) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
}
|
||||
|
||||
#endif /* _MATH_PRIVATE_H_ */
|
||||
36
targets/wasm-tacle/sequential/audiobeam/changeLog.txt
Executable file
36
targets/wasm-tacle/sequential/audiobeam/changeLog.txt
Executable file
@ -0,0 +1,36 @@
|
||||
File: audiobeam.c
|
||||
Original provenience: StreamIt
|
||||
http://groups.csail.mit.edu/cag/streamit/
|
||||
|
||||
2015-12-29:
|
||||
- Removed original header comment, replaced by TACLeBench header.
|
||||
- Renamed libraryfiles according to TACLeBench naming scheme.
|
||||
- Removed all preprocessor macros, integrated them directly in the source code.
|
||||
- Added prefix "audiobeam_" to all global symbols.
|
||||
- Added explicit forward declarations of functions.
|
||||
- Added an empty init function
|
||||
- Added preprocessor command to determine if 32 or 64 bit in audiobeamlibmalloc.h
|
||||
- Added new function audiobeam_return producing a checksum as return value.
|
||||
- Added new function audiobeam_main according to TACLeBench guidelines.
|
||||
audiobeam_main is annotated as entry-point for timing analysis.
|
||||
- Applied code formatting according to the following rules
|
||||
- Lines shall not be wider than 80 characters; whenever possible, appropriate
|
||||
line breaks shall be inserted to keep lines below 80 characters
|
||||
- Indentation is done using whitespaces only, no tabs. Code is indented by
|
||||
two whitespaces
|
||||
- Two empty lines are put between any two functions
|
||||
- In non-empty lists or index expressions, opening '(' and '[' are followed by
|
||||
one whitespace, closing ')' and ']' are preceded by one whitespace
|
||||
- In comma- or colon-separated argument lists, one whitespace is put after
|
||||
each comma/colon
|
||||
- Names of functions and global variables all start with a benchmark-specific
|
||||
prefix (here: bs_) followed by lowercase letter (e.g., bs_square)
|
||||
- For pointer types, one whitespace is put before the '*'
|
||||
- Operators within expressions shall be preceded and followed by one
|
||||
whitespace
|
||||
- Code of then- and else-parts of if-then-else statements shall be put in
|
||||
separate lines, not in the same lines as the if-condition or the keyword
|
||||
"else"
|
||||
- Opening braces '{' denoting the beginning of code for some if-else or loop
|
||||
body shall be put at the end of the same line where the keywords "if",
|
||||
"else", "for", "while" etc. occur
|
||||
BIN
targets/wasm-tacle/sequential/audiobeam/generated/default/audiobeam.wasm
Executable file
BIN
targets/wasm-tacle/sequential/audiobeam/generated/default/audiobeam.wasm
Executable file
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -0,0 +1,542 @@
|
||||
/*
|
||||
|
||||
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 "audiobeam.h"
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmalloc.h"
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
void audiobeam_init();
|
||||
int audiobeam_return();
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
audiobeam_main(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) 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(23040, 23040);
|
||||
for (i = 0; i < sizeof(audiobeam_input); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_mic_locations[0];
|
||||
__pragma_loopbound(180, 180);
|
||||
for (i = 0; i < sizeof(audiobeam_mic_locations); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_source_location[0];
|
||||
__pragma_loopbound(12, 12);
|
||||
for (i = 0; i < sizeof(audiobeam_source_location); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_origin_location[0];
|
||||
__pragma_loopbound(12, 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(15, 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(15, 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(15, 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(15, 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(15, 15);
|
||||
for (i = 0; i < (max_delay + 1); i++) {
|
||||
(queue->sample_queue)[i] =
|
||||
(float *) audiobeam_malloc(num_mic * sizeof(float));
|
||||
__pragma_loopbound(15, 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(1, 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(15, 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(15, 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(15, 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(0, 0);
|
||||
for (z = 1; z >= -1; z -= 2) {
|
||||
__pragma_loopbound(0, 0);
|
||||
for (y = 0; y < half; y++) {
|
||||
weights[index] =
|
||||
0.54 + 0.46 * audiobeam_cos(audiobeam_M_PI * y / half);
|
||||
index++;
|
||||
}
|
||||
__pragma_loopbound(0, 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(15, 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(0, 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(15, 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(13, 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(371, 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(1, 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(1, 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
|
||||
*/
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
audiobeam_main(void) {
|
||||
char hamming = 1;
|
||||
audiobeam_calc_single_pos(audiobeam_source_location,
|
||||
audiobeam_mic_locations, hamming);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
audiobeam_init();
|
||||
audiobeam_main();
|
||||
|
||||
return (audiobeam_return());
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
|
||||
#ifndef AUDIOBEAM_MAIN_H
|
||||
#define AUDIOBEAM_MAIN_H
|
||||
|
||||
struct audiobeam_DataQueue {
|
||||
float **sample_queue;
|
||||
int head;
|
||||
int tail;
|
||||
unsigned char full;
|
||||
};
|
||||
|
||||
struct audiobeam_Delays {
|
||||
float **delay_values;
|
||||
long int max_delay;
|
||||
};
|
||||
|
||||
struct audiobeam_PreprocessedDelays {
|
||||
float delay;
|
||||
int low;
|
||||
int high;
|
||||
float offset;
|
||||
};
|
||||
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX 999e999
|
||||
|
||||
#define SOUND_SPEED 342
|
||||
#define SAMPLING_RATE 16000
|
||||
#define CARTESIAN_DISTANCE(x1, y1, z1, x2, y2, z2) \
|
||||
(sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + \
|
||||
(z1 - z2) * (z1 - z2)));
|
||||
|
||||
#define NUM_MIC 15
|
||||
#define ANGLE_ENERGY_WINDOW_SIZE 400
|
||||
#define GRID_STEP_SIZE 0.003 // .3cm
|
||||
#define NUM_DIRS 7
|
||||
#define NUM_TILES 16
|
||||
|
||||
#define MIC_HORIZ_SPACE 0.038257
|
||||
#define MIC_VERT_SPACE 0.015001
|
||||
#define TWO23 8388608.0 // 2^23
|
||||
#define BUFFER_SIZE 384 // No of input-tupels (each with NUM_MIC elements)
|
||||
#define NUM_MIC_IN_CHAIN 32
|
||||
#define NUM_BOARDS_IN_CHAIN 16
|
||||
#define INPUT_LENGTH 5760
|
||||
|
||||
#define INTERPOLATE(low_value, high_value, offset) \
|
||||
(((high_value - low_value) * (offset)) + low_value)
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,425 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibm.c
|
||||
|
||||
Author: Ian Lance Taylor and J.T. Conklin
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmath.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
static const int audiobeam_npio2_hw[] = {
|
||||
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
|
||||
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
|
||||
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
|
||||
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
|
||||
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
|
||||
0x4242c700, 0x42490f00};
|
||||
|
||||
static const float audiobeam_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
|
||||
audiobeam_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
|
||||
audiobeam_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
|
||||
audiobeam_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
|
||||
audiobeam_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
|
||||
audiobeam_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
|
||||
audiobeam_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
|
||||
|
||||
static const float audiobeam_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
|
||||
audiobeam_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
|
||||
audiobeam_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
|
||||
audiobeam_C4 = -2.7557314297e-07f, /* 0xb493f27c */
|
||||
audiobeam_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
|
||||
audiobeam_C6 = -1.1359647598e-11f; /* 0xad47d74e */
|
||||
|
||||
static const float audiobeam_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
|
||||
audiobeam_S2 = 8.3333337680e-03f, /* 0x3c088889 */
|
||||
audiobeam_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
|
||||
audiobeam_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
|
||||
audiobeam_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
|
||||
audiobeam_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
|
||||
|
||||
static const float audiobeam_two25 = 3.355443200e+07f, /* 0x4c000000 */
|
||||
audiobeam_twom25 = 2.9802322388e-08f; /* 0x33000000 */
|
||||
|
||||
int
|
||||
audiobeam___ieee754_rem_pio2f(float x, float *y) {
|
||||
float z, w, t, r, fn;
|
||||
int i, j, n = 0, ix, hx;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
if (ix <= 0x3f490fd8) {
|
||||
y[0] = x;
|
||||
y[1] = 0;
|
||||
return 0;
|
||||
}
|
||||
if (ix < 0x4016cbe4) {
|
||||
if (hx > 0) {
|
||||
z = x - audiobeam_pio2_1;
|
||||
if ((ix & 0xfffffff0) != 0x3fc90fd0) {
|
||||
y[0] = z - audiobeam_pio2_1t;
|
||||
y[1] = (z - y[0]) - audiobeam_pio2_1t;
|
||||
} else {
|
||||
z -= audiobeam_pio2_2;
|
||||
y[0] = z - audiobeam_pio2_2t;
|
||||
y[1] = (z - y[0]) - audiobeam_pio2_2t;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
z = x + audiobeam_pio2_1;
|
||||
if ((ix & 0xfffffff0) != 0x3fc90fd0) {
|
||||
y[0] = z + audiobeam_pio2_1t;
|
||||
y[1] = (z - y[0]) + audiobeam_pio2_1t;
|
||||
} else {
|
||||
z += audiobeam_pio2_2;
|
||||
y[0] = z + audiobeam_pio2_2t;
|
||||
y[1] = (z - y[0]) + audiobeam_pio2_2t;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (ix <= 0x43490f80) {
|
||||
t = audiobeam_fabsf(x);
|
||||
n = (int) (t * audiobeam_invpio2 + audiobeam_half);
|
||||
fn = (float) n;
|
||||
r = t - fn * audiobeam_pio2_1;
|
||||
w = fn * audiobeam_pio2_1t;
|
||||
if (n < 32 && (int) (ix & 0xffffff00) != audiobeam_npio2_hw[n - 1])
|
||||
y[0] = r - w;
|
||||
else {
|
||||
unsigned int high;
|
||||
j = ix >> 23;
|
||||
y[0] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(high, y[0]);
|
||||
i = j - ((high >> 23) & 0xff);
|
||||
if (i > 8) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_2;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_2t - ((t - r) - w);
|
||||
y[0] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(high, y[0]);
|
||||
i = j - ((high >> 23) & 0xff);
|
||||
if (i > 25) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_3;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_3t - ((t - r) - w);
|
||||
y[0] = r - w;
|
||||
}
|
||||
}
|
||||
}
|
||||
y[1] = (r - y[0]) - w;
|
||||
if (hx < 0) {
|
||||
y[0] = -y[0];
|
||||
y[1] = -y[1];
|
||||
return -n;
|
||||
} else
|
||||
return n;
|
||||
}
|
||||
if (ix >= 0x7f800000) {
|
||||
y[0] = y[1] = x - x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___kernel_cosf(float x, float y) {
|
||||
float a, hz, z, r, qx;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
ix &= 0x7fffffff;
|
||||
if (ix < 0x32000000) {
|
||||
if (((int) x) == 0)
|
||||
return audiobeam_one;
|
||||
}
|
||||
z = x * x;
|
||||
r = z * (audiobeam_C1 +
|
||||
z * (audiobeam_C2 +
|
||||
z * (audiobeam_C3 +
|
||||
z * (audiobeam_C4 +
|
||||
z * (audiobeam_C5 + z * audiobeam_C6)))));
|
||||
if (ix < 0x3e99999a)
|
||||
return audiobeam_one - ((float) 0.5f * z - (z * r - x * y));
|
||||
else {
|
||||
if (ix > 0x3f480000)
|
||||
qx = (float) 0.28125f;
|
||||
else
|
||||
AUDIOBEAM_SET_FLOAT_WORD(qx, ix - 0x01000000);
|
||||
hz = (float) 0.5f * z - qx;
|
||||
a = audiobeam_one - qx;
|
||||
return a - (hz - (z * r - x * y));
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___kernel_sinf(float x, float y, int iy) {
|
||||
float z, r, v;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
ix &= 0x7fffffff;
|
||||
if (ix < 0x32000000) {
|
||||
if ((int) x == 0)
|
||||
return x;
|
||||
}
|
||||
z = x * x;
|
||||
v = z * x;
|
||||
r = audiobeam_S2 +
|
||||
z * (audiobeam_S3 +
|
||||
z * (audiobeam_S4 + z * (audiobeam_S5 + z * audiobeam_S6)));
|
||||
if (iy == 0)
|
||||
return x + v * (audiobeam_S1 + z * r);
|
||||
else
|
||||
return x - ((z * (audiobeam_half * y - v * r) - y) - v * audiobeam_S1);
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___copysignf(float x, float y) {
|
||||
unsigned int ix, iy;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
AUDIOBEAM_GET_FLOAT_WORD(iy, y);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
|
||||
return x;
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___cosf(float x) {
|
||||
float y[2], z = 0.0f;
|
||||
int n, ix;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
|
||||
ix &= 0x7fffffff;
|
||||
if (ix <= 0x3f490fd8)
|
||||
return audiobeam___kernel_cosf(x, z);
|
||||
|
||||
else if (ix >= 0x7f800000)
|
||||
return x - x;
|
||||
|
||||
else {
|
||||
y[0] = 0.0;
|
||||
y[1] = 0.0;
|
||||
n = audiobeam___ieee754_rem_pio2f(x, y);
|
||||
switch (n & 3) {
|
||||
case 0:
|
||||
return audiobeam___kernel_cosf(y[0], y[1]);
|
||||
case 1:
|
||||
return -audiobeam___kernel_sinf(y[0], y[1], 1);
|
||||
case 2:
|
||||
return -audiobeam___kernel_cosf(y[0], y[1]);
|
||||
default:
|
||||
return audiobeam___kernel_sinf(y[0], y[1], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___fabsf(float x) {
|
||||
unsigned int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, ix & 0x7fffffff);
|
||||
return x;
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___floorf(float x) {
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(i0, x);
|
||||
j0 = ((i0 >> 23) & 0xff) - 0x7f;
|
||||
if (j0 < 23) {
|
||||
if (j0 < 0) {
|
||||
if (audiobeam_huge + x > (float) 0.0f) {
|
||||
if (i0 >= 0)
|
||||
i0 = 0;
|
||||
else if ((i0 & 0x7fffffff) != 0)
|
||||
i0 = 0xbf800000;
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff) >> j0;
|
||||
if ((i0 & i) == 0)
|
||||
return x;
|
||||
if (audiobeam_huge + x > (float) 0.0f) {
|
||||
if (i0 < 0)
|
||||
i0 += (0x00800000) >> j0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (j0 == 0x80)
|
||||
return x + x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, i0);
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
audiobeam___isinff(float x) {
|
||||
int ix, t;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
t = ix & 0x7fffffff;
|
||||
t ^= 0x7f800000;
|
||||
t |= -t;
|
||||
return ~(t >> 31) & (ix >> 30);
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___scalbnf(float x, int n) {
|
||||
int k, ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
k = (ix & 0x7f800000) >> 23;
|
||||
if (k == 0) {
|
||||
if ((ix & 0x7fffffff) == 0)
|
||||
return x;
|
||||
x *= audiobeam_two25;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
k = ((ix & 0x7f800000) >> 23) - 25;
|
||||
}
|
||||
if (k == 0xff)
|
||||
return x + x;
|
||||
k = k + n;
|
||||
if (n > 50000 || k > 0xfe)
|
||||
return audiobeam_huge * audiobeam___copysignf(audiobeam_huge, x);
|
||||
if (n < -50000)
|
||||
return audiobeam_tiny * audiobeam___copysignf(audiobeam_tiny, x);
|
||||
if (k > 0) {
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
|
||||
return x;
|
||||
}
|
||||
if (k <= -25)
|
||||
return audiobeam_tiny * audiobeam___copysignf(audiobeam_tiny, x);
|
||||
k += 25;
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
|
||||
return x * audiobeam_twom25;
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___ceilf(float x) {
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(i0, x);
|
||||
j0 = ((i0 >> 23) & 0xff) - 0x7f;
|
||||
if (j0 < 23) {
|
||||
if (j0 < 0) {
|
||||
if (audiobeam_huge + x > (float) 0.0) {
|
||||
if (i0 < 0)
|
||||
i0 = 0x80000000;
|
||||
else if (i0 != 0)
|
||||
i0 = 0x3f800000;
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff) >> j0;
|
||||
if ((i0 & i) == 0)
|
||||
return x;
|
||||
if (audiobeam_huge + x > (float) 0.0) {
|
||||
if (i0 > 0)
|
||||
i0 += (0x00800000) >> j0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (j0 == 0x80)
|
||||
return x + x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, i0);
|
||||
return x;
|
||||
}
|
||||
|
||||
float
|
||||
audiobeam___ieee754_sqrtf(float x) {
|
||||
float z;
|
||||
int sign = (int) 0x80000000;
|
||||
int ix, s, q, m, t, i;
|
||||
unsigned int r;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
|
||||
if ((ix & 0x7f800000) == 0x7f800000)
|
||||
return x * x + x;
|
||||
if (ix <= 0) {
|
||||
if ((ix & (~sign)) == 0)
|
||||
return x;
|
||||
else if (ix < 0)
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
m = (ix >> 23);
|
||||
if (m == 0) {
|
||||
__pragma_loopbound(0, 0);
|
||||
for (i = 0; (ix & 0x00800000) == 0; i++)
|
||||
ix <<= 1;
|
||||
m -= i - 1;
|
||||
}
|
||||
m -= 127;
|
||||
ix = (ix & 0x007fffff) | 0x00800000;
|
||||
if (m & 1)
|
||||
ix += ix;
|
||||
m >>= 1;
|
||||
|
||||
ix += ix;
|
||||
q = s = 0;
|
||||
r = 0x01000000;
|
||||
|
||||
__pragma_loopbound(25, 25);
|
||||
while (r != 0) {
|
||||
t = s + r;
|
||||
if (t <= ix) {
|
||||
s = t + r;
|
||||
ix -= t;
|
||||
q += r;
|
||||
}
|
||||
ix += ix;
|
||||
r >>= 1;
|
||||
}
|
||||
|
||||
if (ix != 0) {
|
||||
z = audiobeam_one - audiobeam_tiny;
|
||||
if (z >= audiobeam_one) {
|
||||
z = audiobeam_one + audiobeam_tiny;
|
||||
if (z > audiobeam_one)
|
||||
q += 2;
|
||||
else
|
||||
q += (q & 1);
|
||||
}
|
||||
}
|
||||
ix = (q >> 1) + 0x3f000000;
|
||||
ix += (m << 23);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(z, ix);
|
||||
return z;
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: quicksortlibm.c
|
||||
|
||||
Author: Ian Lance Taylor
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See audiobeamlibm.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_LIBM
|
||||
#define AUDIOBEAM_LIBM
|
||||
|
||||
#define audiobeam_M_PI 3.14159265358979323846
|
||||
|
||||
static const float audiobeam_one = 1.0f, audiobeam_tiny = 1.0e-30f,
|
||||
audiobeam_half = 5.0000000000e-01, /* 0x3f000000 */
|
||||
audiobeam_huge = 1.0e30, audiobeam_two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
audiobeam_twon8 = 3.9062500000e-03, /* 0x3b800000 */
|
||||
audiobeam_zero = 0.0;
|
||||
|
||||
#define audiobeam_cos audiobeam___cosf
|
||||
#define audiobeam_fabs audiobeam___fabsf
|
||||
#define audiobeam_fabsf audiobeam___fabsf
|
||||
#define audiobeam_isinf audiobeam___isinff
|
||||
#define audiobeam_sqrt audiobeam___ieee754_sqrtf
|
||||
#define audiobeam_ceil audiobeam___ceilf
|
||||
#define audiobeam_floor audiobeam___floorf
|
||||
|
||||
float audiobeam___copysignf(float x, float y);
|
||||
float audiobeam___cosf(float x);
|
||||
float audiobeam___fabsf(float x);
|
||||
float audiobeam___floorf(float x);
|
||||
int audiobeam___ieee754_rem_pio2f(float x, float *y);
|
||||
float audiobeam___ieee754_sqrtf(float x);
|
||||
int audiobeam___isinff(float x);
|
||||
float audiobeam___kernel_cosf(float x, float y);
|
||||
float audiobeam___kernel_sinf(float x, float y, int iy);
|
||||
int audiobeam___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec,
|
||||
const int *ipio2);
|
||||
float audiobeam___scalbnf(float x, int n);
|
||||
float audiobeam___ceilf(float x);
|
||||
float audiobeam___floorf(float x);
|
||||
|
||||
#endif // AUDIOBEAM_LIBM
|
||||
@ -0,0 +1,15 @@
|
||||
#include "audiobeamlibmalloc.h"
|
||||
|
||||
#define AUDIOBEAM_HEAP_SIZE 10000
|
||||
|
||||
static char audiobeam_simulated_heap[AUDIOBEAM_HEAP_SIZE];
|
||||
static unsigned int audiobeam_freeHeapPos;
|
||||
|
||||
void *
|
||||
audiobeam_malloc(unsigned int numberOfBytes) {
|
||||
void *currentPos =
|
||||
(void *) &audiobeam_simulated_heap[audiobeam_freeHeapPos];
|
||||
/* Get a 4-byte address for alignment purposes */
|
||||
audiobeam_freeHeapPos += ((numberOfBytes + 4) & (unsigned int) 0xfffffffc);
|
||||
return currentPos;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmalloc.c
|
||||
|
||||
Author: unkown
|
||||
|
||||
Function: Memory allocation.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: see license.txt
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MALLOC_H
|
||||
#define AUDIOBEAM_MALLOC_H
|
||||
|
||||
void *audiobeam_malloc(unsigned int numberOfBytes);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmath.h
|
||||
|
||||
Author: Unknown
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems
|
||||
|
||||
Original name: math_private.h
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from: @(#)fdlibm.h 5.1 93/09/24
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MATH_PRIVATE_H_
|
||||
#define AUDIOBEAM_MATH_PRIVATE_H_
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
|
||||
/* A union which permits us to convert between a float and a 32 bit
|
||||
int. */
|
||||
|
||||
typedef union {
|
||||
float value;
|
||||
unsigned int word;
|
||||
} audiobeam_ieee_float_shape_type;
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define AUDIOBEAM_GET_FLOAT_WORD(i, d) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
}
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define AUDIOBEAM_SET_FLOAT_WORD(d, i) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
}
|
||||
|
||||
#endif /* _MATH_PRIVATE_H_ */
|
||||
@ -0,0 +1,569 @@
|
||||
/*
|
||||
|
||||
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 "audiobeam.h"
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmalloc.h"
|
||||
|
||||
/*
|
||||
Forward declaration of functions
|
||||
*/
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
|
||||
#include "audiobeaminput.c"
|
||||
#include "audiobeamlibm.c"
|
||||
#include "audiobeamlibmalloc.c"
|
||||
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
__attribute__((always_inline)) static inline void audiobeam_init();
|
||||
__attribute__((always_inline)) static inline int audiobeam_return();
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
audiobeam_main(void);
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void);
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_preprocess_delays(struct audiobeam_PreprocessedDelays prep_delays[],
|
||||
float *delays);
|
||||
__attribute__((always_inline)) static inline float *
|
||||
audiobeam_parse_line(float *float_arr, int num_mic);
|
||||
__attribute__((always_inline)) static inline long int
|
||||
audiobeam_find_max_in_arr(float *arr, int size);
|
||||
__attribute__((always_inline)) static inline long int
|
||||
audiobeam_find_min_in_arr(float *arr, int size);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_inc_offset(int i, int offset, int max_i);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_dec_offset(int i, int offset, int max_i);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_inc(int i, int max_i);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_dec(int i, int max_i);
|
||||
__attribute__((always_inline)) static inline struct audiobeam_DataQueue *
|
||||
audiobeam_init_data_queue(int max_delay, int num_mic);
|
||||
__attribute__((always_inline)) static inline struct audiobeam_Delays *
|
||||
audiobeam_init_delays(int num_angles, int num_mic);
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_calc_distances(float *source_location,
|
||||
float audiobeam_mic_locations[15][3], float *distances,
|
||||
int num_mic);
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_calc_delays(float *distances, float *delays, int sound_speed,
|
||||
int sampling_rate, int num_mic);
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_adjust_delays(float *delays, int num_mic);
|
||||
__attribute__((always_inline)) static inline float *
|
||||
audiobeam_calc_weights_lr(int num_mic);
|
||||
__attribute__((always_inline)) static inline float *
|
||||
audiobeam_calc_weights_left_only(int num_mic);
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam_calculate_energy(float *samples, int num_samples);
|
||||
__attribute__((always_inline)) static inline float audiobeam_do_beamforming(
|
||||
struct audiobeam_PreprocessedDelays preprocessed_delays[],
|
||||
float **sample_queue, int queue_head, long int max_delay, int num_mic,
|
||||
float *weights);
|
||||
__attribute__((always_inline)) static inline 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);
|
||||
__attribute__((always_inline)) static inline 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);
|
||||
__attribute__((always_inline)) static inline 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
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) static inline 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(23040, 23040);
|
||||
for (i = 0; i < sizeof(audiobeam_input); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_mic_locations[0];
|
||||
__pragma_loopbound(180, 180);
|
||||
for (i = 0; i < sizeof(audiobeam_mic_locations); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_source_location[0];
|
||||
__pragma_loopbound(12, 12);
|
||||
for (i = 0; i < sizeof(audiobeam_source_location); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
|
||||
p = (unsigned char *) &audiobeam_origin_location[0];
|
||||
__pragma_loopbound(12, 12);
|
||||
for (i = 0; i < sizeof(audiobeam_origin_location); ++i, ++p)
|
||||
*p ^= bitmask;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_return() {
|
||||
return (audiobeam_checksum + 1 != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
Algorithm core functions
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_preprocess_delays(struct audiobeam_PreprocessedDelays prep_delays[],
|
||||
float *delays) {
|
||||
int i;
|
||||
|
||||
__pragma_loopbound(15, 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;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float *
|
||||
audiobeam_parse_line(float *float_arr, int num_mic) {
|
||||
int i;
|
||||
|
||||
__pragma_loopbound(15, 15);
|
||||
for (i = 0; i < num_mic; i++)
|
||||
float_arr[i] = audiobeam_input[audiobeam_input_pos++];
|
||||
|
||||
return float_arr;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline long int
|
||||
audiobeam_find_max_in_arr(float *arr, int size) {
|
||||
int i;
|
||||
float max = 0;
|
||||
|
||||
__pragma_loopbound(15, 15);
|
||||
for (i = 0; i < size; i++) {
|
||||
if (arr[i] > max)
|
||||
max = arr[i];
|
||||
}
|
||||
|
||||
return audiobeam_ceil(max);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline long int
|
||||
audiobeam_find_min_in_arr(float *arr, int size) {
|
||||
int i;
|
||||
float min = arr[0];
|
||||
|
||||
__pragma_loopbound(15, 15);
|
||||
for (i = 0; i < size; i++) {
|
||||
if (arr[i] < min)
|
||||
min = arr[i];
|
||||
}
|
||||
|
||||
return audiobeam_floor(min);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_inc(int i, int max_i) {
|
||||
return audiobeam_wrapped_inc_offset(i, 1, max_i);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam_wrapped_dec(int i, int max_i) {
|
||||
return audiobeam_wrapped_dec_offset(i, 1, max_i);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(15, 15);
|
||||
for (i = 0; i < (max_delay + 1); i++) {
|
||||
(queue->sample_queue)[i] =
|
||||
(float *) audiobeam_malloc(num_mic * sizeof(float));
|
||||
__pragma_loopbound(15, 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;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(1, 1);
|
||||
for (i = 0; i < (num_angles); i++) {
|
||||
delays->delay_values[i] =
|
||||
(float *) audiobeam_malloc(num_mic * sizeof(float));
|
||||
}
|
||||
|
||||
return delays;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_calc_distances(float *source_location,
|
||||
float audiobeam_mic_locations[15][3], float *distances,
|
||||
int num_mic) {
|
||||
int i;
|
||||
|
||||
__pragma_loopbound(15, 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])));
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
audiobeam_calc_delays(float *distances, float *delays, int sound_speed,
|
||||
int sampling_rate, int num_mic) {
|
||||
int i;
|
||||
|
||||
__pragma_loopbound(15, 15);
|
||||
for (i = 0; i < num_mic; i++)
|
||||
delays[i] = (distances[i] / sound_speed) * sampling_rate;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(15, 15);
|
||||
for (i = 0; i < num_mic; i++)
|
||||
delays[i] -= min_delay;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(0, 0);
|
||||
for (z = 1; z >= -1; z -= 2) {
|
||||
__pragma_loopbound(0, 0);
|
||||
for (y = 0; y < half; y++) {
|
||||
weights[index] =
|
||||
0.54 + 0.46 * audiobeam_cos(audiobeam_M_PI * y / half);
|
||||
index++;
|
||||
}
|
||||
__pragma_loopbound(0, 0);
|
||||
for (y = 0; y < half; y++) {
|
||||
weights[index] =
|
||||
0.54 + 0.46 * audiobeam_cos(audiobeam_M_PI * (-y) / half);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(15, 15);
|
||||
for (y = -half; y <= half; y++) {
|
||||
weights[index] = 0.54 + 0.46 * audiobeam_cos(audiobeam_M_PI * y / half);
|
||||
index++;
|
||||
}
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam_calculate_energy(float *samples, int num_samples) {
|
||||
int i;
|
||||
float sum = 0.0;
|
||||
|
||||
__pragma_loopbound(0, 0);
|
||||
for (i = 0; i < num_samples; i++)
|
||||
sum += (samples[i] * samples[i]);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(15, 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;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(13, 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(371, 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(1, 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);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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(1, 1);
|
||||
for (i = 0; i < num_beams; i++)
|
||||
energies[i] =
|
||||
audiobeam_calculate_energy(beamform_results[i], window);
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline 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
|
||||
*/
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
||||
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
||||
audiobeam_main(void) {
|
||||
char hamming = 1;
|
||||
audiobeam_calc_single_pos(audiobeam_source_location,
|
||||
audiobeam_mic_locations, hamming);
|
||||
}
|
||||
|
||||
__attribute__((noinline)) __attribute__((export_name("main")))
|
||||
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
||||
main(void) {
|
||||
audiobeam_init();
|
||||
audiobeam_main();
|
||||
|
||||
return (audiobeam_return());
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
|
||||
#ifndef AUDIOBEAM_MAIN_H
|
||||
#define AUDIOBEAM_MAIN_H
|
||||
|
||||
struct audiobeam_DataQueue {
|
||||
float **sample_queue;
|
||||
int head;
|
||||
int tail;
|
||||
unsigned char full;
|
||||
};
|
||||
|
||||
struct audiobeam_Delays {
|
||||
float **delay_values;
|
||||
long int max_delay;
|
||||
};
|
||||
|
||||
struct audiobeam_PreprocessedDelays {
|
||||
float delay;
|
||||
int low;
|
||||
int high;
|
||||
float offset;
|
||||
};
|
||||
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX 999e999
|
||||
|
||||
#define SOUND_SPEED 342
|
||||
#define SAMPLING_RATE 16000
|
||||
#define CARTESIAN_DISTANCE(x1, y1, z1, x2, y2, z2) \
|
||||
(sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + \
|
||||
(z1 - z2) * (z1 - z2)));
|
||||
|
||||
#define NUM_MIC 15
|
||||
#define ANGLE_ENERGY_WINDOW_SIZE 400
|
||||
#define GRID_STEP_SIZE 0.003 // .3cm
|
||||
#define NUM_DIRS 7
|
||||
#define NUM_TILES 16
|
||||
|
||||
#define MIC_HORIZ_SPACE 0.038257
|
||||
#define MIC_VERT_SPACE 0.015001
|
||||
#define TWO23 8388608.0 // 2^23
|
||||
#define BUFFER_SIZE 384 // No of input-tupels (each with NUM_MIC elements)
|
||||
#define NUM_MIC_IN_CHAIN 32
|
||||
#define NUM_BOARDS_IN_CHAIN 16
|
||||
#define INPUT_LENGTH 5760
|
||||
|
||||
#define INTERPOLATE(low_value, high_value, offset) \
|
||||
(((high_value - low_value) * (offset)) + low_value)
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,425 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibm.c
|
||||
|
||||
Author: Ian Lance Taylor and J.T. Conklin
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
#include "audiobeamlibmath.h"
|
||||
|
||||
// Wasm loop bounds
|
||||
|
||||
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
||||
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
||||
|
||||
static const int audiobeam_npio2_hw[] = {
|
||||
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
|
||||
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
|
||||
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
|
||||
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
|
||||
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
|
||||
0x4242c700, 0x42490f00};
|
||||
|
||||
static const float audiobeam_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
|
||||
audiobeam_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
|
||||
audiobeam_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
|
||||
audiobeam_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
|
||||
audiobeam_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
|
||||
audiobeam_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
|
||||
audiobeam_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
|
||||
|
||||
static const float audiobeam_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
|
||||
audiobeam_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
|
||||
audiobeam_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
|
||||
audiobeam_C4 = -2.7557314297e-07f, /* 0xb493f27c */
|
||||
audiobeam_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
|
||||
audiobeam_C6 = -1.1359647598e-11f; /* 0xad47d74e */
|
||||
|
||||
static const float audiobeam_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
|
||||
audiobeam_S2 = 8.3333337680e-03f, /* 0x3c088889 */
|
||||
audiobeam_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
|
||||
audiobeam_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
|
||||
audiobeam_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
|
||||
audiobeam_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
|
||||
|
||||
static const float audiobeam_two25 = 3.355443200e+07f, /* 0x4c000000 */
|
||||
audiobeam_twom25 = 2.9802322388e-08f; /* 0x33000000 */
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam___ieee754_rem_pio2f(float x, float *y) {
|
||||
float z, w, t, r, fn;
|
||||
int i, j, n = 0, ix, hx;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(hx, x);
|
||||
ix = hx & 0x7fffffff;
|
||||
if (ix <= 0x3f490fd8) {
|
||||
y[0] = x;
|
||||
y[1] = 0;
|
||||
return 0;
|
||||
}
|
||||
if (ix < 0x4016cbe4) {
|
||||
if (hx > 0) {
|
||||
z = x - audiobeam_pio2_1;
|
||||
if ((ix & 0xfffffff0) != 0x3fc90fd0) {
|
||||
y[0] = z - audiobeam_pio2_1t;
|
||||
y[1] = (z - y[0]) - audiobeam_pio2_1t;
|
||||
} else {
|
||||
z -= audiobeam_pio2_2;
|
||||
y[0] = z - audiobeam_pio2_2t;
|
||||
y[1] = (z - y[0]) - audiobeam_pio2_2t;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
z = x + audiobeam_pio2_1;
|
||||
if ((ix & 0xfffffff0) != 0x3fc90fd0) {
|
||||
y[0] = z + audiobeam_pio2_1t;
|
||||
y[1] = (z - y[0]) + audiobeam_pio2_1t;
|
||||
} else {
|
||||
z += audiobeam_pio2_2;
|
||||
y[0] = z + audiobeam_pio2_2t;
|
||||
y[1] = (z - y[0]) + audiobeam_pio2_2t;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (ix <= 0x43490f80) {
|
||||
t = audiobeam_fabsf(x);
|
||||
n = (int) (t * audiobeam_invpio2 + audiobeam_half);
|
||||
fn = (float) n;
|
||||
r = t - fn * audiobeam_pio2_1;
|
||||
w = fn * audiobeam_pio2_1t;
|
||||
if (n < 32 && (int) (ix & 0xffffff00) != audiobeam_npio2_hw[n - 1])
|
||||
y[0] = r - w;
|
||||
else {
|
||||
unsigned int high;
|
||||
j = ix >> 23;
|
||||
y[0] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(high, y[0]);
|
||||
i = j - ((high >> 23) & 0xff);
|
||||
if (i > 8) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_2;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_2t - ((t - r) - w);
|
||||
y[0] = r - w;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(high, y[0]);
|
||||
i = j - ((high >> 23) & 0xff);
|
||||
if (i > 25) {
|
||||
t = r;
|
||||
w = fn * audiobeam_pio2_3;
|
||||
r = t - w;
|
||||
w = fn * audiobeam_pio2_3t - ((t - r) - w);
|
||||
y[0] = r - w;
|
||||
}
|
||||
}
|
||||
}
|
||||
y[1] = (r - y[0]) - w;
|
||||
if (hx < 0) {
|
||||
y[0] = -y[0];
|
||||
y[1] = -y[1];
|
||||
return -n;
|
||||
} else
|
||||
return n;
|
||||
}
|
||||
if (ix >= 0x7f800000) {
|
||||
y[0] = y[1] = x - x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___kernel_cosf(float x, float y) {
|
||||
float a, hz, z, r, qx;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
ix &= 0x7fffffff;
|
||||
if (ix < 0x32000000) {
|
||||
if (((int) x) == 0)
|
||||
return audiobeam_one;
|
||||
}
|
||||
z = x * x;
|
||||
r = z * (audiobeam_C1 +
|
||||
z * (audiobeam_C2 +
|
||||
z * (audiobeam_C3 +
|
||||
z * (audiobeam_C4 +
|
||||
z * (audiobeam_C5 + z * audiobeam_C6)))));
|
||||
if (ix < 0x3e99999a)
|
||||
return audiobeam_one - ((float) 0.5f * z - (z * r - x * y));
|
||||
else {
|
||||
if (ix > 0x3f480000)
|
||||
qx = (float) 0.28125f;
|
||||
else
|
||||
AUDIOBEAM_SET_FLOAT_WORD(qx, ix - 0x01000000);
|
||||
hz = (float) 0.5f * z - qx;
|
||||
a = audiobeam_one - qx;
|
||||
return a - (hz - (z * r - x * y));
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___kernel_sinf(float x, float y, int iy) {
|
||||
float z, r, v;
|
||||
int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
ix &= 0x7fffffff;
|
||||
if (ix < 0x32000000) {
|
||||
if ((int) x == 0)
|
||||
return x;
|
||||
}
|
||||
z = x * x;
|
||||
v = z * x;
|
||||
r = audiobeam_S2 +
|
||||
z * (audiobeam_S3 +
|
||||
z * (audiobeam_S4 + z * (audiobeam_S5 + z * audiobeam_S6)));
|
||||
if (iy == 0)
|
||||
return x + v * (audiobeam_S1 + z * r);
|
||||
else
|
||||
return x - ((z * (audiobeam_half * y - v * r) - y) - v * audiobeam_S1);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___copysignf(float x, float y) {
|
||||
unsigned int ix, iy;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
AUDIOBEAM_GET_FLOAT_WORD(iy, y);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___cosf(float x) {
|
||||
float y[2], z = 0.0f;
|
||||
int n, ix;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
|
||||
ix &= 0x7fffffff;
|
||||
if (ix <= 0x3f490fd8)
|
||||
return audiobeam___kernel_cosf(x, z);
|
||||
|
||||
else if (ix >= 0x7f800000)
|
||||
return x - x;
|
||||
|
||||
else {
|
||||
y[0] = 0.0;
|
||||
y[1] = 0.0;
|
||||
n = audiobeam___ieee754_rem_pio2f(x, y);
|
||||
switch (n & 3) {
|
||||
case 0:
|
||||
return audiobeam___kernel_cosf(y[0], y[1]);
|
||||
case 1:
|
||||
return -audiobeam___kernel_sinf(y[0], y[1], 1);
|
||||
case 2:
|
||||
return -audiobeam___kernel_cosf(y[0], y[1]);
|
||||
default:
|
||||
return audiobeam___kernel_sinf(y[0], y[1], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___fabsf(float x) {
|
||||
unsigned int ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, ix & 0x7fffffff);
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___floorf(float x) {
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(i0, x);
|
||||
j0 = ((i0 >> 23) & 0xff) - 0x7f;
|
||||
if (j0 < 23) {
|
||||
if (j0 < 0) {
|
||||
if (audiobeam_huge + x > (float) 0.0f) {
|
||||
if (i0 >= 0)
|
||||
i0 = 0;
|
||||
else if ((i0 & 0x7fffffff) != 0)
|
||||
i0 = 0xbf800000;
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff) >> j0;
|
||||
if ((i0 & i) == 0)
|
||||
return x;
|
||||
if (audiobeam_huge + x > (float) 0.0f) {
|
||||
if (i0 < 0)
|
||||
i0 += (0x00800000) >> j0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (j0 == 0x80)
|
||||
return x + x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, i0);
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam___isinff(float x) {
|
||||
int ix, t;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
t = ix & 0x7fffffff;
|
||||
t ^= 0x7f800000;
|
||||
t |= -t;
|
||||
return ~(t >> 31) & (ix >> 30);
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___scalbnf(float x, int n) {
|
||||
int k, ix;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
k = (ix & 0x7f800000) >> 23;
|
||||
if (k == 0) {
|
||||
if ((ix & 0x7fffffff) == 0)
|
||||
return x;
|
||||
x *= audiobeam_two25;
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
k = ((ix & 0x7f800000) >> 23) - 25;
|
||||
}
|
||||
if (k == 0xff)
|
||||
return x + x;
|
||||
k = k + n;
|
||||
if (n > 50000 || k > 0xfe)
|
||||
return audiobeam_huge * audiobeam___copysignf(audiobeam_huge, x);
|
||||
if (n < -50000)
|
||||
return audiobeam_tiny * audiobeam___copysignf(audiobeam_tiny, x);
|
||||
if (k > 0) {
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
|
||||
return x;
|
||||
}
|
||||
if (k <= -25)
|
||||
return audiobeam_tiny * audiobeam___copysignf(audiobeam_tiny, x);
|
||||
k += 25;
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
|
||||
return x * audiobeam_twom25;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___ceilf(float x) {
|
||||
int i0, j0;
|
||||
unsigned int i;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(i0, x);
|
||||
j0 = ((i0 >> 23) & 0xff) - 0x7f;
|
||||
if (j0 < 23) {
|
||||
if (j0 < 0) {
|
||||
if (audiobeam_huge + x > (float) 0.0) {
|
||||
if (i0 < 0)
|
||||
i0 = 0x80000000;
|
||||
else if (i0 != 0)
|
||||
i0 = 0x3f800000;
|
||||
}
|
||||
} else {
|
||||
i = (0x007fffff) >> j0;
|
||||
if ((i0 & i) == 0)
|
||||
return x;
|
||||
if (audiobeam_huge + x > (float) 0.0) {
|
||||
if (i0 > 0)
|
||||
i0 += (0x00800000) >> j0;
|
||||
i0 &= (~i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (j0 == 0x80)
|
||||
return x + x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
AUDIOBEAM_SET_FLOAT_WORD(x, i0);
|
||||
return x;
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___ieee754_sqrtf(float x) {
|
||||
float z;
|
||||
int sign = (int) 0x80000000;
|
||||
int ix, s, q, m, t, i;
|
||||
unsigned int r;
|
||||
|
||||
AUDIOBEAM_GET_FLOAT_WORD(ix, x);
|
||||
|
||||
if ((ix & 0x7f800000) == 0x7f800000)
|
||||
return x * x + x;
|
||||
if (ix <= 0) {
|
||||
if ((ix & (~sign)) == 0)
|
||||
return x;
|
||||
else if (ix < 0)
|
||||
return (x - x) / (x - x);
|
||||
}
|
||||
m = (ix >> 23);
|
||||
if (m == 0) {
|
||||
__pragma_loopbound(0, 0);
|
||||
for (i = 0; (ix & 0x00800000) == 0; i++)
|
||||
ix <<= 1;
|
||||
m -= i - 1;
|
||||
}
|
||||
m -= 127;
|
||||
ix = (ix & 0x007fffff) | 0x00800000;
|
||||
if (m & 1)
|
||||
ix += ix;
|
||||
m >>= 1;
|
||||
|
||||
ix += ix;
|
||||
q = s = 0;
|
||||
r = 0x01000000;
|
||||
|
||||
__pragma_loopbound(25, 25);
|
||||
while (r != 0) {
|
||||
t = s + r;
|
||||
if (t <= ix) {
|
||||
s = t + r;
|
||||
ix -= t;
|
||||
q += r;
|
||||
}
|
||||
ix += ix;
|
||||
r >>= 1;
|
||||
}
|
||||
|
||||
if (ix != 0) {
|
||||
z = audiobeam_one - audiobeam_tiny;
|
||||
if (z >= audiobeam_one) {
|
||||
z = audiobeam_one + audiobeam_tiny;
|
||||
if (z > audiobeam_one)
|
||||
q += 2;
|
||||
else
|
||||
q += (q & 1);
|
||||
}
|
||||
}
|
||||
ix = (q >> 1) + 0x3f000000;
|
||||
ix += (m << 23);
|
||||
AUDIOBEAM_SET_FLOAT_WORD(z, ix);
|
||||
return z;
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: quicksortlibm.c
|
||||
|
||||
Author: Ian Lance Taylor
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See audiobeamlibm.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_LIBM
|
||||
#define AUDIOBEAM_LIBM
|
||||
|
||||
#define audiobeam_M_PI 3.14159265358979323846
|
||||
|
||||
static const float audiobeam_one = 1.0f, audiobeam_tiny = 1.0e-30f,
|
||||
audiobeam_half = 5.0000000000e-01, /* 0x3f000000 */
|
||||
audiobeam_huge = 1.0e30, audiobeam_two8 = 2.5600000000e+02, /* 0x43800000 */
|
||||
audiobeam_twon8 = 3.9062500000e-03, /* 0x3b800000 */
|
||||
audiobeam_zero = 0.0;
|
||||
|
||||
#define audiobeam_cos audiobeam___cosf
|
||||
#define audiobeam_fabs audiobeam___fabsf
|
||||
#define audiobeam_fabsf audiobeam___fabsf
|
||||
#define audiobeam_isinf audiobeam___isinff
|
||||
#define audiobeam_sqrt audiobeam___ieee754_sqrtf
|
||||
#define audiobeam_ceil audiobeam___ceilf
|
||||
#define audiobeam_floor audiobeam___floorf
|
||||
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___copysignf(float x, float y);
|
||||
__attribute__((always_inline)) static inline float audiobeam___cosf(float x);
|
||||
__attribute__((always_inline)) static inline float audiobeam___fabsf(float x);
|
||||
__attribute__((always_inline)) static inline float audiobeam___floorf(float x);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam___ieee754_rem_pio2f(float x, float *y);
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___ieee754_sqrtf(float x);
|
||||
__attribute__((always_inline)) static inline int audiobeam___isinff(float x);
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___kernel_cosf(float x, float y);
|
||||
__attribute__((always_inline)) static inline float
|
||||
audiobeam___kernel_sinf(float x, float y, int iy);
|
||||
__attribute__((always_inline)) static inline int
|
||||
audiobeam___kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec,
|
||||
const int *ipio2);
|
||||
__attribute__((always_inline)) static inline float audiobeam___scalbnf(float x,
|
||||
int n);
|
||||
__attribute__((always_inline)) static inline float audiobeam___ceilf(float x);
|
||||
__attribute__((always_inline)) static inline float audiobeam___floorf(float x);
|
||||
|
||||
#endif // AUDIOBEAM_LIBM
|
||||
@ -0,0 +1,15 @@
|
||||
#include "audiobeamlibmalloc.h"
|
||||
|
||||
#define AUDIOBEAM_HEAP_SIZE 10000
|
||||
|
||||
static char audiobeam_simulated_heap[AUDIOBEAM_HEAP_SIZE];
|
||||
static unsigned int audiobeam_freeHeapPos;
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
audiobeam_malloc(unsigned int numberOfBytes) {
|
||||
void *currentPos =
|
||||
(void *) &audiobeam_simulated_heap[audiobeam_freeHeapPos];
|
||||
/* Get a 4-byte address for alignment purposes */
|
||||
audiobeam_freeHeapPos += ((numberOfBytes + 4) & (unsigned int) 0xfffffffc);
|
||||
return currentPos;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmalloc.c
|
||||
|
||||
Author: unkown
|
||||
|
||||
Function: Memory allocation.
|
||||
|
||||
Source: Sun Microsystems and Cygnus
|
||||
|
||||
Original name: Unknown
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: see license.txt
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MALLOC_H
|
||||
#define AUDIOBEAM_MALLOC_H
|
||||
|
||||
__attribute__((always_inline)) static inline void *
|
||||
audiobeam_malloc(unsigned int numberOfBytes);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
This program is part of the TACLeBench benchmark suite.
|
||||
Version V 2.0
|
||||
|
||||
Name: audiobeamlibmath.h
|
||||
|
||||
Author: Unknown
|
||||
|
||||
Function: IEEE754 software library routines.
|
||||
|
||||
Source: Sun Microsystems
|
||||
|
||||
Original name: math_private.h
|
||||
|
||||
Changes: No major functional changes.
|
||||
|
||||
License: See the terms below.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
====================================================
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
====================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
from: @(#)fdlibm.h 5.1 93/09/24
|
||||
*/
|
||||
|
||||
#ifndef AUDIOBEAM_MATH_PRIVATE_H_
|
||||
#define AUDIOBEAM_MATH_PRIVATE_H_
|
||||
|
||||
#include "audiobeamlibm.h"
|
||||
|
||||
/* A union which permits us to convert between a float and a 32 bit
|
||||
int. */
|
||||
|
||||
typedef union {
|
||||
float value;
|
||||
unsigned int word;
|
||||
} audiobeam_ieee_float_shape_type;
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
|
||||
#define AUDIOBEAM_GET_FLOAT_WORD(i, d) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type gf_u; \
|
||||
gf_u.value = (d); \
|
||||
(i) = gf_u.word; \
|
||||
}
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
|
||||
#define AUDIOBEAM_SET_FLOAT_WORD(d, i) \
|
||||
{ \
|
||||
audiobeam_ieee_float_shape_type sf_u; \
|
||||
sf_u.word = (i); \
|
||||
(d) = sf_u.value; \
|
||||
}
|
||||
|
||||
#endif /* _MATH_PRIVATE_H_ */
|
||||
21
targets/wasm-tacle/sequential/audiobeam/license.txt
Executable file
21
targets/wasm-tacle/sequential/audiobeam/license.txt
Executable file
@ -0,0 +1,21 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Reference in New Issue
Block a user