Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 493afc06 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Automerger Merge Worker
Browse files

Merge "Add tee sink to SpdifStreamOut" into main am: 2c4386d4 am: 86639507

parents f6d4d4db 86639507
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ namespace android {
 "aftee_Date_ThreadId_C_reason.wav" RecordThread
 "aftee_Date_ThreadId_M_reason.wav" MixerThread (Normal)
 "aftee_Date_ThreadId_F_reason.wav" MixerThread (Fast)
 "aftee_Date_ThreadId_D_reason.raw" DirectOutputThread (SpdifStreamOut)
 "aftee_Date_ThreadId_TrackId_R_reason.wav" RecordTrack
 "aftee_Date_ThreadId_TrackId_TrackName_T_reason.wav" PlaybackTrack

@@ -120,7 +121,7 @@ private:
        return directory.size() > 0 && directory[0] == '/';
    }

    std::string generateFilename(const std::string &suffix) const {
    std::string generateFilename(const std::string &suffix, audio_format_t format) const {
        char fileTime[sizeof("YYYYmmdd_HHMMSS_\0")];
        struct timeval tv;
        gettimeofday(&tv, nullptr /* struct timezone */);
@@ -130,7 +131,7 @@ private:
            "incorrect fileTime buffer");
        char msec[4];
        (void)snprintf(msec, sizeof(msec), "%03d", (int)(tv.tv_usec / 1000));
        return mPrefix + fileTime + msec + suffix + ".wav";
        return mPrefix + fileTime + msec + suffix + (audio_is_linear_pcm(format) ? ".wav" : ".raw");
    }

    bool isManagedFilename(const char *name) {
@@ -225,7 +226,7 @@ void NBAIO_Tee::NBAIO_TeeImpl::dumpTee(
NBAIO_Tee::NBAIO_TeeImpl::NBAIO_SinkSource NBAIO_Tee::NBAIO_TeeImpl::makeSinkSource(
        const NBAIO_Format &format, size_t frames, bool *enabled)
{
    if (Format_isValid(format) && audio_is_linear_pcm(format.mFormat)) {
    if (Format_isValid(format) && audio_has_proportional_frames(format.mFormat)) {
        Pipe *pipe = new Pipe(frames, format);
        size_t numCounterOffers = 0;
        const NBAIO_Format offers[1] = {format};
@@ -259,7 +260,7 @@ std::string AudioFileHandler::create(
        audio_format_t format,
        const std::string &suffix)
{
    std::string filename = generateFilename(suffix);
    std::string filename = generateFilename(suffix, format);

    if (mThreadPool.launch(std::string("create ") + filename,
            [=]() { return createInternal(reader, sampleRate, channelCount, format, filename); })
@@ -406,6 +407,7 @@ status_t AudioFileHandler::createInternal(
    switch (format) {
    case AUDIO_FORMAT_PCM_8_BIT:
    case AUDIO_FORMAT_PCM_16_BIT:
    case AUDIO_FORMAT_IEC61937:
        sf_format = SF_FORMAT_PCM_16;
        writeFormat = AUDIO_FORMAT_PCM_16_BIT;
        ALOGV("%s: %s using PCM_16 for format %#x", __func__, filename.c_str(), format);
@@ -424,7 +426,6 @@ status_t AudioFileHandler::createInternal(
        break;
    default:
        // TODO:
        // handle audio_has_proportional_frames() formats.
        // handle compressed formats as single byte files.
        return BAD_VALUE;
    }
@@ -440,7 +441,7 @@ status_t AudioFileHandler::createInternal(
        .frames = 0,
        .samplerate = (int)sampleRate,
        .channels = (int)channelCount,
        .format = SF_FORMAT_WAV | sf_format,
        .format = sf_format | (audio_is_linear_pcm(format) ? SF_FORMAT_WAV : 0 /* RAW */),
    };
    SNDFILE *sf = sf_open(path.c_str(), SFM_WRITE, &info);
    if (sf == nullptr) {
@@ -463,7 +464,7 @@ status_t AudioFileHandler::createInternal(
        }

        // Convert input format to writeFormat as needed.
        if (format != writeFormat) {
        if (format != writeFormat && audio_is_linear_pcm(format)) {
            memcpy_by_audio_format(
                    buffer, writeFormat, buffer, format, actualRead * info.channels);
        }
+4 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ namespace android {
 *
 * Some AudioFlinger specific notes:
 *
 * 1) Tees capture only linear PCM data.
 * 1) Tees capture only linear PCM or IEC61937 data.
 * 2) Tees without any data written are considered empty and do not generate
 *    any output files.
 * 2) Once a Tee dumps data, it is considered "emptied" and new data
@@ -58,6 +58,7 @@ namespace android {
 *    WAV integer PCM 32 bit for AUDIO_FORMAT_PCM_8_24_BIT, AUDIO_FORMAT_PCM_24_BIT_PACKED
 *                               AUDIO_FORMAT_PCM_32_BIT.
 *    WAV float PCM 32 bit for AUDIO_FORMAT_PCM_FLOAT.
 *    RAW for AUDIO_FORMAT_IEC61937.
 *
 * Input_Thread:
 * 1) Capture buffer is teed when read from the HAL, before resampling for the AudioRecord
@@ -68,8 +69,8 @@ namespace android {
 *    NormalMixer output (if no FastMixer).
 * 2) DuplicatingThreads do not tee any mixed data. Apply a tee on the downstream OutputTrack
 *    or on the upstream playback Tracks.
 * 3) DirectThreads and OffloadThreads do not tee any data. The upstream track
 *    (if linear PCM format) may be teed to discover data.
 * 3) DirectThreads and OffloadThreads with SpdifStreamOut will tee IEC61937 wrapped data.
 *    Otherwise, the upstream track (if linear PCM format) may be teed to discover data.
 * 4) MmapThreads are not supported.
 *
 * Tracks:
+8 −0
Original line number Diff line number Diff line
@@ -55,10 +55,18 @@ cc_library {
    shared_libs: [
        "audioclient-types-aidl-cpp",
        "av-types-aidl-cpp",
        "libaudioflinger_utils", // NBAIO_Tee
        "libaudioprocessing",
        "libaudiospdif",
        "libaudioutils",
        "libbase",
        "libcutils",
        "liblog",
        "libnbaio",
        "libutils", // refbase
    ],

    include_dirs: [
        "frameworks/av/services/audioflinger",  // for configuration
    ],
}
+20 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

#define LOG_TAG "AudioFlinger"
//#define LOG_NDEBUG 0
#include "Configuration.h"
#include <system/audio.h>
#include <utils/Log.h>

@@ -96,6 +97,16 @@ status_t SpdifStreamOut::open(

    ALOGI("SpdifStreamOut::open() status = %d", status);

#ifdef TEE_SINK
    if (status == OK) {
        // Don't use PCM 16-bit format to avoid WAV encoding IEC61937 data.
        mTee.set(customConfig.sample_rate,
                audio_channel_count_from_out_mask(customConfig.channel_mask),
                AUDIO_FORMAT_IEC61937, NBAIO_Tee::TEE_FLAG_OUTPUT_THREAD);
        mTee.setId(std::string("_") + std::to_string(handle) + "_D");
    }
#endif

    return status;
}

@@ -113,7 +124,15 @@ int SpdifStreamOut::standby()

ssize_t SpdifStreamOut::writeDataBurst(const void* buffer, size_t bytes)
{
    return AudioStreamOut::write(buffer, bytes);
    const ssize_t written = AudioStreamOut::write(buffer, bytes);

#ifdef TEE_SINK
    if (written > 0) {
        mTee.write(reinterpret_cast<const char *>(buffer),
                written / AudioStreamOut::getFrameSize());
    }
#endif
    return written;
}

ssize_t SpdifStreamOut::write(const void* buffer, size_t numBytes)
+5 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include "AudioStreamOut.h"

#include <afutils/NBAIO_Tee.h>
#include <audio_utils/spdif/SPDIFEncoder.h>

namespace android {
@@ -121,6 +122,10 @@ private:
    ssize_t  writeDataBurst(const void* data, size_t bytes);
    ssize_t  writeInternal(const void* buffer, size_t bytes);

#ifdef TEE_SINK
    NBAIO_Tee mTee;
#endif

};

} // namespace android