diff --git a/services/audioflinger/BufLog.cpp b/services/audioflinger/BufLog.cpp
new file mode 100644
index 0000000..9680eb5
--- /dev/null
+++ b/services/audioflinger/BufLog.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+
+#include "BufLog.h"
+#define LOG_TAG "BufLog"
+//#define LOG_NDEBUG 0
+
+#include <errno.h>
+#include "log/log.h"
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+// ------------------------------
+// BufLogSingleton
+// ------------------------------
+pthread_once_t onceControl = PTHREAD_ONCE_INIT;
+
+BufLog *BufLogSingleton::mInstance = NULL;
+
+void BufLogSingleton::initOnce() {
+    mInstance = new BufLog();
+    ALOGW("=====================================\n" \
+            "Warning: BUFLOG is defined in some part of your code.\n" \
+            "This will create large audio dumps in %s.\n" \
+            "=====================================\n", BUFLOG_BASE_PATH);
+}
+
+BufLog *BufLogSingleton::instance() {
+    pthread_once(&onceControl, initOnce);
+    return mInstance;
+}
+
+bool BufLogSingleton::instanceExists() {
+    return mInstance != NULL;
+}
+
+// ------------------------------
+// BufLog
+// ------------------------------
+
+BufLog::BufLog() {
+    memset(mStreams, 0, sizeof(mStreams));
+}
+
+BufLog::~BufLog() {
+    android::Mutex::Autolock autoLock(mLock);
+
+    for (unsigned int id = 0; id < BUFLOG_MAXSTREAMS; id++) {
+        BufLogStream *pBLStream = mStreams[id];
+        if (pBLStream != NULL) {
+            delete pBLStream ;
+            mStreams[id] = NULL;
+        }
+    }
+}
+
+size_t BufLog::write(int streamid, const char *tag, int format, int channels,
+        int samplingRate, size_t maxBytes, const void *buf, size_t size) {
+    unsigned int id = streamid % BUFLOG_MAXSTREAMS;
+    android::Mutex::Autolock autoLock(mLock);
+
+    BufLogStream *pBLStream = mStreams[id];
+
+    if (pBLStream == NULL) {
+        pBLStream = mStreams[id] = new BufLogStream(id, tag, format, channels,
+                samplingRate, maxBytes);
+        ALOG_ASSERT(pBLStream != NULL, "BufLogStream Failed to be created");
+    }
+
+    return pBLStream->write(buf, size);
+}
+
+void BufLog::reset() {
+    android::Mutex::Autolock autoLock(mLock);
+    ALOGV("Resetting all BufLogs");
+    int count = 0;
+
+    for (unsigned int id = 0; id < BUFLOG_MAXSTREAMS; id++) {
+        BufLogStream *pBLStream = mStreams[id];
+        if (pBLStream != NULL) {
+            delete pBLStream;
+            mStreams[id] = NULL;
+            count++;
+        }
+    }
+    ALOGV("Reset %d BufLogs", count);
+}
+
+// ------------------------------
+// BufLogStream
+// ------------------------------
+
+BufLogStream::BufLogStream(unsigned int id,
+        const char *tag,
+        unsigned int format,
+        unsigned int channels,
+        unsigned int samplingRate,
+        size_t maxBytes = 0) : mId(id), mFormat(format), mChannels(channels),
+                mSamplingRate(samplingRate), mMaxBytes(maxBytes) {
+    mByteCount = 0l;
+    mPaused = false;
+    if (tag != NULL) {
+        strncpy(mTag, tag, BUFLOGSTREAM_MAX_TAGSIZE);
+    } else {
+        mTag[0] = 0;
+    }
+    ALOGV("Creating BufLogStream id:%d tag:%s format:%d ch:%d sr:%d maxbytes:%zu", mId, mTag,
+            mFormat, mChannels, mSamplingRate, mMaxBytes);
+
+    //open file (s), info about tag, format, etc.
+    //timestamp
+    char timeStr[16];   //size 16: format %Y%m%d%H%M%S 14 chars + string null terminator
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    struct tm tm;
+    localtime_r(&tv.tv_sec, &tm);
+    strftime(timeStr, sizeof(timeStr), "%Y%m%d%H%M%S", &tm);
+    char logPath[BUFLOG_MAX_PATH_SIZE];
+    snprintf(logPath, BUFLOG_MAX_PATH_SIZE, "%s/%s_%d_%s_%d_%d_%d.raw", BUFLOG_BASE_PATH, timeStr,
+            mId, mTag, mFormat, mChannels, mSamplingRate);
+    ALOGV("data output: %s", logPath);
+
+    mFile = fopen(logPath, "wb");
+    if (mFile != NULL) {
+        ALOGV("Success creating file at: %p", mFile);
+    } else {
+        ALOGE("Error: could not create file BufLogStream %s", strerror(errno));
+    }
+}
+
+void BufLogStream::closeStream_l() {
+    ALOGV("Closing BufLogStream id:%d tag:%s", mId, mTag);
+    if (mFile != NULL) {
+        fclose(mFile);
+        mFile = NULL;
+    }
+}
+
+BufLogStream::~BufLogStream() {
+    ALOGV("Destroying BufLogStream id:%d tag:%s", mId, mTag);
+    android::Mutex::Autolock autoLock(mLock);
+    closeStream_l();
+}
+
+size_t BufLogStream::write(const void *buf, size_t size) {
+
+    size_t bytes = 0;
+    if (!mPaused && mFile != NULL) {
+        if (size > 0 && buf != NULL) {
+            android::Mutex::Autolock autoLock(mLock);
+            if (mMaxBytes > 0) {
+                size = MIN(size, mMaxBytes - mByteCount);
+            }
+            bytes = fwrite(buf, 1, size, mFile);
+            mByteCount += bytes;
+            if (mMaxBytes > 0 && mMaxBytes == mByteCount) {
+                closeStream_l();
+            }
+        }
+        ALOGV("wrote %zu/%zu bytes to BufLogStream %d tag:%s. Total Bytes: %zu", bytes, size, mId,
+                mTag, mByteCount);
+    } else {
+        ALOGV("Warning: trying to write to %s BufLogStream id:%d tag:%s",
+                mPaused ? "paused" : "closed", mId, mTag);
+    }
+    return bytes;
+}
+
+bool BufLogStream::setPause(bool pause) {
+    bool old = mPaused;
+    mPaused = pause;
+    return old;
+}
+
+void BufLogStream::finalize() {
+    android::Mutex::Autolock autoLock(mLock);
+    closeStream_l();
+}
