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

Commit 2c4386d4 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Gerrit Code Review
Browse files

Merge "Add tee sink to SpdifStreamOut" into main

parents b78d96b0 ace1eebf
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