Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ BaseAudioContextHostObject::BaseAudioContextHostObject(
addGetters(
JSI_EXPORT_PROPERTY_GETTER(BaseAudioContextHostObject, destination),
JSI_EXPORT_PROPERTY_GETTER(BaseAudioContextHostObject, listener),
JSI_EXPORT_PROPERTY_GETTER(BaseAudioContextHostObject, state),
JSI_EXPORT_PROPERTY_GETTER(BaseAudioContextHostObject, sampleRate),
JSI_EXPORT_PROPERTY_GETTER(BaseAudioContextHostObject, currentTime));

Expand Down Expand Up @@ -85,11 +84,6 @@ JSI_PROPERTY_GETTER_IMPL(BaseAudioContextHostObject, listener) {
return jsi::Object::createFromHostObject(runtime, listener_);
}

JSI_PROPERTY_GETTER_IMPL(BaseAudioContextHostObject, state) {
return jsi::String::createFromUtf8(
runtime, js_enum_parser::contextStateToString(context_->getState()));
}

JSI_PROPERTY_GETTER_IMPL(BaseAudioContextHostObject, sampleRate) {
return {context_->getSampleRate()};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class BaseAudioContextHostObject : public HostObject {

JSI_PROPERTY_GETTER_DECL(destination);
JSI_PROPERTY_GETTER_DECL(listener);
JSI_PROPERTY_GETTER_DECL(state);
JSI_PROPERTY_GETTER_DECL(sampleRate);
JSI_PROPERTY_GETTER_DECL(currentTime);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,6 @@ AudioEvent audioEventFromString(const std::string &event) {
throw std::invalid_argument("Unknown audio event: " + event);
}

std::string contextStateToString(ContextState state) {
switch (state) {
case ContextState::SUSPENDED:
return "suspended";
case ContextState::RUNNING:
return "running";
case ContextState::CLOSED:
return "closed";
default:
throw std::invalid_argument("Unknown context state");
}
}

std::string channelCountModeToString(ChannelCountMode mode) {
switch (mode) {
case ChannelCountMode::MAX:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ bool AudioContext::resume(const std::shared_ptr<ContextPromiseResolver<void>> &p
}

if (result) {
// Visible RUNNING is applied in the promise resolve task (CallInvoker).
// Visible RUNNING is applied inside the resolver
ContextPromiseResolver<void>::resolve(promise);
} else {
ContextPromiseResolver<void>::reject(promise, "Failed to resume audio context.");
Expand All @@ -155,7 +155,7 @@ bool AudioContext::suspend(const std::shared_ptr<ContextPromiseResolver<void>> &
processAudioEvents();
}

// Visible SUSPENDED is applied in the promise resolve task (CallInvoker).
// Visible SUSPENDED is applied inside the resolver
ContextPromiseResolver<void>::resolve(promise);
return true;
}
Expand Down
27 changes: 27 additions & 0 deletions packages/react-native-audio-api/src/core/AudioContext.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { InvalidStateError } from '../errors';
import { assertSupportedSampleRate } from '../utils/validation';
import { AudioTagHandle } from '../Audio/types';
import { IAudioContext } from '../jsi-interfaces';
Expand Down Expand Up @@ -28,17 +29,43 @@ export default class AudioContext extends BaseAudioContext {
}

async close(): Promise<undefined> {
if (this.contextState === 'closed') {
throw new InvalidStateError('Cannot close a closed audio context.');
}

this.contextState = 'closed';
return (this.context as IAudioContext).close();
}

async resume(): Promise<undefined> {
if (this.contextState === 'closed') {
throw new InvalidStateError('Cannot resume a closed audio context.');
}

this.contextState = 'running';
return (this.context as IAudioContext).resume();
}

async suspend(): Promise<undefined> {
if (this.contextState === 'closed') {
throw new InvalidStateError('Cannot suspend a closed audio context.');
}

this.contextState = 'suspended';
return (this.context as IAudioContext).suspend();
}

/**
* @internal Called by AudioScheduledSourceNode.start(). The native driver
* can start implicitly from the first scheduled source, with no promise to
* carry the transition, so this publishes the state that follows.
*/
public override markRunningOnSourceStart(): void {
if (this.contextState === 'suspended') {
this.contextState = 'running';
}
}

createMediaElementSource(
mediaElement: AudioTagHandle
): MediaElementAudioSourceNode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default class AudioScheduledSourceNode extends AudioNode {

this.hasBeenStarted = true;
(this.node as IAudioScheduledSourceNode).start(when);
this.context.markRunningOnSourceStart();
}

public stop(when: number = 0): void {
Expand Down
12 changes: 11 additions & 1 deletion packages/react-native-audio-api/src/core/BaseAudioContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,24 @@ export default class BaseAudioContext {
this.sampleRate = context.sampleRate;
}

protected contextState: ContextState = 'suspended';

public get currentTime(): number {
return this.context.currentTime;
}

public get state(): ContextState {
return this.context.state;
return this.contextState;
}

/**
* @internal Called by AudioScheduledSourceNode.start(). No-op here: only
* AudioContext overrides it, since only AudioContext's native driver can
* start implicitly from a source's start() call. OfflineAudioContext only
* starts rendering from an explicit startRendering() call.
*/
public markRunningOnSourceStart(): void {}

public async decodeAudioData(
input: DecodeDataInput,
fetchOptions?: RequestInit
Expand Down
18 changes: 9 additions & 9 deletions packages/react-native-audio-api/src/core/OfflineAudioContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import AudioBuffer from './AudioBuffer';
import BaseAudioContext from './BaseAudioContext';

export default class OfflineAudioContext extends BaseAudioContext {
private isSuspended: boolean;
private isRendering: boolean;
private duration: number;

Expand Down Expand Up @@ -41,7 +40,6 @@ export default class OfflineAudioContext extends BaseAudioContext {
throw new NotSupportedError('Invalid constructor arguments');
}

this.isSuspended = false;
this.isRendering = false;
}

Expand All @@ -52,14 +50,13 @@ export default class OfflineAudioContext extends BaseAudioContext {
);
}

if (!this.isSuspended) {
if (!(this.contextState === 'suspended')) {
throw new InvalidStateError(
'Cannot resume an OfflineAudioContext that is not suspended'
);
}

this.isSuspended = false;

this.contextState = 'running';
return (this.context as IOfflineAudioContext).resume();
}

Expand All @@ -80,9 +77,11 @@ export default class OfflineAudioContext extends BaseAudioContext {
);
}

this.isSuspended = true;

return (this.context as IOfflineAudioContext).suspend(suspendTime);
const result = await (this.context as IOfflineAudioContext).suspend(
suspendTime
);
this.contextState = 'suspended';
return result;
}

async startRendering(): Promise<AudioBuffer> {
Expand All @@ -91,10 +90,11 @@ export default class OfflineAudioContext extends BaseAudioContext {
}

this.isRendering = true;

this.contextState = 'running';
const audioBuffer = await (
this.context as IOfflineAudioContext
).startRendering();
this.contextState = 'closed';

return new AudioBuffer(audioBuffer);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/react-native-audio-api/src/jsi-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {
ChannelSplitterOptions,
ConstantSourceOptions,
ConvolverOptions,
ContextState,
DelayOptions,
FileInfo,
GainOptions,
Expand All @@ -40,7 +39,6 @@ export interface IOscillatorOptions extends Omit<
export interface IBaseAudioContext {
readonly destination: IAudioDestinationNode;
readonly listener: IAudioListener;
readonly state: ContextState;
readonly sampleRate: number;
readonly currentTime: number;
readonly decoder: IAudioDecoder;
Expand Down
Loading