Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tinyhal: audio: Impl channel adjustment for input sound flow #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

AlexBobro
Copy link

Hello.

We have detected the issue on RCAR3 platform where high level applications can not capture a sound through Tinyhal with requested channel count less than 8. This occurs because the min-max interval for allowed channel count values
is set to [8..8] in 'pcm3168a' driver, so pcm_open() function returns error in case requested count != 8.
But only AUDIO_CHANNEL_IN_MONO & AUDIO_CHANNEL_IN_STEREO channel masks are supported by functionality in alsa_device_profile.c file ('alsa_utils' directory).
So it is required to apply the current patch, which provides a channel adjustment for input sound by converting the N-channel flow (N - supported by driver) to requested Mono or Stereo flow.
When this patch is merged, we will be able to fix described problem just by a setting IN_CHANNEL_COUNT_DEFAULT and
'in->hw_channel_count' to the value N supported by our driver.

audio/audio_hw.c Outdated Show resolved Hide resolved
audio/audio_hw.c Show resolved Hide resolved
@AlexBobro AlexBobro force-pushed the Impl_channel_adjustment_for_input branch from 4c88a65 to d04fa5d Compare November 13, 2020 11:06
Fix the issue where applications can not capture a sound through Tinyhal
with requested channel count less than 8 (the min/max interval for
allowed channel count values is set to [8..8] in 'pcm3168a' driver,
so pcm_open() function returns error in case count != 8).
Implement a patch that provides a channel adjustment for input sound
by converting the 8-channel flow to requested Mono or Stereo flow.

Signed-off-by: Oleksandr Bobro <oleksandr.bobro@globallogic.com>
@AlexBobro AlexBobro force-pushed the Impl_channel_adjustment_for_input branch from d04fa5d to e48358e Compare November 14, 2020 00:52
@AlexBobro
Copy link
Author

I have excluded from this PR the commits provided by @AntonDehtiarov in his PR#9.
Also I've rebased this PR onto current CirrusLogic/master.

@@ -76,6 +76,10 @@ ifeq ($(strip $(TINYHAL_COMPRESS_PLAYBACK)),true)
LOCAL_CFLAGS += -DTINYHAL_COMPRESS_PLAYBACK
endif

ifeq ($(TARGET_DEVICE),kingfisher)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't create defines and dependencies for a specific target. Make a generic define that describes the functionality it controls and define it in your device.mk. For example see the 3 defines above (lines 66..77)

@@ -76,6 +76,10 @@ ifeq ($(strip $(TINYHAL_COMPRESS_PLAYBACK)),true)
LOCAL_CFLAGS += -DTINYHAL_COMPRESS_PLAYBACK
endif

ifeq ($(TARGET_DEVICE),kingfisher)
LOCAL_CFLAGS += -DPLATFORM_RCAR3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and also use a generic name for this define instead of the name of a platform

#define IN_CHANNEL_MASK_DEFAULT AUDIO_CHANNEL_IN_STEREO
#define IN_CHANNEL_COUNT_DEFAULT 8
#define IN_RATE_DEFAULT 48000

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all a nasty hack, changing the default values to match some specific hardware instead of using the configuration.
The defaults are just that - defaults to use if nothing else is defined by the xml or driver.

The correct way to do this is use a defined constant in the xml file (https://github.com/CirrusLogic/tinyhal/blob/master/audio.example.xml#L342) to set the hardware channel count. Or read the limits from ALSA and work it out automatically.

Copy link
Contributor

@rfvirgil rfvirgil Dec 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use a <set> constant I suggest naming it "hw-channels"

goto fail;
}
}
else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferred style is

} else {

all on one line

@@ -1758,6 +1802,8 @@ static int do_open_pcm_input(struct stream_in_pcm *in)
fail:
pcm_close(in->pcm);
in->pcm = NULL;
if (in->pre_read_buf)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need to check for NULL pointer. It is safe to pass NULL to free()

@@ -2015,6 +2092,14 @@ static void do_close_in_pcm(struct audio_stream *stream)
{
struct stream_in_pcm *in = (struct stream_in_pcm *)stream;

ALOGV("do_close_in_pcm(%p)", in);
if (in && in->pre_read_buf)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need to check pre_read_buf for NULL. It is safe to pass NULL to free().

in->common.channel_count, in->hw_channel_count);
in->pre_read_buf_size = in->common.buffer_size * in->hw_channel_count / in->common.channel_count;
ALOGV("in->pre_read_buf_size=0x%zx", in->pre_read_buf_size);
in->pre_read_buf = calloc(1, in->pre_read_buf_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

malloc()?
The only reason I can see to use calloc() like this is to zero-fill the pre_read_buf. But it will be overwritten by the first pcm_read(). So the zero-fill is just overhead.

@@ -1874,10 +1922,39 @@ static ssize_t do_in_pcm_read(struct audio_stream_in *stream, void *buffer,
goto exit;
}

if (in->pre_read_buf) {
read_buf = in->pre_read_buf;
read_buf_size = in->pre_read_buf_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes bytes == (pre_read_buf_size / in->hw_channel_count) * in->common.channel_count
If it isn't, you'll read the wrong amount of data from ALSA. And also possibly adjust_channels() will fall off the end of buffer and overwrite memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants