<commit_before>#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"
Bundler.setup
require "thread"
require "coreaudio"
require "fftw3"

Thread.abort_on_exception = true

DEVICE_ID   = ARGV.shift.to_i
WINDOW      = 1024
device      = CoreAudio.devices.find { |dev| dev.devid == DEVICE_ID.to_i }
fail "No such device ID!" unless device
inbuf       = device.input_buffer(WINDOW)
SAMPLE_RATE = device.actual_rate

puts "Sampling at #{SAMPLE_RATE}hz from #{device.name}..."
# def bin_freq(idx); (idx * SAMPLE_RATE) / WINDOW; end
# TODO: Do I need to add 1 to compensate for the DC bin?
def freq_bin(hz); ((hz * WINDOW) / SAMPLE_RATE).round; end

# Only care about frequencies from 300hz to 3khz...
# Do we need to go around the mid-point a la the pitch-shifting code did?
#     half = w.shape[1] / 2
#     f = FFTW3.fft(w, 1)
#     shift = 12
#     f.shape[0].times do |ch|
#       f[ch, (shift+1)...half] = f[ch, 1...(half-shift)]
#       f[ch, 1..shift] = 0
#       f[ch, (half+1)...(w.shape[1]-shift)] = f[ch, (half+shift+1)..-1]
#       f[ch, -shift..-1] = 0

bin_start = freq_bin(300)
bin_end   = freq_bin(3_000)
num_bins  = bin_end - bin_start + 1

# TODO: Look into this to allow routing AudioHijack output into processor? http://www.ambrosiasw.com/utilities/wta/
# http://www.abstractnew.com/2014/04/the-fast-fourier-transform-fft-without.html

queue = Queue.new
pitch_shift_th = Thread.start do
  min = Float::INFINITY
  max = 0.0
  loop do
    w = queue.pop
    break unless w
<commit_msg>Notes to myself and offset bin by one to account for DC bin.<commit_after>#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"
Bundler.setup
require "thread"
require "coreaudio"
require "fftw3"

Thread.abort_on_exception = true

DEVICE_ID   = ARGV.shift.to_i
# For 300Hz..3kHz:
#    512 == bins 4..36 (33)
#   1024 == bins 8..71 (64)
#   2048 == bins 15..140 (126)
#   4096 == bins 29..280 (252)
WINDOW      = 1024
device      = CoreAudio.devices.find { |dev| dev.devid == DEVICE_ID.to_i }
fail "No such device ID!" unless device
inbuf       = device.input_buffer(WINDOW)
SAMPLE_RATE = device.actual_rate

puts "Sampling at #{SAMPLE_RATE}hz from #{device.name}..."
# def bin_freq(idx); (idx * SAMPLE_RATE) / WINDOW; end
# TODO: Do I need to add 1 to compensate for the DC bin?
def freq_bin(hz); ((hz * WINDOW) / SAMPLE_RATE).round + 1; end

# Only care about frequencies from 300hz to 3khz...
# Do we need to go around the mid-point a la the pitch-shifting code did?
#     half = w.shape[1] / 2
#     f = FFTW3.fft(w, 1)
#     shift = 12
#     f.shape[0].times do |ch|
#       f[ch, (shift+1)...half] = f[ch, 1...(half-shift)]
#       f[ch, 1..shift] = 0
#       f[ch, (half+1)...(w.shape[1]-shift)] = f[ch, (half+shift+1)..-1]
#       f[ch, -shift..-1] = 0

bin_start = freq_bin(300)
bin_end   = freq_bin(3_000)
num_bins  = bin_end - bin_start + 1
puts "Getting bins #{bin_start}..#{bin_end} (#{num_bins} bins)."

# Internal Microphone, Noise Reduction:
#   No Offset:
#      512 Samples: Min=1069.6, Max=1331759.8
#     1024 Samples: Min=1477.9, Max=1874171.2
#     2048 Samples: Min=1984.8, Max=2620696.1
#     4096 Samples: Min=2638.2, Max=3489267.6
#   1 offset:
#      512 Samples: Min= 986.8, Max=1378807.9
#     1024 Samples: Min=1552.5, Max=1930567.0
#     2048 Samples: Min=1329.5, Max=2763622.3
#     4096 Samples: Min=2697.6, Max=3851381.3

# TODO: Look into this to allow routing AudioHijack output into processor? http://www.ambrosiasw.com/utilities/wta/
# http://www.abstractnew.com/2014/04/the-fast-fourier-transform-fft-without.html

queue = Queue.new
pitch_shift_th = Thread.start do
  min = Float::INFINITY
  max = 0.0
  loop do
    w = queue.pop
    break unless w

{'fraction_non_alphanumeric': 0.14895917815625845, 'fraction_numerical': 0.07191132738577995, 'mean_word_length': 3.1760722347629797, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6370681', 'n_tokens_mistral': 1644, 'n_tokens_neox': 1446, 'n_words': 378}