Skip to content

Commit 498a3cf

Browse files
committed
implement binaural beat generation engine and CLI application.
0 parents  commit 498a3cf

File tree

13 files changed

+994
-0
lines changed

13 files changed

+994
-0
lines changed

.bazelignore

Whitespace-only changes.

.bazelrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build --strategy=Scalac=worker
2+
build --worker_sandboxing

.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.0.0

.gitignore

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
_run/*
2+
3+
# General
4+
.DS_Store
5+
.AppleDouble
6+
.LSOverride
7+
8+
# Icon must end with two \r
9+
Icon
10+
11+
# Thumbnails
12+
._*
13+
14+
# Files that might appear in the root of a volume
15+
.DocumentRevisions-V100
16+
.fseventsd
17+
.Spotlight-V100
18+
.TemporaryItems
19+
.Trashes
20+
.VolumeIcon.icns
21+
.com.apple.timemachine.donotpresent
22+
23+
# Directories potentially created on remote AFP share
24+
.AppleDB
25+
.AppleDesktop
26+
Network Trash Folder
27+
Temporary Items
28+
29+
# Docker project generated files to ignore
30+
# if you want to ignore files created by your editor/tools,
31+
# please consider a global .gitignore https://help.github.com/articles/ignoring-files
32+
.vagrant*
33+
bin
34+
docker/docker
35+
.*.swp
36+
a.out
37+
*.orig
38+
build_src
39+
.flymake*
40+
.idea
41+
.DS_Store
42+
docs/_build
43+
docs/_static
44+
docs/_templates
45+
.gopath/
46+
.dotcloud
47+
*.test
48+
bundles/
49+
.hg/
50+
.git/
51+
vendor/pkg/
52+
pyenv
53+
Vagrantfile
54+
**/Payload
55+
56+
# Ignore backup files.
57+
*~
58+
# Ignore Vim swap files.
59+
.*.swp
60+
# Ignore files generated by IDEs.
61+
**/.classpath
62+
**/.factorypath
63+
# ignoring these breaks shared runconfigs so everyone will need to manually configure their run commands and flags. Have fun!
64+
**/.idea/
65+
**/.ijwb/
66+
**/.project
67+
**/.settings
68+
**/.vscode/
69+
**/bazel.iml
70+
# Ignore all bazel-* symlinks. There is no full list since this can change
71+
# based on the name of the directory bazel is cloned into.
72+
**/bazel-*
73+
# Ignore outputs generated during Bazel bootstrapping.
74+
**/output/
75+
# Ignore jekyll build output.
76+
production
77+
.sass-cache
78+
# User-specific .bazelrc
79+
user.bazelrc

BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Binaural Beats Generator
2+
3+
A binaural beat is an [auditory illusion](https://en.wikipedia.org/wiki/Auditory_illusion) [perceived](https://en.wikipedia.org/wiki/Perception) when two different pure-tone [sine waves](https://en.wikipedia.org/wiki/Sine_wave), both with [frequencies](https://en.wikipedia.org/wiki/Frequency) lower than 1500 Hz, with less than a 40 Hz difference between them, are presented to a [listener](https://en.wikipedia.org/wiki/Hearing) dichotically (one through each [ear](https://en.wikipedia.org/wiki/Ear)).
4+
5+
This command line program generates binaural beats.
6+
7+
## Build & Run from Source:
8+
9+
```bash
10+
bazel run //cli:app -- alpha
11+
```
12+
13+
## Usage:
14+
15+
```
16+
Usage: binaural [delta|theta|alpha|beta|gamma] [options]
17+
18+
Command: delta
19+
Delta pattern preset; Binaural beats in the delta pattern operate at a frequency of 0.5–4 Hz with links to a dreamless sleep.
20+
Command: theta
21+
Theta pattern preset; Practitioners set binaural beats in the theta pattern to a frequency of 4–7 Hz. Theta patterns contribute to improved meditation, creativity, and sleep in the rapid eye movement (REM) phase.
22+
Command: alpha
23+
Alpha pattern preset; Binaural beats in the alpha pattern are at a frequency of 7–13 Hz and may encourage relaxation.
24+
Command: beta
25+
Beta pattern preset; Binaural beats in the beta pattern are at a frequency of 13–30 Hz. This frequency range may help promote concentration and alertness. However, it can also increase anxiety at the higher end of the range.
26+
Command: gamma
27+
Gamma pattern preset; This frequency pattern accounts for a range of 30–50 Hz. The study authors suggest that frequencies promote maintenance of arousal while a person is awake.
28+
-p, --pitch <value> the frequency in Hz - an integer property
29+
-b, --binaural_pitch <value> the binaural tone's frequency - a decimal property
30+
-d, --duration <value> the duration for which to play the binaural audio - an integer property
31+
```
32+
33+
## More About Binaural Beats:
34+
(via Wikipedia)
35+
36+
A binaural beat is an [auditory illusion](https://en.wikipedia.org/wiki/Auditory_illusion) [perceived](https://en.wikipedia.org/wiki/Perception) when two different pure-tone [sine waves](https://en.wikipedia.org/wiki/Sine_wave), both with [frequencies](https://en.wikipedia.org/wiki/Frequency) lower than 1500 Hz, with less than a 40 Hz difference between them, are presented to a [listener](https://en.wikipedia.org/wiki/Hearing) dichotically (one through each [ear](https://en.wikipedia.org/wiki/Ear)).
37+
38+
For example, if a 530 Hz pure [tone](https://en.wikipedia.org/wiki/Pitch_(music)) is presented to a subject's right ear, while a 520 Hz pure tone is presented to the subject's left ear, the listener will perceive the [auditory illusion](https://en.wikipedia.org/wiki/Auditory_illusion) of a third tone, in addition to the two pure-tones presented to each ear. The third sound is called a binaural beat, and in this example would have a perceived pitch correlating to a frequency of 10 Hz, that being the difference between the 530 Hz and 520 Hz pure tones presented to each ear.[[citation needed](https://en.wikipedia.org/wiki/Wikipedia:Citation_needed)]
39+
40+
Binaural-beat perception originates in the [inferior colliculus](https://en.wikipedia.org/wiki/Inferior_colliculus) of the [midbrain](https://en.wikipedia.org/wiki/Midbrain) and the [superior olivary complex](https://en.wikipedia.org/wiki/Superior_olivary_complex) of the [brainstem](https://en.wikipedia.org/wiki/Brainstem), where [auditory signals](https://en.wikipedia.org/wiki/Audio_signal_processing) from each [ear](https://en.wikipedia.org/wiki/Ear) are integrated and precipitate [electrical impulses](https://en.wikipedia.org/wiki/Action_potential) along [neural pathways](https://en.wikipedia.org/wiki/Neural_pathway) through the [reticular formation](https://en.wikipedia.org/wiki/Reticular_formation) up the midbrain to the [thalamus](https://en.wikipedia.org/wiki/Thalamus), [auditory cortex](https://en.wikipedia.org/wiki/Auditory_cortex), and other cortical regions.[[6]](https://en.wikipedia.org/wiki/Beat_(acoustics)#cite_note-oster-6)
41+
42+
Some potential benefits of binaural beats therapy may include: reduced [stress](https://en.wikipedia.org/wiki/Psychological_stress), reduced [anxiety](https://en.wikipedia.org/wiki/Anxiety), increased focus, increased concentration, increased motivation, increased confidence, and deeper [meditation](https://en.wikipedia.org/wiki/Meditation).[[7]](https://en.wikipedia.org/wiki/Beat_(acoustics)#cite_note-MedicalNewsToday-7)

WORKSPACE

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
rules_scala_version="bd0c388125e12f4f173648fc4474f73160a5c628" # update this as needed
2+
3+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
4+
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
5+
6+
http_archive(
7+
name = "bazel_skylib",
8+
urls = [
9+
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
10+
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.2/bazel-skylib-1.0.2.tar.gz",
11+
],
12+
sha256 = "97e70364e9249702246c0e9444bccdc4b847bed1eb03c5a3ece4f83dfe6abc44",
13+
)
14+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
15+
bazel_skylib_workspace()
16+
17+
http_archive(
18+
name = "io_bazel_rules_scala",
19+
strip_prefix = "rules_scala-%s" % rules_scala_version,
20+
type = "zip",
21+
url = "https://github.com/bazelbuild/rules_scala/archive/%s.zip" % rules_scala_version,
22+
)
23+
24+
load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_toolchains")
25+
scala_register_toolchains()
26+
27+
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_repositories")
28+
scala_repositories()
29+
30+
protobuf_version="09745575a923640154bcf307fba8aedff47f240a"
31+
protobuf_version_sha256="416212e14481cff8fd4849b1c1c1200a7f34808a54377e22d7447efdf54ad758"
32+
33+
http_archive(
34+
name = "com_google_protobuf",
35+
url = "https://github.com/protocolbuffers/protobuf/archive/%s.tar.gz" % protobuf_version,
36+
strip_prefix = "protobuf-%s" % protobuf_version,
37+
sha256 = protobuf_version_sha256,
38+
)
39+
40+
RULES_JVM_EXTERNAL_TAG = "3.0"
41+
RULES_JVM_EXTERNAL_SHA = "62133c125bf4109dfd9d2af64830208356ce4ef8b165a6ef15bbff7460b35c3a"
42+
43+
http_archive(
44+
name = "rules_jvm_external",
45+
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
46+
sha256 = RULES_JVM_EXTERNAL_SHA,
47+
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
48+
)
49+
50+
load("@rules_jvm_external//:defs.bzl", "maven_install")
51+
52+
maven_install(
53+
name = "maven",
54+
artifacts = [
55+
"com.github.scopt:scopt_2.11:4.0.0-RC2",
56+
"junit:junit:4.12",
57+
"com.novocode:junit-interface:0.11",
58+
"org.scalaz:scalaz-core_2.11:7.2.7",
59+
"org.scalatest:scalatest_2.11:2.2.4",
60+
"org.apache.thrift:libthrift:0.9.3",
61+
"org.eclipse.jetty:jetty-servlet:9.4.0.M0",
62+
"org.eclipse.jetty:jetty-servlets:9.4.0.M0",
63+
"org.openjdk.jmh:jmh-core:1.12",
64+
"com.github.yannrichet:JMathPlot:1.0.1",
65+
"org.auroboros:signal-z_2.11:0.1.0",
66+
"org.clojars.sidec:jsyn:16.7.3",
67+
"org.apache.commons:commons-math3:3.6",
68+
"ch.qos.logback:logback-classic:1.1.7"
69+
],
70+
repositories = [
71+
"https://jcenter.bintray.com/",
72+
"https://maven.google.com",
73+
"https://repo1.maven.org/maven2",
74+
],
75+
maven_install_json = "//:maven_install.json",
76+
)
77+
78+
load("@maven//:defs.bzl", "pinned_maven_install")
79+
pinned_maven_install()
80+
81+
git_repository(
82+
name = "zachgrayio_scalaudio",
83+
commit = "6d7dfabd71392a6b15ff3eea8b86945b12ad20f5",
84+
remote = "http://github.com/zachgrayio/scalaudio.git",
85+
shallow_since = "1578573315 +1100"
86+
)

cli/BUILD

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
load(
2+
"@io_bazel_rules_scala//scala:scala.bzl",
3+
"scala_binary",
4+
)
5+
6+
scala_binary(
7+
name = "app",
8+
srcs = glob(["src/main/**/*.scala"]),
9+
main_class = "io.zachgray.binauralBeats.cli.BinauralApp",
10+
deps = [
11+
"//engine:engine",
12+
"@maven//:com_github_scopt_scopt_2_11",
13+
],
14+
visibility = ["//visibility:public"]
15+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.zachgray.binauralBeats.cli
2+
3+
import io.zachgray.binauralBeats.engine.{BinauralBeatsConfiguration, BinauralEngine}
4+
import scopt.OParser
5+
6+
object BinauralApp extends App {
7+
/**
8+
* Main function - the entrypoint for the CLI application.
9+
*
10+
* Invokes the Binaural Engine with configuration values passed via command line flags.
11+
* @param args
12+
*/
13+
override def main(args: Array[String]): Unit = {
14+
parseBinauralBeatsConfiguration(args) match {
15+
case Some(config) => BinauralEngine.play(config)
16+
case _ =>
17+
}
18+
}
19+
20+
/**
21+
* Parses command line options and returns binaural beats configuration.
22+
*
23+
* @param args
24+
* @return BinauralBeatConfiguration
25+
*/
26+
private def parseBinauralBeatsConfiguration(args: Array[String]): Option[BinauralBeatsConfiguration] = {
27+
val builder = OParser.builder[BinauralBeatsConfiguration]
28+
val optionsParser: OParser[Unit, BinauralBeatsConfiguration] = {
29+
import builder._
30+
OParser.sequence(
31+
programName("binaural"),
32+
33+
// presets
34+
35+
cmd("delta")
36+
.action((_, c) => c.copy(binauralPitch = 3))
37+
.text("Delta pattern preset; Binaural beats in the delta pattern operate at a frequency of 0.5–4 Hz with links to a dreamless sleep."),
38+
39+
cmd("theta")
40+
.action((_, c) => c.copy(binauralPitch = 5.5))
41+
.text("Theta pattern preset; Practitioners set binaural beats in the theta pattern to a frequency of 4–7 Hz. " +
42+
"Theta patterns contribute to improved meditation, creativity, and sleep in the rapid eye movement (REM) phase."),
43+
44+
cmd("alpha")
45+
.action((_, c) => c.copy(binauralPitch = 10))
46+
.text("Alpha pattern preset; Binaural beats in the alpha pattern are at a frequency of 7–13 Hz and may encourage relaxation."),
47+
48+
cmd("beta")
49+
.action((_, c) => c.copy(binauralPitch = 20))
50+
.text("Beta pattern preset; Binaural beats in the beta pattern are at a frequency of 13–30 Hz. This frequency range " +
51+
"may help promote concentration and alertness. However, it can also increase anxiety at the higher end of the range."),
52+
53+
cmd("gamma")
54+
.action((_, c) => c.copy(binauralPitch = 40))
55+
.text("Gamma pattern preset; This frequency pattern accounts for a range of 30–50 Hz. The study authors suggest that " +
56+
"frequencies promote maintenance of arousal while a person is awake."),
57+
58+
// full customization
59+
60+
opt[Double]('p', "pitch")
61+
.action((x, c) => c.copy(pitch = x))
62+
.text("the frequency in Hz - an integer property"),
63+
64+
opt[Double]('b', "binaural_pitch")
65+
.action((x, c) => c.copy(binauralPitch = x))
66+
.text("the binaural tone's frequency - a decimal property"),
67+
68+
opt[Int]('d', "duration")
69+
.action((x, c) => c.copy(duration = x))
70+
.text("the duration for which to play the binaural audio - an integer property")
71+
)
72+
}
73+
OParser.parse(optionsParser, args, BinauralBeatsConfiguration())
74+
}
75+
}

engine/BUILD

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
load(
2+
"@io_bazel_rules_scala//scala:scala.bzl",
3+
"scala_library",
4+
)
5+
6+
scala_library(
7+
name = "engine",
8+
srcs = glob(["src/main/**/*.scala"]),
9+
deps = [
10+
"@zachgrayio_scalaudio//scalaudio-amp:scalaudio-amp",
11+
],
12+
exports = [
13+
"@zachgrayio_scalaudio//scalaudio-amp:scalaudio-amp",
14+
],
15+
visibility = ["//visibility:public"]
16+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package io.zachgray.binauralBeats.engine
2+
3+
case class BinauralBeatsConfiguration(pitch: Double = 300, binauralPitch: Double = 10, duration: Int = 30)

0 commit comments

Comments
 (0)