You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
7.0 KiB
200 lines
7.0 KiB
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef ANDROID_AUDIO_BUFLOG_H
|
|
#define ANDROID_AUDIO_BUFLOG_H
|
|
|
|
/*
|
|
* BUFLOG creates up to BUFLOG_MAXSTREAMS simultaneous streams [0:15] of audio buffer data
|
|
* and saves them to disk. The files are stored in the path specified in BUFLOG_BASE_PATH and
|
|
* are named following this format:
|
|
* YYYYMMDDHHMMSS_id_format_channels_samplingrate.raw
|
|
*
|
|
* Normally we strip BUFLOG dumps from release builds.
|
|
* You can modify this (for example with "#define BUFLOG_NDEBUG 0"
|
|
* at the top of your source file) to change that behavior.
|
|
*
|
|
* usage:
|
|
* - Add this to the top of the source file you want to debug:
|
|
* #define BUFLOG_NDEBUG 0
|
|
* #include "BufLog.h"
|
|
*
|
|
* - dump an audio buffer
|
|
* BUFLOG(buff_id, buff_tag, format, channels, sampling_rate, max_bytes, buff_pointer, buff_size);
|
|
*
|
|
* buff_id: int [0:15] buffer id. If a buffer doesn't exist, it is created the first time.
|
|
* buff_tag: char* string tag used on stream filename and logs
|
|
* format: int Audio format (audio_format_t see audio.h)
|
|
* channels: int Channel Count
|
|
* sampling_rate: int Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
|
|
* max_bytes: int [0 or positive number]
|
|
* Maximum size of the file (in bytes) to be output.
|
|
* If the value is 0, no limit.
|
|
* buff_pointer: void * Pointer to audio buffer.
|
|
* buff_size: int Size (in bytes) of the current audio buffer to be stored.
|
|
*
|
|
*
|
|
* Example usage:
|
|
* int format = mConfig.outputCfg.format;
|
|
* int channels = audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
|
|
* int samplingRate = mConfig.outputCfg.samplingRate;
|
|
* int frameCount = mConfig.outputCfg.buffer.frameCount;
|
|
* int frameSize = audio_bytes_per_sample((audio_format_t)format) * channels;
|
|
* int buffSize = frameCount * frameSize;
|
|
* long maxBytes = 10 * samplingRate * frameSize; //10 seconds max
|
|
* BUFLOG(11, "loudnes_enhancer_out", format, channels, samplingRate, maxBytes,
|
|
* mConfig.outputCfg.buffer.raw, buffSize);
|
|
*
|
|
* Other macros:
|
|
* BUFLOG_EXISTS returns true if there is an instance of BufLog
|
|
*
|
|
* BUFLOG_RESET If an instance of BufLog exists, it stops the capture and closes all
|
|
* streams.
|
|
* If a new call to BUFLOG(..) is done, new streams are created.
|
|
*/
|
|
|
|
#ifndef BUFLOG_NDEBUG
|
|
#ifdef NDEBUG
|
|
#define BUFLOG_NDEBUG 1
|
|
#else
|
|
#define BUFLOG_NDEBUG 0
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
* Simplified macro to send a buffer.
|
|
*/
|
|
#ifndef BUFLOG
|
|
#define __BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
|
|
BufLogSingleton::instance()->write(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, \
|
|
BUF, SIZE)
|
|
#if BUFLOG_NDEBUG
|
|
#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
|
|
do { if (0) { } } while (0)
|
|
#else
|
|
#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
|
|
__BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE)
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef BUFLOG_EXISTS
|
|
#define BUFLOG_EXISTS BufLogSingleton::instanceExists()
|
|
#endif
|
|
|
|
#ifndef BUFLOG_RESET
|
|
#define BUFLOG_RESET do { if (BufLogSingleton::instanceExists()) { \
|
|
BufLogSingleton::instance()->reset(); } } while (0)
|
|
#endif
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <utils/Mutex.h>
|
|
|
|
//BufLog configuration
|
|
#define BUFLOGSTREAM_MAX_TAGSIZE 32
|
|
#define BUFLOG_BASE_PATH "/data/misc/audioserver"
|
|
#define BUFLOG_MAX_PATH_SIZE 300
|
|
|
|
class BufLogStream {
|
|
public:
|
|
BufLogStream(unsigned int id,
|
|
const char *tag,
|
|
unsigned int format,
|
|
unsigned int channels,
|
|
unsigned int samplingRate,
|
|
size_t maxBytes);
|
|
~BufLogStream();
|
|
|
|
// write buffer to stream
|
|
// buf: pointer to buffer
|
|
// size: number of bytes to write
|
|
size_t write(const void *buf, size_t size);
|
|
|
|
// pause/resume stream
|
|
// pause: true = paused, false = not paused
|
|
// return value: previous state of stream (paused or not).
|
|
bool setPause(bool pause);
|
|
|
|
// will stop the stream and close any open file
|
|
// the stream can't be reopen. Instead, a new stream (and file) should be created.
|
|
void finalize();
|
|
|
|
private:
|
|
bool mPaused;
|
|
const unsigned int mId;
|
|
char mTag[BUFLOGSTREAM_MAX_TAGSIZE + 1];
|
|
const unsigned int mFormat;
|
|
const unsigned int mChannels;
|
|
const unsigned int mSamplingRate;
|
|
const size_t mMaxBytes;
|
|
size_t mByteCount;
|
|
FILE *mFile;
|
|
mutable android::Mutex mLock;
|
|
|
|
void closeStream_l();
|
|
};
|
|
|
|
|
|
class BufLog {
|
|
public:
|
|
BufLog();
|
|
~BufLog();
|
|
BufLog(BufLog const&) {};
|
|
|
|
// streamid: int [0:BUFLOG_MAXSTREAMS-1] buffer id.
|
|
// If a buffer doesn't exist, it is created the first time is referenced
|
|
// tag: char* string tag used on stream filename and logs
|
|
// format: int Audio format (audio_format_t see audio.h)
|
|
// channels: int Channel Count
|
|
// samplingRate: int Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
|
|
// maxBytes: int [0 or positive number]
|
|
// Maximum size of the file (in bytes) to be output.
|
|
// If the value is 0, no limit.
|
|
// size: int Size (in bytes) of the current audio buffer to be written.
|
|
// buf: void * Pointer to audio buffer.
|
|
size_t write(int streamid,
|
|
const char *tag,
|
|
int format,
|
|
int channels,
|
|
int samplingRate,
|
|
size_t maxBytes,
|
|
const void *buf,
|
|
size_t size);
|
|
|
|
// reset will stop and close all active streams, thus finalizing any open file.
|
|
// New streams will be created if write() is called again.
|
|
void reset();
|
|
|
|
protected:
|
|
static const unsigned int BUFLOG_MAXSTREAMS = 16;
|
|
BufLogStream *mStreams[BUFLOG_MAXSTREAMS];
|
|
mutable android::Mutex mLock;
|
|
};
|
|
|
|
class BufLogSingleton {
|
|
public:
|
|
static BufLog *instance();
|
|
static bool instanceExists();
|
|
|
|
private:
|
|
static void initOnce();
|
|
static BufLog *mInstance;
|
|
};
|
|
|
|
#endif //ANDROID_AUDIO_BUFLOG_H
|