xref: /btstack/test/avdtp/sine_encode_decode_performance_test.c (revision cd5f23a3250874824c01a2b3326a9522fea3f99f)
1 /*
2  * Copyright (C) 2016 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #include <stdio.h>
39 #include <math.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <portaudio.h>
43 
44 #include "btstack_sbc.h"
45 #include "avdtp.h"
46 #include "avdtp_source.h"
47 #include "btstack_stdin.h"
48 
49 #define NUM_CHANNELS        2
50 #define SAMPLE_RATE         44100
51 #define BYTES_PER_AUDIO_SAMPLE   (2*NUM_CHANNELS)
52 #define LATENCY             300 // ms
53 
54 #ifndef M_PI
55 #define M_PI  3.14159265
56 #endif
57 #define TABLE_SIZE_441HZ   100
58 
59 typedef struct {
60     int16_t source[TABLE_SIZE_441HZ];
61     int left_phase;
62     int right_phase;
63 } paTestData;
64 
65 static uint8_t pcm_frame[2*8*16*2];
66 
67 static paTestData sin_data;
68 
69 static btstack_sbc_mode_t mode = SBC_MODE_STANDARD;
70 static btstack_sbc_encoder_state_t sbc_encoder_state;
71 static btstack_sbc_decoder_state_t sbc_decoder_state;
72 
73 static void handle_pcm_data(int16_t * data, int num_samples, int num_channels, int sample_rate, void * context){
74     UNUSED(sample_rate);
75     UNUSED(context);
76     UNUSED(data);
77     UNUSED(num_samples);
78     UNUSED(num_channels);
79 }
80 
81 static void fill_sine_frame(void *userData, int num_samples_to_write){
82     paTestData *data = (paTestData*)userData;
83     int count = 0;
84     int offset = 0;
85     while (count < num_samples_to_write){
86         uint8_t write_data[BYTES_PER_AUDIO_SAMPLE];
87         *(int16_t*)&write_data[0] = data->source[data->left_phase];
88         *(int16_t*)&write_data[2] = data->source[data->right_phase];
89 
90         memcpy(pcm_frame+offset, write_data, BYTES_PER_AUDIO_SAMPLE);
91         offset += BYTES_PER_AUDIO_SAMPLE;
92         count++;
93 
94         data->left_phase += 1;
95         if (data->left_phase >= TABLE_SIZE_441HZ){
96             data->left_phase -= TABLE_SIZE_441HZ;
97         }
98         data->right_phase += 1;
99         if (data->right_phase >= TABLE_SIZE_441HZ){
100             data->right_phase -= TABLE_SIZE_441HZ;
101         }
102     }
103 }
104 
105 int btstack_main(int argc, const char * argv[]);
106 int btstack_main(int argc, const char * argv[]){
107     (void) argc;
108     (void) argv;
109     btstack_sbc_encoder_init(&sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, SBC_ALLOCATION_METHOD_LOUDNESS, 44100, 53, SBC_CHANNEL_MODE_STEREO);
110 
111     /* initialise sinusoidal wavetable */
112     int i;
113     for (i=0; i<TABLE_SIZE_441HZ; i++){
114         sin_data.source[i] = sin(((double)i/(double)TABLE_SIZE_441HZ) * M_PI * 2.)*32767;
115     }
116     sin_data.left_phase = sin_data.right_phase = 0;
117 
118     btstack_sbc_decoder_init(&sbc_decoder_state, mode, handle_pcm_data, NULL);
119     int num_frames = 10000;
120     uint32_t timestamp_start;
121     uint32_t encoding_time = 0;
122     uint32_t decoding_time = 0;
123 
124     timestamp_start = btstack_run_loop_get_time_ms();
125     for (i=0; i<num_frames; i++){
126         fill_sine_frame(&sin_data, 128);
127         btstack_sbc_encoder_process_data((int16_t *) pcm_frame);
128     }
129     encoding_time = btstack_run_loop_get_time_ms() - timestamp_start;
130 
131     timestamp_start = btstack_run_loop_get_time_ms();
132     for (i=0; i<num_frames; i++){
133         fill_sine_frame(&sin_data, 128);
134         btstack_sbc_encoder_process_data((int16_t *) pcm_frame);
135         btstack_sbc_decoder_process_data(&sbc_decoder_state, 0, btstack_sbc_encoder_sbc_buffer(), btstack_sbc_encoder_sbc_buffer_length());
136     }
137     decoding_time =  btstack_run_loop_get_time_ms() - timestamp_start - encoding_time;
138 
139     printf("%d frames encoded in %dms\n", num_frames, encoding_time);
140     printf("%d frames decoded in %dms\n", num_frames, decoding_time);
141 
142     exit(0);
143 }
144