Loading system/audio_a2dp_hw/audio_a2dp_hw.cc +114 −4 Original line number Diff line number Diff line Loading @@ -150,6 +150,10 @@ struct a2dp_stream_in { *****************************************************************************/ static size_t out_get_buffer_size(const struct audio_stream* stream); static size_t audio_stream_compute_buffer_size( btav_a2dp_codec_sample_rate_t codec_sample_rate, btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample, btav_a2dp_codec_channel_mode_t codec_channel_mode); /***************************************************************************** * Externs Loading Loading @@ -607,6 +611,9 @@ static int a2dp_read_output_audio_config( common->cfg.rate = stream_config.rate; common->cfg.channel_mask = stream_config.channel_mask; common->cfg.format = stream_config.format; common->buffer_sz = audio_stream_compute_buffer_size( codec_config->sample_rate, codec_config->bits_per_sample, codec_config->channel_mode); } INFO( Loading Loading @@ -712,8 +719,8 @@ static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) { /* retry logic to catch any timing variations on control channel */ for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) { /* connect control channel if not already connected */ if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0) { if ((common->ctrl_fd = skt_connect( A2DP_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) > 0) { /* success, now check if stack is ready */ if (check_a2dp_ready(common) == 0) break; Loading Loading @@ -927,6 +934,106 @@ static size_t out_get_buffer_size(const struct audio_stream* stream) { return period_size; } static size_t audio_stream_compute_buffer_size( btav_a2dp_codec_sample_rate_t codec_sample_rate, btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample, btav_a2dp_codec_channel_mode_t codec_channel_mode) { size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value const uint32_t time_period_ms = 20; // Conservative 20ms uint32_t sample_rate; uint32_t bits_per_sample; uint32_t number_of_channels; // Check the codec config sample rate switch (codec_sample_rate) { case BTAV_A2DP_CODEC_SAMPLE_RATE_44100: sample_rate = 44100; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_48000: sample_rate = 48000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_88200: sample_rate = 88200; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_96000: sample_rate = 96000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_176400: sample_rate = 176400; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_192000: sample_rate = 192000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE: default: ERROR("Invalid sample rate: 0x%x", codec_sample_rate); return buffer_sz; } // Check the codec config bits per sample switch (codec_bits_per_sample) { case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16: bits_per_sample = 16; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24: bits_per_sample = 24; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32: bits_per_sample = 32; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE: default: ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample); return buffer_sz; } // Check the codec config channel mode switch (codec_channel_mode) { case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO: number_of_channels = 1; break; case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO: number_of_channels = 2; break; case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE: default: ERROR("Invalid channel mode: 0x%x", codec_channel_mode); return buffer_sz; } // // The buffer size is computed by using the following formula: // // AUDIO_STREAM_OUTPUT_BUFFER_SIZE = // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000 // // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers // data in chunks of // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) . // If the number of periods is 2, the socket buffer represents "double // buffering" of the AudioFlinger mixer buffer. // // Furthermore, the AudioFlinger expects the buffer size to be a multiple // of 16 frames. const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * number_of_channels * bits_per_sample) / 8; buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate * number_of_channels * (bits_per_sample / 8)) / 1000; // Adjust the buffer size so it can be divided by the divisor const size_t remainder = buffer_sz % divisor; if (remainder != 0) { buffer_sz += divisor - remainder; } return buffer_sz; } static uint32_t out_get_channels(const struct audio_stream* stream) { struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream; Loading Loading @@ -1434,8 +1541,11 @@ static int adev_open_output_stream(struct audio_hw_device* dev, config->channel_mask = out_get_channels((const struct audio_stream*)&out->stream); INFO("Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x", config->format, config->sample_rate, config->channel_mask); INFO( "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x " "buffer_sz=%zu", config->format, config->sample_rate, config->channel_mask, out->common.buffer_sz); } *stream_out = &out->stream; a2dp_dev->output = out; Loading system/audio_a2dp_hw/audio_a2dp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ // resulting in mixer sleep and throttling. We increase this to 28 * 512 to help // reduce the effect of variable data consumption. #define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512) #define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256 // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided // for AudioFlinger data delivery. The AudioFlinger mixer delivers data in Loading system/udrv/ulinux/uipc_linux.hdeleted 100644 → 0 +0 −34 Original line number Diff line number Diff line /****************************************************************************** * * Copyright (C) 2007-2012 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #ifndef _UIPC_LINUX_H_ #define _UIPC_LINUX_H_ typedef int SOCKET; #define INVALID_SOCKET (SOCKET)(-1) #define SOCKET_ERROR (-1) /* tcp/ip socket configuration */ typedef struct { char* p_address; unsigned int port; } tUIPC_LINUX_CFG_TCP; /* Socket configuration for GLGPS interface */ extern tUIPC_LINUX_CFG_TCP uipc_linux_cfg_glgps; #endif /* _UIPC_LINUX_H_ */ Loading
system/audio_a2dp_hw/audio_a2dp_hw.cc +114 −4 Original line number Diff line number Diff line Loading @@ -150,6 +150,10 @@ struct a2dp_stream_in { *****************************************************************************/ static size_t out_get_buffer_size(const struct audio_stream* stream); static size_t audio_stream_compute_buffer_size( btav_a2dp_codec_sample_rate_t codec_sample_rate, btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample, btav_a2dp_codec_channel_mode_t codec_channel_mode); /***************************************************************************** * Externs Loading Loading @@ -607,6 +611,9 @@ static int a2dp_read_output_audio_config( common->cfg.rate = stream_config.rate; common->cfg.channel_mask = stream_config.channel_mask; common->cfg.format = stream_config.format; common->buffer_sz = audio_stream_compute_buffer_size( codec_config->sample_rate, codec_config->bits_per_sample, codec_config->channel_mode); } INFO( Loading Loading @@ -712,8 +719,8 @@ static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) { /* retry logic to catch any timing variations on control channel */ for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) { /* connect control channel if not already connected */ if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0) { if ((common->ctrl_fd = skt_connect( A2DP_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) > 0) { /* success, now check if stack is ready */ if (check_a2dp_ready(common) == 0) break; Loading Loading @@ -927,6 +934,106 @@ static size_t out_get_buffer_size(const struct audio_stream* stream) { return period_size; } static size_t audio_stream_compute_buffer_size( btav_a2dp_codec_sample_rate_t codec_sample_rate, btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample, btav_a2dp_codec_channel_mode_t codec_channel_mode) { size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value const uint32_t time_period_ms = 20; // Conservative 20ms uint32_t sample_rate; uint32_t bits_per_sample; uint32_t number_of_channels; // Check the codec config sample rate switch (codec_sample_rate) { case BTAV_A2DP_CODEC_SAMPLE_RATE_44100: sample_rate = 44100; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_48000: sample_rate = 48000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_88200: sample_rate = 88200; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_96000: sample_rate = 96000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_176400: sample_rate = 176400; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_192000: sample_rate = 192000; break; case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE: default: ERROR("Invalid sample rate: 0x%x", codec_sample_rate); return buffer_sz; } // Check the codec config bits per sample switch (codec_bits_per_sample) { case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16: bits_per_sample = 16; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24: bits_per_sample = 24; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32: bits_per_sample = 32; break; case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE: default: ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample); return buffer_sz; } // Check the codec config channel mode switch (codec_channel_mode) { case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO: number_of_channels = 1; break; case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO: number_of_channels = 2; break; case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE: default: ERROR("Invalid channel mode: 0x%x", codec_channel_mode); return buffer_sz; } // // The buffer size is computed by using the following formula: // // AUDIO_STREAM_OUTPUT_BUFFER_SIZE = // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000 // // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers // data in chunks of // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) . // If the number of periods is 2, the socket buffer represents "double // buffering" of the AudioFlinger mixer buffer. // // Furthermore, the AudioFlinger expects the buffer size to be a multiple // of 16 frames. const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * number_of_channels * bits_per_sample) / 8; buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate * number_of_channels * (bits_per_sample / 8)) / 1000; // Adjust the buffer size so it can be divided by the divisor const size_t remainder = buffer_sz % divisor; if (remainder != 0) { buffer_sz += divisor - remainder; } return buffer_sz; } static uint32_t out_get_channels(const struct audio_stream* stream) { struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream; Loading Loading @@ -1434,8 +1541,11 @@ static int adev_open_output_stream(struct audio_hw_device* dev, config->channel_mask = out_get_channels((const struct audio_stream*)&out->stream); INFO("Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x", config->format, config->sample_rate, config->channel_mask); INFO( "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x " "buffer_sz=%zu", config->format, config->sample_rate, config->channel_mask, out->common.buffer_sz); } *stream_out = &out->stream; a2dp_dev->output = out; Loading
system/audio_a2dp_hw/audio_a2dp_hw.h +1 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ // resulting in mixer sleep and throttling. We increase this to 28 * 512 to help // reduce the effect of variable data consumption. #define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512) #define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256 // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided // for AudioFlinger data delivery. The AudioFlinger mixer delivers data in Loading
system/udrv/ulinux/uipc_linux.hdeleted 100644 → 0 +0 −34 Original line number Diff line number Diff line /****************************************************************************** * * Copyright (C) 2007-2012 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #ifndef _UIPC_LINUX_H_ #define _UIPC_LINUX_H_ typedef int SOCKET; #define INVALID_SOCKET (SOCKET)(-1) #define SOCKET_ERROR (-1) /* tcp/ip socket configuration */ typedef struct { char* p_address; unsigned int port; } tUIPC_LINUX_CFG_TCP; /* Socket configuration for GLGPS interface */ extern tUIPC_LINUX_CFG_TCP uipc_linux_cfg_glgps; #endif /* _UIPC_LINUX_H_ */