Skip to content

Commit f64509e

Browse files
Toby MaoToby Mao
Toby Mao
authored and
Toby Mao
committed
tag 0.0.2
1 parent 0575072 commit f64509e

12 files changed

+172
-21
lines changed

README.md

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# rcaudio : A Realtime Audio Recording & Analyze Script
2-
1+
# rcaudio : A Realtime Audio Recording & Analyzing Library
32

43
## Introduction
54

@@ -11,7 +10,12 @@ It supports real-time analysis of :
1110
* Volume
1211
* Beat Information
1312

14-
For chinese documentation : [中文文档](http://mhy12345.xyz/technology/python-beat-detection/)
13+
For chinese documentation : [中文文档](http://mhy12345.xyz/technology/rcaudio-documentation/)
14+
## Installation
15+
16+
```bash
17+
pip install rcaudio
18+
```
1519

1620
## Usage
1721

@@ -46,6 +50,9 @@ All class extended from `BaseAnalyzer` can be registered into `SimpleRecorder`.
4650

4751

4852
```python
53+
import time
54+
from rcaudio import SimpleRecorder,VolumeAnalyzer
55+
4956
SR = SimpleRecorder()
5057
VA = VolumeAnalyzer(rec_time = 1)
5158
SR.register(VA)
@@ -66,3 +73,21 @@ while True:
6673
print(BA.block_until_next_beat())
6774
```
6875

76+
A FeatureAnalyzer can use to generate all user defined acoustic features. Just override the `data_process` function. (Current function are the calculation of the *Zero Crossing Rate*.
77+
78+
```python
79+
SR = SimpleRecorder(sr = 1000)
80+
FA = FeatureAnalyzer(refresh_time = 1)
81+
SR.register(FA)
82+
SR.start()
83+
cpos = 0
84+
while True:
85+
if len(FA.result) > cpos:
86+
print(FA.result[cpos])
87+
cpos += 1
88+
time.sleep(.01)
89+
```
90+
91+
## Some note
92+
93+
Most function has the time delay about 1-2 seconds. I did lot effort to let the BeatAnalyzer looked as it is real-time. However, for the `FeatureAnalyzer`, if the feature extraction function are too slow compare to the microphone recording, the dalay may become huge. Decrease the sample rates would be a solution, but better solution would be DIY a analyzer yourself.

build/lib/rcaudio/beat_analyzer.py

-3
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,8 @@ def block_until_next_beat(self):
7979
self.current_k = self.current_k + (self.expected_k - self.current_k)*(1-self.smooth_ratio)
8080
if self.current_k < self.initial_k*.45:
8181
self.current_k *= 2
82-
print("INC")
8382
if self.current_k > self.initial_k * 2.1:
8483
self.current_k /= 2
85-
print("DEC")
86-
print(">>>",self.current_k,self.expected_k)
8784
while time.time() < pred:
8885
time.sleep(.01)
8986
return self.beat_count

demo.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44

55

6-
logging.basicConfig(level=logging.DEBUG,
6+
logging.basicConfig(level=logging.INFO,
77
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
88

99

@@ -38,4 +38,33 @@ def demo3():
3838
while True:
3939
print(BA.block_until_next_beat())
4040

41-
demo3()
41+
def demo4():
42+
SR = SimpleRecorder(sr = 20000)
43+
BA = BeatAnalyzer(rec_time = 15, initial_bpm = 120, smooth_ratio = .8)
44+
VA = VolumeAnalyzer(rec_time = 1)
45+
SR.register(BA)
46+
SR.register(VA)
47+
SR.start()
48+
low_volume_count = 0
49+
while True:
50+
v = VA.get_volume()
51+
if v < 50:
52+
low_volume_count += 1
53+
if low_volume_count > 4:
54+
break
55+
SR.stop()
56+
SR.join()
57+
58+
def demo5():
59+
SR = SimpleRecorder(sr = 1000)
60+
FA = FeatureAnalyzer(refresh_time = 1)
61+
SR.register(FA)
62+
SR.start()
63+
cpos = 0
64+
while True:
65+
if len(FA.result) > cpos:
66+
print("Zero Crossing Rate : ",FA.result[cpos])
67+
cpos += 1
68+
time.sleep(.01)
69+
70+
demo5()

dist/rcaudio-0.0.1-py3-none-any.whl

677 Bytes
Binary file not shown.

dist/rcaudio-0.0.1.tar.gz

793 Bytes
Binary file not shown.

rcaudio.egg-info/PKG-INFO

+58-2
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,72 @@ Author-email: maohanyang789@163.com
88
License: UNKNOWN
99
Description: # rcaudio : A Realtime Audio Recording & Analyze Script
1010

11+
1112
## Introduction
1213

13-
rcaudio is a realtime audio recording script, it provide easy way to record via microphone and then analyze.
14+
**rcaudio** Rcaudio is a real-time audio analysis library that allows you to simply record audio through a microphone and analyze.
1415

15-
rcaudio provide APIs to get:
16+
It supports real-time analysis of :
1617

1718
* The raw audio data
1819
* Volume
1920
* Beat Information
2021

22+
For chinese documentation : [中文文档](http://mhy12345.xyz/technology/python-beat-detection/)
23+
24+
## Usage
25+
26+
### CoreRecorder
27+
28+
`CoreRecorder` is used to fetch raw data. When started, the audio data will be stored in the `CoreRecorder.buffer`.
29+
30+
```python
31+
from rcaudio import CoreRecorder
32+
CR = CoreRecorder(
33+
time = 10, #How much time to record
34+
sr = 1000 #sample rate
35+
)
36+
CR.start()
37+
while True:
38+
if not CR.buffer.empty():
39+
x = CR.buffer.get()
40+
print('*'*int(abs(x)))
41+
```
42+
43+
### SimpleRecorder
44+
45+
In most cases, we use `SimpleRecorder`. For efficiency consideration, the `SimpleRecorder` should only be instantiated once.
46+
47+
This class can register several `Analyzer`.
48+
49+
When the function `start()` called, It will begin to record through microphone, and refresh the status of all the `Analyzer`
50+
51+
### Analyzers
52+
53+
All class extended from `BaseAnalyzer` can be registered into `SimpleRecorder`. For example `VolumeAnalyzer` can get the current volume of the microphone.
54+
55+
56+
```python
57+
SR = SimpleRecorder()
58+
VA = VolumeAnalyzer(rec_time = 1)
59+
SR.register(VA)
60+
SR.start()
61+
while True:
62+
print("VOLUME : ",VA.get_volume())
63+
time.sleep(1)
64+
```
65+
66+
And beat analyzer can predict the beats from the music. (However, there will be some delay.)
67+
68+
```python
69+
SR = SimpleRecorder(sr = 20000)
70+
BA = BeatAnalyzer(rec_time = 15, initial_bpm = 120, smooth_ratio = .8)
71+
SR.register(BA)
72+
SR.start()
73+
while True:
74+
print(BA.block_until_next_beat())
75+
```
76+
2177

2278
Platform: UNKNOWN
2379
Classifier: Programming Language :: Python :: 3

rcaudio/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
from .volume_analyzer import VolumeAnalyzer
66
from .beat_analyzer import BeatAnalyzer
7+
from .feature_analyzer import FeatureAnalyzer
78

89
__all__ = [
910
"CoreRecorder",
1011
"SimpleRecorder",
1112
"BaseAnalyzer",
1213
"VolumeAnalyzer",
13-
"BeatAnalyzer"
14+
"BeatAnalyzer",
15+
"FeatureAnalyzer"
1416
]

rcaudio/base_analyzer.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ def __init__(self):
1212
self.logger = logging.getLogger(str(self.__class__))
1313

1414
def stop(self):
15-
logger.warn("Stop signal received")
15+
self.logger.debug("Stop signal received")
1616
self.running.clear()
1717

1818
def register_recorder(self,recorder):
1919
self.audio_data = recorder.audio_data
2020
self.sr = recorder.sr
2121
self.recorder = recorder
2222

23+
def is_running(self):
24+
return self.running.isSet()
25+

rcaudio/beat_analyzer.py

-4
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def block_until_next_beat(self):
6666
exp_i = math.ceil((pred_v2 - self.expected_b)/self.expected_k)
6767
exp_v2 = exp_i * self.expected_k + self.expected_b
6868
exp_v1 = exp_v2 - self.expected_k
69-
print(exp_v1,pred_v2,exp_v2)
7069
if (pred_v2-exp_v1) < (exp_v2-pred_v2):
7170
pred = pred_v2 + (exp_v1-pred_v2)*(1-self.smooth_ratio)
7271
self.beat_count += pred_i
@@ -79,11 +78,8 @@ def block_until_next_beat(self):
7978
self.current_k = self.current_k + (self.expected_k - self.current_k)*(1-self.smooth_ratio)
8079
if self.current_k < self.initial_k*.45:
8180
self.current_k *= 2
82-
print("INC")
8381
if self.current_k > self.initial_k * 2.1:
8482
self.current_k /= 2
85-
print("DEC")
86-
print(">>>",self.current_k,self.expected_k)
8783
while time.time() < pred:
8884
time.sleep(.01)
8985
return self.beat_count

rcaudio/feature_analyzer.py

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from .base_analyzer import BaseAnalyzer
2+
import librosa
3+
import time
4+
import math
5+
import numpy as np
6+
7+
class FeatureAnalyzer(BaseAnalyzer):
8+
def __init__(self,
9+
refresh_time = 1
10+
):
11+
BaseAnalyzer.__init__(self)
12+
self.refresh_time = refresh_time
13+
self.cpos = 0
14+
self.result = []
15+
16+
def register_recorder(self,recorder):
17+
BaseAnalyzer.register_recorder(self,recorder)
18+
self.refresh_size = self.sr * self.refresh_time
19+
20+
def data_process(self,data):
21+
def ZeroCR(waveData,frameSize,overLap):
22+
#http://ibillxia.github.io/blog/2013/05/15/audio-signal-processing-time-domain-ZeroCR-python-realization/
23+
wlen = len(waveData)
24+
step = frameSize - overLap
25+
frameNum = math.ceil(wlen/step)
26+
zcr = np.zeros((frameNum,1))
27+
for i in range(frameNum):
28+
curFrame = waveData[np.arange(i*step,min(i*step+frameSize,wlen))]
29+
curFrame = curFrame - np.mean(curFrame) # zero-justified
30+
zcr[i] = sum(curFrame[0:-1]*curFrame[1::]<=0)
31+
return zcr
32+
zcr = ZeroCR(data,512,0)
33+
return data[0]
34+
35+
def run(self):
36+
while self.recorder.start_time is None:
37+
time.sleep(1)
38+
39+
while self.running.isSet():
40+
while len(self.audio_data) > self.cpos + self.refresh_size:
41+
data = np.array(self.audio_data[self.cpos:self.cpos + self.refresh_size]).astype(np.float32)
42+
data = self.data_process(data)
43+
self.result.append(data)
44+
self.cpos += self.refresh_size
45+

rcaudio/volume_analyzer.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import threading
2-
import logging
31
import time
42
import queue
53
from .base_analyzer import BaseAnalyzer
@@ -21,7 +19,7 @@ def register_recorder(self,recorder):
2119
self.rec_size = self.sr * self.rec_time
2220

2321
def run(self):
24-
while self.audio_data is None:
22+
while self.start_time is None:
2523
time.sleep(1)
2624
while self.running.isSet():
2725
while len(self.audio_data) > self.cpos:

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
setuptools.setup(
77
name="rcaudio",
8-
version="0.0.1",
8+
version="0.0.2",
99
author="mhy12345",
1010
author_email="maohanyang789@163.com",
11-
description="A realtime audio recording scripts",
11+
description="A real-time audio recording & analyzing library",
1212
long_description=long_description,
1313
long_description_content_type="text/markdown",
1414
url="https://github.com/mhy12345/rcaudio",

0 commit comments

Comments
 (0)