Files
pawlet_rpi4/audio/include/core-impl/StreamPrimary.h
T
Konsta c72ec93b0b audio: probe pcm card from property
* Valid values for the audio device property are 'jack', 'hdmi0', 'hdmi1',
  and 'dac'.
* If 'jack' is selected, first PCM card with name 'Headphones' is used.
  If 'dac' is selected, first PCM card that doesn't match the name for 3.5mm
  or HDMI devices is used. HDMI audio uses virtual ALSA devices instead of
  using tinyalsa to open a PCM card directly.
* Allow forcing specific PCM card for debugging/development purposes.
* PCM card numbers are different between Pi 4 and Pi 5 and order can change
  depending on the DAC driver that's enabled.

Pi 4:

console:/ # cat /proc/asound/cards
 0 [Headphones     ]: bcm2835_headpho - bcm2835 Headphones
                      bcm2835 Headphones
 1 [vc4hdmi0       ]: vc4-hdmi - vc4-hdmi-0
                      vc4-hdmi-0
 2 [vc4hdmi1       ]: vc4-hdmi - vc4-hdmi-1
                      vc4-hdmi-1
Pi 5 with DAC:

console:/ # cat /proc/asound/cards
 0 [vc4hdmi0       ]: vc4-hdmi - vc4-hdmi-0
                      vc4-hdmi-0
 1 [vc4hdmi1       ]: vc4-hdmi - vc4-hdmi-1
                      vc4-hdmi-1
 2 [sndrpihifiberry]: HifiberryDacp - snd_rpi_hifiberry_dacplus
                      snd_rpi_hifiberry_dacplus
2025-11-06 13:18:21 +02:00

116 lines
4.4 KiB
C++

/*
* Copyright (C) 2023 The Android Open Source Project
* Copyright (C) 2025 KonstaKANG
*
* 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.
*/
#pragma once
#include <mutex>
#include <vector>
#include <android-base/thread_annotations.h>
#include "DriverStubImpl.h"
#include "StreamAlsa.h"
#include "primary/PrimaryMixer.h"
namespace aidl::android::hardware::audio::core {
class StreamPrimary : public StreamAlsa {
public:
StreamPrimary(StreamContext* context, const Metadata& metadata);
// Methods of 'DriverInterface'.
::android::status_t init(DriverCallbackInterface* callback) override;
::android::status_t drain(StreamDescriptor::DrainMode mode) override;
::android::status_t flush() override;
::android::status_t pause() override;
::android::status_t standby() override;
::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
::android::status_t refinePosition(StreamDescriptor::Position* position) override;
void shutdown() override;
// Overridden methods of 'StreamCommonImpl', called on a Binder thread.
ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
protected:
std::vector<alsa::DeviceProfile> getDeviceProfiles() override;
bool isStubStream();
const bool mIsAsynchronous;
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
bool mSkipNextTransfer = false;
private:
using AlsaDeviceId = std::pair<int, int>;
static constexpr StreamPrimary::AlsaDeviceId kDefaultCardAndDeviceId{
primary::PrimaryMixer::kAlsaCard, primary::PrimaryMixer::kAlsaDevice};
static constexpr StreamPrimary::AlsaDeviceId kStubDeviceId{
primary::PrimaryMixer::kInvalidAlsaCard, primary::PrimaryMixer::kInvalidAlsaDevice};
static AlsaDeviceId getCardId();
static AlsaDeviceId getCardAndDeviceId(
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices);
static bool useStubStream(bool isInput,
const ::aidl::android::media::audio::common::AudioDevice& device);
bool isStubStreamOnWorker() const { return mCurrAlsaDeviceId == kStubDeviceId; }
DriverStubImpl mStubDriver;
mutable std::mutex mLock;
AlsaDeviceId mAlsaDeviceId GUARDED_BY(mLock) = kStubDeviceId;
// Used by the worker thread only.
AlsaDeviceId mCurrAlsaDeviceId = kStubDeviceId;
};
class StreamInPrimary final : public StreamIn, public StreamPrimary, public StreamInHwGainHelper {
public:
friend class ndk::SharedRefBase;
StreamInPrimary(
StreamContext&& context,
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwGain(const std::vector<float>& in_channelGains) override;
};
class StreamOutPrimary final : public StreamOut,
public StreamPrimary,
public StreamOutHwVolumeHelper {
public:
friend class ndk::SharedRefBase;
StreamOutPrimary(StreamContext&& context,
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
offloadInfo);
private:
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
};
} // namespace aidl::android::hardware::audio::core