Skip to content

Commit

Permalink
add R2C FFT sample, fix sample formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
joesavage committed Jun 28, 2017
1 parent 91f48af commit 16accc6
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 26 deletions.
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.

INPUT = ../inc ../modules ../common ../README.md ../samples ../doc
INPUT = ../inc ../modules ../common ../README.md ../samples ../doc ../CONTRIBUTING.md

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
Expand Down
12 changes: 6 additions & 6 deletions samples/NE10_sample_complex_fft.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int complex_fft_sample_main(void)
ne10_fft_cpx_float32_t dst[SAMPLES]; // A destination array for the transformed data
ne10_fft_cfg_float32_t cfg; // An FFT "configuration structure"

// Initialise Ne10, using hardware auto-detection to set library function pointers.
// Initialise Ne10, using hardware auto-detection to set library function pointers
if (ne10_init() != NE10_OK)
{
fprintf(stderr, "Failed to initialise Ne10.\n");
Expand All @@ -51,17 +51,17 @@ int complex_fft_sample_main(void)
// Prepare the complex-to-complex single precision floating point FFT configuration
// structure for inputs of length `SAMPLES`. (You need only generate this once for a
// particular input size.)
cfg = ne10_fft_alloc_c2c_float32 (SAMPLES);
cfg = ne10_fft_alloc_c2c_float32(SAMPLES);

// Generate test input values (with both real and imaginary components)
for (int i = 0; i < SAMPLES; i++)
{
src[i].r = (ne10_float32_t) rand() / RAND_MAX * 50.0f;
src[i].i = (ne10_float32_t) rand() / RAND_MAX * 50.0f;
src[i].r = (ne10_float32_t)rand() / RAND_MAX * 50.0f;
src[i].i = (ne10_float32_t)rand() / RAND_MAX * 50.0f;
}

// Perform the FFT (for an IFFT, the last parameter should be `1`)
ne10_fft_c2c_1d_float32 (dst, src, cfg, 0);
ne10_fft_c2c_1d_float32(dst, src, cfg, 0);

// Display the results
for (int i = 0; i < SAMPLES; i++)
Expand All @@ -71,7 +71,7 @@ int complex_fft_sample_main(void)
}

// Free the allocated configuration structure
ne10_fft_destroy_c2c_float32 (cfg);
ne10_fft_destroy_c2c_float32(cfg);

return 0;
}
10 changes: 5 additions & 5 deletions samples/NE10_sample_fir.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int fir_sample_main(void)
ne10_float32_t coeffs[NUMTAPS]; // An array of FIR coefficients (in reverse order)
ne10_fir_instance_f32_t cfg; // An FIR "instance structure"

// Initialise Ne10, using hardware auto-detection to set library function pointers.
// Initialise Ne10, using hardware auto-detection to set library function pointers
if (ne10_init() != NE10_OK)
{
fprintf(stderr, "Failed to initialise Ne10.\n");
Expand All @@ -56,7 +56,7 @@ int fir_sample_main(void)
// Prepare the FIR instance structure, storing `NUMTAPS`, `coeffs`, and `st` within
// it, and clearing the state buffer. (For constant parameters, this process can
// instead be performed manually.)
if (ne10_fir_init_float (&cfg, NUMTAPS, coeffs, st, BLOCKSIZE) != NE10_OK)
if (ne10_fir_init_float(&cfg, NUMTAPS, coeffs, st, BLOCKSIZE) != NE10_OK)
{
fprintf(stderr, "Failed to initialise FIR instance structure.\n");
return 1;
Expand All @@ -65,20 +65,20 @@ int fir_sample_main(void)
// Generate test coefficient values
for (int i = 0; i < NUMTAPS; i++)
{
coeffs[i] = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
coeffs[i] = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
}

// Generate test input values
for (int i = 0; i < BUFFSIZE; i++)
{
src[i] = (ne10_float32_t) rand() / RAND_MAX * 20.0f;
src[i] = (ne10_float32_t)rand() / RAND_MAX * 20.0f;
}

// Perform the FIR filtering of the input buffer in `NUMBLOCKS` blocks of `BLOCKSIZE`
// elements using the parameters set up in the FIR instance structure `cfg`.
for (int b = 0; b < NUMBLOCKS; b++)
{
ne10_fir_float (&cfg, src + (b * BLOCKSIZE), dst + (b * BLOCKSIZE), BLOCKSIZE);
ne10_fir_float(&cfg, src + (b * BLOCKSIZE), dst + (b * BLOCKSIZE), BLOCKSIZE);
}

// Display the results (dst[i] = b[0] * src[i] + b[1] * src[i - 1] + b[2] * src[i - 2]
Expand Down
18 changes: 9 additions & 9 deletions samples/NE10_sample_intro.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* A simple example of using `ne10_addc_float`, an Ne10 function pointer that
* gets dynamically initialised to the most appropriate function for the hardware.
*/
void test_add_dynamic (void)
void test_add_dynamic(void)
{
ne10_float32_t src[ARR_LEN]; // A source array of scalar floats
ne10_float32_t cst; // A constant scalar to add to the elements in `src`
Expand All @@ -50,13 +50,13 @@ void test_add_dynamic (void)
// Generate test input values for `src` and `cst` using `rand()`
for (int i = 0; i < ARR_LEN; i++)
{
src[i] = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
src[i] = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
}
cst = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
cst = (ne10_float32_t)rand() / RAND_MAX * 5.0f;

// Perform the operation! This will use the NEON-optimised version of the function
// if NEON hardware has been detected, or will otherwise fall back to the C version.
ne10_addc_float (dst, src, cst, ARR_LEN);
ne10_addc_float(dst, src, cst, ARR_LEN);

// Display the results
printf("test_intro[test_add_dynamic]:\n");
Expand All @@ -70,7 +70,7 @@ void test_add_dynamic (void)
* A simple example of calling the C and NEON specific versions of Ne10 functions
* directly -- in this case, `ne10_addc_float_c` and `ne10_addc_float_neon`.
*/
void test_add_static (void)
void test_add_static(void)
{
ne10_float32_t src[ARR_LEN];
ne10_float32_t cst;
Expand All @@ -79,12 +79,12 @@ void test_add_static (void)

for (int i = 0; i < ARR_LEN; i++)
{
src[i] = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
src[i] = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
}
cst = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
cst = (ne10_float32_t)rand() / RAND_MAX * 5.0f;

ne10_addc_float_c (dst_c, src, cst, ARR_LEN);
ne10_addc_float_neon (dst_neon, src, cst, ARR_LEN);
ne10_addc_float_c(dst_c, src, cst, ARR_LEN);
ne10_addc_float_neon(dst_neon, src, cst, ARR_LEN);

printf("test_intro[test_add_static]:\n");
for (int i = 0; i < ARR_LEN; i++)
Expand Down
10 changes: 5 additions & 5 deletions samples/NE10_sample_matrix_multiply.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int matrix_multiply_sample_main(void)
ne10_mat3x3f_t mul[MATRICES]; // An array of matrices to multiply those in `src` by
ne10_mat3x3f_t dst[MATRICES]; // A destination array for the multiplication results

// Initialise Ne10, using hardware auto-detection to set library function pointers.
// Initialise Ne10, using hardware auto-detection to set library function pointers
if (ne10_init() != NE10_OK)
{
fprintf(stderr, "Failed to initialise Ne10.\n");
Expand All @@ -59,7 +59,7 @@ int matrix_multiply_sample_main(void)
}

// Perform the multiplication of the matrices in `src` by those in `mul`
ne10_mulmat_3x3f (dst, src, mul, MATRICES);
ne10_mulmat_3x3f(dst, src, mul, MATRICES);

// Display the results (src[i] * mul[i] == dst[i])
for (int i = 0; i < MATRICES; i++)
Expand Down Expand Up @@ -91,7 +91,7 @@ void initialise_matrix(ne10_mat3x3f_t *mat)

void initialise_matrix_column(ne10_mat_row3f *col)
{
col->r1 = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
col->r2 = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
col->r3 = (ne10_float32_t) rand() / RAND_MAX * 5.0f;
col->r1 = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
col->r2 = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
col->r3 = (ne10_float32_t)rand() / RAND_MAX * 5.0f;
}
78 changes: 78 additions & 0 deletions samples/NE10_sample_real_fft.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2011-16 ARM Limited and Contributors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of ARM Limited nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ARM LIMITED AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>

#include "NE10.h"

#define SAMPLES 16

/**
* @example NE10_sample_real_fft.c
* An example of using the real-to-complex FFT functions.
*/
int real_fft_sample_main(void)
{
ne10_float32_t src[SAMPLES] = {}; // A source array of input data
ne10_fft_cpx_float32_t dst[(SAMPLES / 2) + 1] = {}; // A destination array for the transformed data
ne10_fft_r2c_cfg_float32_t cfg; // An FFT "configuration structure"

// Initialise Ne10, using hardware auto-detection to set library function pointers
if (ne10_init() != NE10_OK)
{
fprintf(stderr, "Failed to initialise Ne10.\n");
return 1;
}

// Prepare the real-to-complex single precision floating point FFT configuration
// structure for inputs of length `SAMPLES`. (You need only generate this once for a
// particular input size.)
cfg = ne10_fft_alloc_r2c_float32(SAMPLES);

// Generate test input values
for (int i = 0; i < SAMPLES; i++)
{
src[i] = (ne10_float32_t)rand() / RAND_MAX * 50.0f;
}

// Perform the FFT
ne10_fft_r2c_1d_float32(dst, src, cfg);

// Display the results
for (int i = 0; i < SAMPLES; i++)
{
printf( "IN[%2d]: %10.4f\t", i, src[i]);
if (i <= SAMPLES / 2)
printf("OUT[%2d]: %10.4f + %10.4fi", i, dst[i].r, dst[i].i);
printf("\n");
}

// Free the allocated configuration structure
ne10_fft_destroy_r2c_float32(cfg);

return 0;
}
5 changes: 5 additions & 0 deletions samples/NE10_samples.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
int intro_sample_main(void);
int matrix_multiply_sample_main(void);
int complex_fft_sample_main(void);
int real_fft_sample_main(void);
int fir_sample_main(void);

/*
Expand All @@ -57,6 +58,10 @@ int main(void)
complex_fft_sample_main();
printf("\n");

printf("# Real-to-Complex FFT\n");
real_fft_sample_main();
printf("\n");

printf("# FIR\n");
fir_sample_main();
printf("\n");
Expand Down

0 comments on commit 16accc6

Please sign in to comment.