Skip to content

Commit

Permalink
refactor: update example, docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yigithanyucedag committed Aug 1, 2024
1 parent cd5a9d3 commit b2f0b61
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 8 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ npx pod-install

3. **Rebuild your app** after installing the package.

> On iOS simulators, pitch detection may not work as expected due to the **lack of microphone support**. Make sure to test on a real device.
## Permissions

Microphone permissions are **required for pitch detection** to work. Make sure to request the necessary permissions before starting pitch detection. You can use a library like [react-native-permissions](https://github.com/zoontek/react-native-permissions) to request permissions.

### iOS

`Microphone`

### Android

`RECORD_AUDIO`

## Usage

1. Import the library:
Expand Down Expand Up @@ -99,9 +113,14 @@ Pitchy.isRecording().then((isRecording) => {

## Roadmap

- [ ] Fix example app (permissions issue related to builder-bob)
- [ ] Add FFT for ACF2+ algorithm (currently uses a naive implementation)
- [ ] Add more pitch detection algorithms

## Examples

Check out the [example app](example) for a simple implementation of pitch detection using Pitchy.

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
Expand Down
16 changes: 16 additions & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@ require "#{ws_dir}/node_modules/react-native-test-app/test_app.rb"
workspace 'PitchyExample.xcworkspace'

use_test_app!

def node_require(script)
# Resolve script with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
"require.resolve(
'#{script}',
{paths: [process.argv[1]]},
)", __dir__]).strip
end

# Use it to require both react-native's and this package's scripts:
node_require('react-native-permissions/scripts/setup.rb')

setup_permissions([
'Microphone'
])
3 changes: 2 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.74.3"
"react-native": "0.74.3",
"react-native-permissions": "^4.1.5"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
30 changes: 23 additions & 7 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import { useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { autoCorrelate } from 'react-native-pitchy';
import Pitchy from 'react-native-pitchy';

import { useMicrophonePermission } from './hooks/use-microphone-permission';

export default function App() {
const [result, setResult] = useState<number | undefined>();
const permissionGranted = useMicrophonePermission();

const [frequency, setFrequency] = useState<number | undefined>();

useEffect(() => {
const data = new Array(2048)
.fill(0)
.map((_, i) => Math.sin((i / 2048) * Math.PI * 2 * 440));
autoCorrelate(data, 44100).then(setResult);
Pitchy.init({
minVolume: -45,
});
Pitchy.addListener((data) => {
setFrequency(data.pitch);
});
}, []);

useEffect(() => {
if (!permissionGranted) return;

Pitchy.start();

return () => {
Pitchy.stop();
};
}, [permissionGranted]);

return (
<View style={styles.container}>
<Text>Result: {result}</Text>
<Text>Frequency: {frequency}</Text>
</View>
);
}
Expand Down
21 changes: 21 additions & 0 deletions example/src/hooks/use-microphone-permission.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect, useState } from 'react';
import { Platform } from 'react-native';
import { type Permission, request } from 'react-native-permissions';

export const useMicrophonePermission = () => {
const [hasPermission, setHasPermission] = useState(false);

useEffect(() => {
const permission = Platform.select({
ios: 'ios.permission.MICROPHONE',
android: 'android.permission.RECORD_AUDIO',
});
if (!permission) {
return;
}
request(permission as Permission).then((result) => {
setHasPermission(result === 'granted');
});
}, []);
return hasPermission;
};

0 comments on commit b2f0b61

Please sign in to comment.