1 /*
2 * Copyright (C) 2024 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 #include <android/log.h>
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <fcntl.h>
21
22 #include "WavFileCapture.h"
23 #include "WavCaptureOutputStream.h"
24
25 const char * TAG = "WavFileCapture";
26
27 WavFileCapture sWavFileCapture;
28
WavFileCapture()29 WavFileCapture::WavFileCapture() : mCaptureActive(false) {
30 mOutputStream = new WavCaptureOutputStream();
31 mWavFileWriter = new WaveFileWriter(mOutputStream);
32 }
33
~WavFileCapture()34 WavFileCapture::~WavFileCapture() {
35 delete mOutputStream;
36 delete mWavFileWriter;
37 }
38
setCaptureFile(const char * wavFilePath)39 void WavFileCapture::setCaptureFile(const char* wavFilePath) {
40 mWavCapturePath = wavFilePath;
41 }
42
setWavSpec(int numChannels,int sampleRate)43 void WavFileCapture::setWavSpec(int numChannels, int sampleRate) {
44 mNumChannels = numChannels;
45 mSampleRate = sampleRate;
46 }
47
startCapture()48 void WavFileCapture::startCapture() {
49 mOutputStream->init();
50 mWavFileWriter->reset();
51 mCaptureActive = true;
52 }
53
completeCapture()54 int WavFileCapture::completeCapture() {
55 if (!mCaptureActive) {
56 return CAPTURE_NOTDONE;
57 }
58
59 int returnVal;
60 FILE* file = fopen(mWavCapturePath.c_str(), "w");
61 if (file == nullptr) {
62 __android_log_print(ANDROID_LOG_ERROR, TAG,
63 "error opening capture file: %s", mWavCapturePath.c_str());
64 returnVal = CAPTURE_BADOPEN;
65 } else {
66 int numWriteBytes = mOutputStream->length();
67 int numWrittenBytes =
68 fwrite(mOutputStream->getData(), sizeof(uint8_t), numWriteBytes, file);
69 if (numWrittenBytes != numWriteBytes) {
70 __android_log_print(ANDROID_LOG_ERROR, TAG,
71 "error writing capture file: %s", mWavCapturePath.c_str());
72 returnVal = CAPTURE_BADWRITE;
73 } else {
74 returnVal = CAPTURE_SUCCESS;
75 }
76 fclose(file);
77 }
78 mCaptureActive = false;
79
80 return returnVal;
81 }
82
abandonCaptureData()83 void WavFileCapture::abandonCaptureData() {
84 // TODO: implement when we have a caller for this.
85 mCaptureActive = false;
86 }
87
captureData(void * audioData,int32_t numFrames)88 void WavFileCapture::captureData(void *audioData, int32_t numFrames) {
89 if (mCaptureActive) {
90 mWavFileWriter->write((float*)audioData, 0, numFrames /* * numChannels? */);
91 }
92 }
93
94 /*
95 * JNI Interface
96 */
97 #include <jni.h>
98
99 extern "C" {
100
101 JNIEXPORT jlong JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_getCapture_1n()102 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_getCapture_1n() {
103 return (jlong)&sWavFileCapture;
104 }
105
106 JNIEXPORT void JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setCaptureFile_1n(JNIEnv * env __unused,jobject obj __unused,jlong wavCaptureObj,jstring wavFilePath)107 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setCaptureFile_1n(
108 JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj, jstring wavFilePath) {
109 WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
110
111 const char *captureFile = env->GetStringUTFChars(wavFilePath, 0);
112 capture->setCaptureFile(captureFile);
113
114 env->ReleaseStringUTFChars(wavFilePath, captureFile);
115 }
116
117 JNIEXPORT void JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setWavSpec_1n(JNIEnv * env __unused,jobject obj __unused,jlong wavCaptureObj,jint numChannels,jint sampleRate)118 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_setWavSpec_1n(
119 JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj, jint numChannels, jint sampleRate) {
120 WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
121 capture->setWavSpec(numChannels, sampleRate);
122 }
123
124 JNIEXPORT void JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_startCapture_1n(JNIEnv * env __unused,jobject obj __unused,jlong wavCaptureObj)125 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_startCapture_1n(
126 JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
127 WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
128 capture->startCapture();
129 }
130
131 JNIEXPORT jint JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_completeCapture_1n(JNIEnv * env __unused,jobject obj __unused,jlong wavCaptureObj)132 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_completeCapture_1n(
133 JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
134 WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
135 return capture->completeCapture();
136 }
137
138 JNIEXPORT void JNICALL
Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_abandonCapture_n(JNIEnv * env __unused,jobject obj __unused,jlong wavCaptureObj)139 Java_com_android_cts_verifier_audio_audiolib_WavFileCapture_abandonCapture_n(
140 JNIEnv *env __unused, jobject obj __unused, jlong wavCaptureObj) {
141 WavFileCapture* capture = (WavFileCapture*)wavCaptureObj;
142 capture->abandonCaptureData();
143 }
144
145 } // extern "C"
146