Skip to content

Commit

Permalink
feat: added startAudioListening addEventListener functions to library
Browse files Browse the repository at this point in the history
  • Loading branch information
AminAllahham committed Jan 26, 2024
1 parent 58eed7f commit 5a10a0e
Show file tree
Hide file tree
Showing 3 changed files with 13,455 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
package com.liveaudiovisualizer;

import android.media.AudioRecord;
import android.media.AudioFormat;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import java.util.ArrayList;
import java.util.List;

@ReactModule(name = LiveAudioVisualizerModule.NAME)
public class LiveAudioVisualizerModule extends ReactContextBaseJavaModule {
public static final String NAME = "LiveAudioVisualizer";
private static final String EVENT_AUDIO_STARTED = "audioStarted";
private static final String EVENT_VISUALIZATION_CHANGED = "VisualizationChanged";

private AudioRecord audioRecord;
private boolean isListening = false;
private List<Integer> audioDataList = new ArrayList<>();
private Handler handler = new Handler(Looper.getMainLooper());

public LiveAudioVisualizerModule(ReactApplicationContext reactContext) {
super(reactContext);
Expand All @@ -22,11 +39,90 @@ public String getName() {
return NAME;
}

@ReactMethod
public void startAudioListening(Promise promise) {
if (!isListening) {
startAudioCapture();
sendEvent(EVENT_AUDIO_STARTED, null);
promise.resolve("Audio listening started");
} else {
promise.reject("ALREADY_LISTENING", "Audio listening is already started");
}
}

@ReactMethod
public void stopAudioListening(Promise promise) {
if (isListening) {
stopAudioCapture();
promise.resolve("Audio listening stopped");
} else {
promise.reject("NOT_LISTENING", "Audio listening is not started");
}
}

// Add audio capture logic
private void startAudioCapture() {
int bufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audioRecord.startRecording();
isListening = true;

// Start a separate thread to continuously read audio data
new Thread(() -> {
short[] buffer = new short[bufferSize / 2];
while (isListening) {
audioRecord.read(buffer, 0, buffer.length);
processData(buffer);
}
}).start();
}

private void stopAudioCapture() {
if (audioRecord != null) {
isListening = false;
audioRecord.stop();
audioRecord.release();
audioRecord = null;
}
}

// Process audio data and send it to React Native
private void processData(short[] buffer) {
// For simplicity, this example just sends the average amplitude of the audio data
int sum = 0;
for (short sample : buffer) {
sum += Math.abs(sample);
}
int averageAmplitude = sum / buffer.length;

// Add the average amplitude to the list
audioDataList.add(averageAmplitude);

// Send the data to React Native every second
handler.post(() -> {
sendEvent(EVENT_VISUALIZATION_CHANGED, audioDataList.toString());
audioDataList.clear();
});
}

private void sendEvent(String eventName, String data) {
getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, data);
}

@ReactMethod
public void setSensitivity(int sensitivity, Promise promise) {
// Implement sensitivity setting logic
promise.resolve();
}

// Example method
// See https://reactnative.dev/docs/native-modules-android
@ReactMethod
public void multiply(double a, double b, Promise promise) {
promise.resolve(a * b);
public void addEventListener(String eventName, Promise promise) {
if (eventName.equals(EVENT_VISUALIZATION_CHANGED)) {
promise.resolve();
} else {
promise.reject("INVALID_EVENT", "Invalid event name");
}
}
}
34 changes: 16 additions & 18 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { NativeModules, Platform } from 'react-native';
import { NativeModules } from 'react-native';

const LINKING_ERROR =
`The package 'react-native-live-audio-visualizer' doesn't seem to be linked. Make sure: \n\n` +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo Go\n';
const LiveAudioVisualizer = NativeModules.LiveAudioVisualizer;

const LiveAudioVisualizer = NativeModules.LiveAudioVisualizer
? NativeModules.LiveAudioVisualizer
: new Proxy(
{},
{
get() {
throw new Error(LINKING_ERROR);
},
}
);
export function startAudioListening(): Promise<void> {
return LiveAudioVisualizer.startAudioListening();
}

export function stopAudioListening(): Promise<void> {
return LiveAudioVisualizer.stopAudioListening();
}

export function setSensitivity(sensitivity: number): Promise<void> {
return LiveAudioVisualizer.setSensitivity(sensitivity);
}

export function multiply(a: number, b: number): Promise<number> {
return LiveAudioVisualizer.multiply(a, b);
export function addEventListener(callback: (data: any) => void): void {
LiveAudioVisualizer.addListener('audioStarted', callback);
LiveAudioVisualizer.addListener('VisualizationChanged', callback);
}
Loading

0 comments on commit 5a10a0e

Please sign in to comment.