Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions apps/common-app/src/examples/AudioFile/AudioFile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import { useState, useRef, useEffect, FC } from 'react';
import { Container, Button } from '../../components';

import {
AudioContext,
AudioBufferSourceNode,
AudioBuffer,
} from 'react-native-audio-api';

const AudioFile: FC = () => {
const [isPlaying, setIsPlaying] = useState(false);

const audioContextRef = useRef<AudioContext | null>(null);
const audioBufferSourceNodeRef = useRef<AudioBufferSourceNode | null>(null);
const [audioBuffer, setAudioBuffer] = useState<AudioBuffer | null>(null);

const setup = () => {
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
}

audioBufferSourceNodeRef.current =
audioContextRef.current.createBufferSource();
audioBufferSourceNodeRef.current.buffer;
audioBufferSourceNodeRef.current.connect(
audioContextRef.current.destination
);
};

const fetchAudioBuffer = async () => {
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
}

setAudioBuffer(
// audioContextRef.current.decodeAudioDataSource(
// '/Users/maciejmakowski/projects/react-native-audio-api/apps/common-app/src/examples/AudioFile/runaway_kanye_west.mp3'
// )
audioContextRef.current.decodeAudioDataSource(
'https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a'
)
);
};

const handlePress = () => {
if (isPlaying) {
audioBufferSourceNodeRef.current?.stop();
} else {
setup();
audioBufferSourceNodeRef.current!.buffer = audioBuffer;
audioBufferSourceNodeRef.current?.start();
}

setIsPlaying(!isPlaying);
};

useEffect(() => {
if (!audioContextRef.current) {
audioContextRef.current = new AudioContext();
}

fetchAudioBuffer();

return () => {
audioContextRef.current?.close();
};
}, []);

return (
<Container centered>
<Button title={isPlaying ? 'Stop' : 'Play'} onPress={handlePress} />
</Container>
);
};

export default AudioFile;
1 change: 1 addition & 0 deletions apps/common-app/src/examples/AudioFile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AudioFile';
Binary file not shown.
8 changes: 8 additions & 0 deletions apps/common-app/src/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import Piano from './Piano';
import Metronome from './Metronome';
import Oscillator from './Oscillator';
import DrumMachine from './DrumMachine';
import AudioFile from './AudioFile';

type NavigationParamList = {
Oscillator: undefined;
Metronome: undefined;
DrumMachine: undefined;
Piano: undefined;
AudioFile: undefined;
};

export type ExampleKey = keyof NavigationParamList;
Expand Down Expand Up @@ -47,4 +49,10 @@ export const Examples: Example[] = [
subtitle: 'Generate sound waves',
screen: Oscillator,
},
{
key: 'AudioFile',
title: 'Audio File',
subtitle: 'Play an audio file',
screen: AudioFile,
},
] as const;
8 changes: 4 additions & 4 deletions apps/fabric-example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ PODS:
- React-logger (= 0.76.0)
- React-perflogger (= 0.76.0)
- React-utils (= 0.76.0)
- RNAudioAPI (0.1.0):
- RNAudioAPI (0.2.0):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -2058,13 +2058,13 @@ SPEC CHECKSUMS:
React-utils: d9624101245ebaab39c9f1bd786132da0b4f27ff
ReactCodegen: dbfef1fef26f42c900bb1884fa149d49d501d64d
ReactCommon: 429ca28cd813c31359c73ffac6dc24f93347d522
RNAudioAPI: a4068f739b4e80e636ac6110d70858ea89ac4835
RNAudioAPI: adb400fcab1b85cafaff4e0880be5d4616fd4727
RNGestureHandler: a3822e519fd1e9885b92d8c9bd82a7a0be305fe3
RNReanimated: 77242c6d67416988a2fd9f5cf574bb3e60016362
RNScreens: e389d6a6a66a4f0d3662924ecae803073ccce8ec
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 1d66db49f38fd9e576a1d7c3b081e46ab4c28b9e
Yoga: f8ec45ce98bba1bc93dd28f2ee37215180e6d2b6

PODFILE CHECKSUM: 75ad38075e71875257a2590065853ea6a608b897

COCOAPODS: 1.16.2
COCOAPODS: 1.15.2
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@

#include "AudioBus.h"
#include "Constants.h"
#include "AudioArray.h"
#include "AudioPlayer.h"
#include "AudioArray.h"
#include "AudioBus.h"
#include "AudioContext.h"
#include "Constants.h"

namespace audioapi {

AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
AudioPlayer::AudioPlayer(
const std::function<void(AudioBus *, int)> &renderAudio)
: renderAudio_(renderAudio) {
AudioStreamBuilder builder;

Expand All @@ -20,7 +21,8 @@ AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
->setDataCallback(this)
->openStream(mStream_);

mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
mBus_ = std::make_shared<AudioBus>(
getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
isInitialized_ = true;
}

Expand Down Expand Up @@ -62,7 +64,8 @@ DataCallbackResult AudioPlayer::onAudioReady(
// TODO: optimize this with SIMD?
for (int32_t i = 0; i < numFrames; i += 1) {
for (int channel = 0; channel < CHANNEL_COUNT; channel += 1) {
buffer[i * CHANNEL_COUNT + channel] = mBus_->getChannel(channel)->getData()[i];
buffer[i * CHANNEL_COUNT + channel] =
mBus_->getChannel(channel)->getData()[i];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AudioBus;

class AudioPlayer : public AudioStreamDataCallback {
public:
explicit AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio);
explicit AudioPlayer(const std::function<void(AudioBus *, int)> &renderAudio);

int getSampleRate() const;
int getBufferSizeInFrames() const;
Expand All @@ -25,7 +25,7 @@ class AudioPlayer : public AudioStreamDataCallback {
int32_t numFrames) override;

private:
std::function<void(AudioBus*, int)> renderAudio_;
std::function<void(AudioBus *, int)> renderAudio_;
std::shared_ptr<AudioStream> mStream_;
std::shared_ptr<AudioBus> mBus_;
bool isInitialized_ = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ std::vector<jsi::PropNameID> BaseAudioContextHostObject::getPropertyNames(
propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createBuffer"));
propertyNames.push_back(
jsi::PropNameID::forUtf8(runtime, "createPeriodicWave"));
propertyNames.push_back(
jsi::PropNameID::forUtf8(runtime, "decodeAudioDataSource"));
return propertyNames;
}

Expand Down Expand Up @@ -200,6 +202,25 @@ jsi::Value BaseAudioContextHostObject::get(
});
}

if (propName == "decodeAudioDataSource") {
return jsi::Function::createFromHostFunction(
runtime,
propNameId,
1,
[this](
jsi::Runtime &runtime,
const jsi::Value &thisValue,
const jsi::Value *arguments,
size_t count) -> jsi::Value {
std::string source = arguments[0].getString(runtime).utf8(runtime);
auto buffer = wrapper_->decodeAudioDataSource(source);
auto audioBufferHostObject =
AudioBufferHostObject::createFromWrapper(buffer);
return jsi::Object::createFromHostObject(
runtime, audioBufferHostObject);
});
}

throw std::runtime_error("Not yet implemented!");
}

Expand Down
42 changes: 28 additions & 14 deletions packages/react-native-audio-api/common/cpp/core/AudioArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@

namespace audioapi {

AudioArray::AudioArray(int size) : size_(size), data_(0) {
AudioArray::AudioArray(int size) : data_(nullptr), size_(size) {
resize(size);
}

AudioArray::~AudioArray() {
if (data_) {
delete[] data_;
data_ = 0;
data_ = nullptr;
}
}

int AudioArray::getSize() const {
return size_;
}

float* AudioArray::getData() const {
float *AudioArray::getData() const {
return data_;
}

float& AudioArray::operator[](int index) {
float &AudioArray::operator[](int index) {
return data_[index];
}

const float& AudioArray::operator[](int index) const {
const float &AudioArray::operator[](int index) const {
return data_[index];
}

Expand Down Expand Up @@ -75,29 +75,43 @@ void AudioArray::zero(int start, int length) {
memset(data_ + start, 0, length * sizeof(float));
}

void AudioArray::sum(const AudioArray* source) {
void AudioArray::sum(const AudioArray *source) {
sum(source, 0, 0, size_);
}

void AudioArray::sum(const AudioArray* source, int start, int length) {
void AudioArray::sum(const AudioArray *source, int start, int length) {
sum(source, start, start, length);
}

void AudioArray::sum(const AudioArray* source, int sourceStart, int destinationStart, int length) {
VectorMath::add(data_ + destinationStart, source->getData() + sourceStart, data_ + destinationStart, length);
void AudioArray::sum(
const AudioArray *source,
int sourceStart,
int destinationStart,
int length) {
VectorMath::add(
data_ + destinationStart,
source->getData() + sourceStart,
data_ + destinationStart,
length);
}

void AudioArray::copy(const AudioArray* source) {
void AudioArray::copy(const AudioArray *source) {
copy(source, 0, size_);
}

void AudioArray::copy(const AudioArray* source, int start, int length) {
void AudioArray::copy(const AudioArray *source, int start, int length) {
copy(source, start, start, length);
}

void AudioArray::copy(const AudioArray* source, int sourceStart, int destinationStart, int length) {
memcpy(data_ + destinationStart, source->getData() + sourceStart, length * sizeof(float));
void AudioArray::copy(
const AudioArray *source,
int sourceStart,
int destinationStart,
int length) {
memcpy(
data_ + destinationStart,
source->getData() + sourceStart,
length * sizeof(float));
}

} // namespace audioapi

34 changes: 20 additions & 14 deletions packages/react-native-audio-api/common/cpp/core/AudioArray.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include <memory>
#include <algorithm>
#include <memory>

namespace audioapi {

Expand All @@ -11,28 +11,34 @@ class AudioArray {
~AudioArray();

[[nodiscard]] int getSize() const;
float* getData() const;

[[nodiscard]] float *getData() const;

float& operator[](int index);
const float& operator[](int index) const;
float &operator[](int index);
const float &operator[](int index) const;

void normalize();
void resize(int size);
void scale(float value);
float getMaxAbsValue() const;
[[nodiscard]] float getMaxAbsValue() const;

void zero();
void zero(int start, int length);

void sum(const AudioArray* source);
void sum(const AudioArray* source, int start, int length);
void sum(const AudioArray* source, int sourceStart, int destinationStart, int length);

void copy(const AudioArray* source);
void copy(const AudioArray* source, int start, int length);
void copy(const AudioArray* source, int sourceStart, int destinationStart, int length);

void sum(const AudioArray *source);
void sum(const AudioArray *source, int start, int length);
void sum(
const AudioArray *source,
int sourceStart,
int destinationStart,
int length);

void copy(const AudioArray *source);
void copy(const AudioArray *source, int start, int length);
void copy(
const AudioArray *source,
int sourceStart,
int destinationStart,
int length);

private:
float *data_;
Expand Down
Loading
Loading