Last active
September 4, 2017 13:11
-
-
Save feisuzhu/16d0cccf88aa2e3ea55ee8ea8c9c64ca to your computer and use it in GitHub Desktop.
netmeter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
import pyaudio | |
pa = pyaudio.PyAudio() | |
for i in range(pa.get_device_count()): | |
dev = pa.get_device_info_by_index(i) | |
print '%s: %s' % (dev['index'], dev['name']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import | |
# -- stdlib -- | |
import argparse | |
import math | |
import time | |
# -- third party -- | |
# -- own -- | |
import numpy as np | |
import pyaudio | |
# -- code -- | |
parser = argparse.ArgumentParser('retro-netmeter') | |
parser.add_argument('dev', type=str) | |
parser.add_argument('--soundcard', type=int, default=None) | |
parser.add_argument('--bandwidth', type=float, default=20.0) | |
parser.add_argument('--ewma-coeff', type=float, default=0.6) | |
parser.add_argument('--volume', type=float, default=1.0) | |
parser.add_argument('--log-scale', action='store_true') | |
parser.add_argument('--value', type=float, default=None) | |
options = parser.parse_args() | |
audio = pyaudio.PyAudio() | |
stream = audio.open( | |
format=pyaudio.paFloat32, | |
channels=1, | |
rate=44100, | |
output=True, | |
frames_per_buffer=4410, | |
output_device_index=options.soundcard, | |
) | |
def get_netdev_bytes(dev): | |
b = int(open('/sys/class/net/%s/statistics/rx_bytes' % dev).read()) | |
b += int(open('/sys/class/net/%s/statistics/tx_bytes' % dev).read()) | |
return b | |
SAMPLE = [ | |
(0.002, 0.15), | |
(0.02, 0.28), (0.04, 0.35), (0.08, 0.4), (0.12, 0.44), (0.16, 0.48), | |
(0.2, 0.51), (0.24, 0.54), (0.28, 0.56), (0.32, 0.59), (0.37, 0.62), | |
(0.4, 0.64), (0.44, 0.66), (0.48, 0.69), (0.52, 0.71), (0.56, 0.73), | |
(0.6, 0.76), (0.64, 0.78), (0.68, 0.8), (0.72, 0.82), (0.76, 0.84), | |
(0.8, 0.86), (0.84, 0.88), (0.88, 0.9), (0.92, 0.92), (0.95, 0.94), (0.96, 0.95), | |
(1.0, 0.97), | |
] | |
def percent2volume(x): | |
for (p, v), (pn, vn) in zip([(0.0, 0.0)] + SAMPLE, SAMPLE): | |
if x == p: | |
return v | |
if p < x < pn: | |
return (x - p) / (pn - p) * (vn - v) + v | |
return vn | |
CARRIER = np.sin(np.array([440.0*2*math.pi*i/44100 for i in xrange(4410)], dtype=np.float32)) | |
def get_audio_data(percentage): | |
return (CARRIER * (options.volume * percent2volume(options.value or percentage))).tobytes() | |
last_t = time.time() | |
last_b = get_netdev_bytes(options.dev) | |
last_percentage = 0 | |
while True: | |
t = time.time() | |
b = get_netdev_bytes(options.dev) | |
rate = ((b - last_b) / (t - last_t)) / 1024.0 / 1024.0 | |
if options.log_scale: | |
percentage = math.log(1 + rate) / math.log(1 + options.bandwidth) | |
else: | |
percentage = rate / options.bandwidth | |
percentage = max(percentage, 0) | |
percentage = min(percentage, 1) | |
percentage = options.ewma_coeff * percentage + (1-options.ewma_coeff) * last_percentage | |
last_percentage = percentage | |
last_t = t | |
last_b = b | |
stream.write(get_audio_data(percentage)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import | |
# -- stdlib -- | |
import math | |
import threading | |
# -- third party -- | |
import numpy as np | |
import pyaudio | |
# -- own -- | |
# -- code -- | |
parser.add_argument('--soundcard', type=int, default=None) | |
options = parser.parse_args() | |
audio = pyaudio.PyAudio() | |
stream = audio.open( | |
format=pyaudio.paFloat32, | |
channels=1, | |
rate=44100, | |
output=True, | |
frames_per_buffer=4410, | |
output_device_index=options.soundcard, | |
) | |
CARRIER = np.sin(np.array([440.0*2*math.pi*i/44100 for i in xrange(4410)], dtype=np.float32)) | |
def get_audio_data(volume): | |
return CARRIER * volume | |
volume = 0.0 | |
class Sound(threading.Thread): | |
def run(self): | |
global volume | |
while True: | |
stream.write(get_audio_data(volume)) | |
t = Sound() | |
t.daemon = True | |
t.start() | |
lst = [] | |
for i in xrange(100): | |
volume = i / 100.0 | |
v = raw_input() | |
if v.strip(): | |
lst.append([eval(v), volume]) | |
print lst |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment