Loading services/audioflinger/afutils/NBAIO_Tee.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */); Loading @@ -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) { Loading Loading @@ -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}; Loading Loading @@ -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); }) Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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) { Loading @@ -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); } Loading services/audioflinger/afutils/NBAIO_Tee.h +4 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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: Loading services/audioflinger/datapath/Android.bp +8 −0 Original line number Diff line number Diff line Loading @@ -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 ], } services/audioflinger/datapath/SpdifStreamOut.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "AudioFlinger" //#define LOG_NDEBUG 0 #include "Configuration.h" #include <system/audio.h> #include <utils/Log.h> Loading Loading @@ -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; } Loading @@ -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) Loading services/audioflinger/datapath/SpdifStreamOut.h +5 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "AudioStreamOut.h" #include <afutils/NBAIO_Tee.h> #include <audio_utils/spdif/SPDIFEncoder.h> namespace android { Loading Loading @@ -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 Loading Loading
services/audioflinger/afutils/NBAIO_Tee.cpp +8 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 */); Loading @@ -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) { Loading Loading @@ -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}; Loading Loading @@ -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); }) Loading Loading @@ -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); Loading @@ -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; } Loading @@ -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) { Loading @@ -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); } Loading
services/audioflinger/afutils/NBAIO_Tee.h +4 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading @@ -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: Loading
services/audioflinger/datapath/Android.bp +8 −0 Original line number Diff line number Diff line Loading @@ -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 ], }
services/audioflinger/datapath/SpdifStreamOut.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "AudioFlinger" //#define LOG_NDEBUG 0 #include "Configuration.h" #include <system/audio.h> #include <utils/Log.h> Loading Loading @@ -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; } Loading @@ -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) Loading
services/audioflinger/datapath/SpdifStreamOut.h +5 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "AudioStreamOut.h" #include <afutils/NBAIO_Tee.h> #include <audio_utils/spdif/SPDIFEncoder.h> namespace android { Loading Loading @@ -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 Loading