blob: 1b402f47d3ef5c5bb308380f67efabe67ae51c36 [file] [log] [blame]
rago3bd1c872016-09-26 12:58:14 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIO_BUFLOG_H
18#define ANDROID_AUDIO_BUFLOG_H
19
20/*
21 * BUFLOG creates up to BUFLOG_MAXSTREAMS simultaneous streams [0:15] of audio buffer data
22 * and saves them to disk. The files are stored in the path specified in BUFLOG_BASE_PATH and
23 * are named following this format:
24 * YYYYMMDDHHMMSS_id_format_channels_samplingrate.raw
25 *
26 * Normally we strip BUFLOG dumps from release builds.
27 * You can modify this (for example with "#define BUFLOG_NDEBUG 0"
28 * at the top of your source file) to change that behavior.
29 *
30 * usage:
31 * - Add this to the top of the source file you want to debug:
32 * #define BUFLOG_NDEBUG 0
33 * #include "BufLog.h"
34 *
35 * - dump an audio buffer
36 * BUFLOG(buff_id, buff_tag, format, channels, sampling_rate, max_bytes, buff_pointer, buff_size);
37 *
38 * buff_id: int [0:15] buffer id. If a buffer doesn't exist, it is created the first time.
39 * buff_tag: char* string tag used on stream filename and logs
40 * format: int Audio format (audio_format_t see audio.h)
41 * channels: int Channel Count
42 * sampling_rate: int Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
43 * max_bytes: int [0 or positive number]
44 * Maximum size of the file (in bytes) to be output.
45 * If the value is 0, no limit.
46 * buff_pointer: void * Pointer to audio buffer.
47 * buff_size: int Size (in bytes) of the current audio buffer to be stored.
48 *
49 *
50 * Example usage:
51 * int format = mConfig.outputCfg.format;
52 * int channels = audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
53 * int samplingRate = mConfig.outputCfg.samplingRate;
54 * int frameCount = mConfig.outputCfg.buffer.frameCount;
55 * int frameSize = audio_bytes_per_sample((audio_format_t)format) * channels;
56 * int buffSize = frameCount * frameSize;
57 * long maxBytes = 10 * samplingRate * frameSize; //10 seconds max
58 * BUFLOG(11, "loudnes_enhancer_out", format, channels, samplingRate, maxBytes,
59 * mConfig.outputCfg.buffer.raw, buffSize);
60 *
61 * Other macros:
62 * BUFLOG_EXISTS returns true if there is an instance of BufLog
63 *
64 * BUFLOG_RESET If an instance of BufLog exists, it stops the capture and closes all
65 * streams.
66 * If a new call to BUFLOG(..) is done, new streams are created.
67 */
68
69#ifndef BUFLOG_NDEBUG
70#ifdef NDEBUG
71#define BUFLOG_NDEBUG 1
72#else
73#define BUFLOG_NDEBUG 0
74#endif
75#endif
76
77/*
78 * Simplified macro to send a buffer.
79 */
80#ifndef BUFLOG
81#define __BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
82 BufLogSingleton::instance()->write(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, \
83 BUF, SIZE)
84#if BUFLOG_NDEBUG
85#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
86 do { if (0) { } } while (0)
87#else
88#define BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE) \
89 __BUFLOG(STREAMID, TAG, FORMAT, CHANNELS, SAMPLINGRATE, MAXBYTES, BUF, SIZE)
90#endif
91#endif
92
93#ifndef BUFLOG_EXISTS
94#define BUFLOG_EXISTS BufLogSingleton::instanceExists()
95#endif
96
97#ifndef BUFLOG_RESET
98#define BUFLOG_RESET do { if (BufLogSingleton::instanceExists()) { \
99 BufLogSingleton::instance()->reset(); } } while (0)
100#endif
101
102
103#include <stdint.h>
104#include <stdio.h>
105#include <sys/types.h>
106#include <utils/Mutex.h>
107
108//BufLog configuration
109#define BUFLOGSTREAM_MAX_TAGSIZE 32
110#define BUFLOG_BASE_PATH "/data/misc/audioserver"
111#define BUFLOG_MAX_PATH_SIZE 300
112
113class BufLogStream {
114public:
115 BufLogStream(unsigned int id,
116 const char *tag,
117 unsigned int format,
118 unsigned int channels,
119 unsigned int samplingRate,
120 size_t maxBytes);
121 ~BufLogStream();
122
123 // write buffer to stream
124 // buf: pointer to buffer
125 // size: number of bytes to write
126 size_t write(const void *buf, size_t size);
127
128 // pause/resume stream
129 // pause: true = paused, false = not paused
130 // return value: previous state of stream (paused or not).
131 bool setPause(bool pause);
132
133 // will stop the stream and close any open file
134 // the stream can't be reopen. Instead, a new stream (and file) should be created.
135 void finalize();
136
137private:
138 bool mPaused;
139 const unsigned int mId;
140 char mTag[BUFLOGSTREAM_MAX_TAGSIZE + 1];
141 const unsigned int mFormat;
142 const unsigned int mChannels;
143 const unsigned int mSamplingRate;
144 const size_t mMaxBytes;
145 size_t mByteCount;
146 FILE *mFile;
147 mutable android::Mutex mLock;
148
149 void closeStream_l();
150};
151
152
153class BufLog {
154public:
155 BufLog();
156 ~BufLog();
157 BufLog(BufLog const&) {};
158
159 // streamid: int [0:BUFLOG_MAXSTREAMS-1] buffer id.
160 // If a buffer doesn't exist, it is created the first time is referenced
161 // tag: char* string tag used on stream filename and logs
162 // format: int Audio format (audio_format_t see audio.h)
163 // channels: int Channel Count
164 // samplingRate: int Sampling rate in Hz. e.g. 8000, 16000, 44100, 48000, etc
165 // maxBytes: int [0 or positive number]
166 // Maximum size of the file (in bytes) to be output.
167 // If the value is 0, no limit.
168 // size: int Size (in bytes) of the current audio buffer to be written.
169 // buf: void * Pointer to audio buffer.
170 size_t write(int streamid,
171 const char *tag,
172 int format,
173 int channels,
174 int samplingRate,
175 size_t maxBytes,
176 const void *buf,
177 size_t size);
178
179 // reset will stop and close all active streams, thus finalizing any open file.
180 // New streams will be created if write() is called again.
181 void reset();
182
183protected:
184 static const unsigned int BUFLOG_MAXSTREAMS = 16;
185 BufLogStream *mStreams[BUFLOG_MAXSTREAMS];
186 mutable android::Mutex mLock;
187};
188
189class BufLogSingleton {
190public:
191 static BufLog *instance();
192 static bool instanceExists();
193
194private:
195 static void initOnce();
196 static BufLog *mInstance;
197};
198
199#endif //ANDROID_AUDIO_BUFLOG_H