Skip to main content

ToneBarrier

A whiteboard, scrapbook, loose-leaf journal and junk drawer for ToneBarrier

App Distribution

Install ToneBarrier via TestFlight



Schematics

Tone Tetrad Structure


Tone Pair Initialization Process

The tone tetrad initialization sequence

Tone duration specifications

\(x_1 \in [a, b] \quad \text{and} \quad x_2 \in [a, b] \quad \text{such that} \quad |x_1 - x_2| \geq d \quad \text{with segments} \quad [a, x_1], [x_1, b] \quad \text{and} \quad [a, x_2], [x_2, b]\)

The specifications for randomly choosing durations of tones (x1 and x2)

### 1. Inequality Notation with Segments

\[
x_1 \in [a, b] \quad \text{and} \quad x_2 \in [a, b] \quad \text{such that} \quad |x_1 - x_2| \geq d \quad \text{with segments} \quad [a, x_1], [x_1, b] \quad \text{and} \quad [a, x_2], [x_2, b]

\]

#### Explanation:

- **Interval Membership**: \(x_1 \in [a, b]\) and \(x_2 \in [a, b]\) indicate that both \(x_1\) and \(x_2\) are chosen from within the interval \([a, b]\). This means \(x_1\) and \(x_2\) can be any value between \(a\) and \(b\).
- **Distance Constraint**: The condition \(|x_1 - x_2| \geq d\) specifies that the absolute difference between \(x_1\) and \(x_2\) must be at least \(d\). This ensures that the two chosen values are not too close to each other.
- **Segments Creation**: The notation explicitly states that the segments created by choosing \(x_1\) and \(x_2\) are \([a, x_1]\) and \([x_1, b]\) for \(x_1\), and \([a, x_2]\) and \([x_2, b]\) for \(x_2\). This indicates that each choice creates two segments from the same interval \([a, b]\), divided at the points \(x_1\) and \(x_2\).
This notation is straightforward and easy to understand. It clearly defines the range and the conditions, but it may not be as formal or as mathematically rigorous as the set notation or Cartesian product notation. It is well-suited for practical use cases where simplicity is preferred.

### 2. Set Notation with Segments

\[
\{(x_1, x_2) \mid x_1, x_2 \in [a, b] \text{ and } |x_1 - x_2| \geq d \quad \text{with segments} \quad [a, x_1], [x_1, b] \quad \text{and} \quad [a, x_2], [x_2, b]\}
\]

#### Explanation:

- **Set Definition**: The curly braces \(\{\}\) define a set, and the notation within the braces describes the elements of this set.
- **Pairs of Numbers**: The notation \((x_1, x_2)\) indicates that the elements of the set are pairs of numbers.
- **Condition on Pairs**: The vertical bar \(\mid\) means "such that," and it specifies the condition that the pairs \((x_1, x_2)\) must satisfy.
- **Interval Membership**: \(x_1, x_2 \in [a, b]\) means both \(x_1\) and \(x_2\) are chosen from within the interval \([a, b]\).
- **Distance Constraint**: The condition \(|x_1 - x_2| \geq d\) ensures that the absolute difference between \(x_1\) and \(x_2\) is at least \(d\).
- **Segments Creation**: The notation explicitly mentions the segments created by each choice: \([a, x_1]\) and \([x_1, b]\) for \(x_1\), and \([a, x_2]\) and \([x_2, b]\) for \(x_2\).
This notation is formal and precise. It clearly defines a set of pairs of numbers that meet the specified conditions. It is well-suited for mathematical writing and proofs where rigor and clarity are important. The explicit mention of segments helps to clearly convey the idea that each choice of \(x_1\) and \(x_2\) creates two segments from the interval \([a, b]\).

### Comparison

- **Inequality Notation**: Simple and practical. Easy to understand and use in everyday contexts. Clearly states the range and conditions but is less formal.
- **Set Notation**: More formal and precise. Clearly defines a set of pairs that meet the conditions. Suitable for mathematical contexts where rigor is important.
Ultimately, the choice between these notations depends on the context in which you are using them. For formal mathematical definitions, set notation is more appropriate. For practical or less formal contexts, inequality notation might be preferable.

Code

//

//  File.swift

//  ToneBarrier

//

//  Created by James Alan Bush on 5/16/24.

//


import SwiftUI

import Foundation

import Combine

import Observation


@Observable class Durations {

    var durationLength:     Double = 2.0000

    var durationLowerBound: Double = 0.3125

    var durationUpperBound: Double = 1.6875

    var durationToleranceDouble = 0.3125


    init(length: Double?, lowerBound: Double?, upperBound: Double?, tolerance: Double?) {

        self.durationLength     = length     ?? durationLength

        self.durationLowerBound = lowerBound ?? durationLowerBound

        self.durationUpperBound = upperBound ?? durationUpperBound

        self.durationTolerance  = tolerance  ?? durationTolerance

       

        guard (durationUpperBound - durationLowerBound) >= durationTolerance else {

            fatalError("\(#function) error: |durationLowerBound - durationUpperBound| < durationTolerance")

        }

    }


    func scale(oldMin: CGFloat, oldMax: CGFloat, value: CGFloat, newMin: CGFloat, newMax: CGFloat) -> CGFloat {

        return newMin + ((newMax - newMin) * ((value - oldMin) / (oldMax - oldMin)))

    }


    let serialQueue = DispatchQueue(label: "com.example.serialQueue")


    public func randomizeDurationSplits(completion: @escaping ([[Double]]) -> Void) {

        serialQueue.async { [self] in

            let dyad0harmony0: Double = Double.random(in: durationLowerBound...durationUpperBound)

            var dyad1harmony0: Double = dyad0harmony0


            repeat {

                dyad1harmony0 = Double.random(in: durationLowerBound...durationUpperBound)

            } while (abs(dyad0harmony0 - dyad1harmony0) < durationTolerance)


            let dyad0harmony1 = durationLength - dyad0harmony0

            let dyad1harmony1 = durationLength - dyad1harmony0


            let result = [[dyad0harmony0, dyad0harmony1], [dyad1harmony0, dyad1harmony1]]


            DispatchQueue.main.async {

                completion(result)

            }

        }

    }

}


struct ContentView: View {

    private var durations: Durations = Durations(length: nil, lowerBound: nil, upperBound: nil, tolerance: nil)

    @State private var results: [[[Double]]] = []


    var body: some View {

        ZStack(alignment: Alignment(horizontal: .center, vertical: .center), content: {

            List(results, id: \.self) { result in


                let diff = abs(result[0][0] - result[1][0])

                let sum = result[0][0] + result[0][1]


                let formattedDiff = String(format: "-%.4f", diff)

                let formattedSum = String(format: "+%.4f", sum)


                let diffColor = diff >= 0.3125 ? UIColor.green : UIColor.red

                let sumColor = sum == 2.0000 ? UIColor.green : UIColor.red


                let text = NSMutableAttributedString(string: "\(result[0][0])\n\(result[1][0])\n")


                let coloredDiff = NSAttributedString(

                    string: formattedDiff,

                    attributes: [.foregroundColor: diffColor]

                )

                text.append(coloredDiff)

                text.append(NSAttributedString(string: "\n"))


                let coloredSum = NSAttributedString(

                    string: formattedSum,

                    attributes: [.foregroundColor: sumColor]

                )

                text.append(coloredSum)

                //

                return Text(AttributedString(text))

                    .frame(alignment: .leading)

                    .border(.white)

                    .padding()

            }


            Button("Randomize Duration Splits") {

                durations.randomizeDurationSplits { result in

                    print(result)

                    results.append(result)

                }

            }

            .safeAreaPadding()

            .border(.white)

        })

    }

}


@main

struct MyApp: App {

    var body: some Scene {

        WindowGroup {

            ContentView()

        }

    }

}


A more efficient solution(?):

func generateTwoSets(a: Double, b: Double, d: Double) -> (([Double], [Double]), ([Double], [Double])) {

        

        var x1_1: Double = Double.random(in: a...b)

        var x2_1: Double = Double.random(in: a...b)

        

        (x1_1, x2_1) = 

            {

                while abs(x1_1 - x2_1) < d {

                    x1_1 = Double.random(in: a...b)

                    x2_1 = Double.random(in: a...b)

                }

                

                return (x1_1, x2_1)

            }()

        

        let (x1_2, x2_2) = (x1_1, x2_1)

    

        let set1: ([Double], [Double]) = ([a, x1_1], [x1_2, b])

        let set2: ([Double], [Double]) = ([a, x2_1], [x2_2, b])

        

        return (set1, set2)

    }


Slogans

With both eyes closed.

The phrase "With both eyes closed" is a fragment of the widely known taunt, "I could beat you with one hand tied behind my back and both eyes closed." Through a combination of idiomatic expression, hyperbole, conditional structure, and imagery, the original taunt serves to strongly convey the speaker's confidence and perceived superiority in a creative and figurative manner. While asleep, ToneBarrier beats the problem with both eyes closed. 

It conveys:

the speaker's confidence in their superiority or ability to easily outperform the other person, even under significantly disadvantaged conditions.

exaggerates the ease with which the speaker could achieve victory to emphasize their perceived skill or ability

While it borrows from the original taunt, the phrase gains its own linguistic identity… [here’s how it differs]

The original taunt is considered hyperbole, a figure of speech that involves exaggerated statements or claims not meant to be taken literally. With ToneBarrier, “with both eyes closed” is meant literally, and conveys the ease with which one could achieve victory to emphasize their perceived skill or ability.

The original taunt employs vivid imagery to create a mental picture of one being significantly handicapped (with one hand tied and eyes closed) yet still managing to succeed, which makes the statement more impactful. “With both eyes closed” is when ToneBarrier works.

LFO curve (also for random distributions)

A standardized distribution curve (using a normalized sinc curve with a coefficient of 2)

Requisite Tone Frequencies Power Spectral Density

To stop the paralyzing fear characteristic of night terrors, the ToneBarrier score must play at least 30 seconds of tones ranging in frequency between 2,000 and 3,000 Hz, and 2 minutes and 30 seconds of tones ranging in frequency between 500 and 1,500 Hz — all randomly assigned using a Gaussian normal distribution curve.

Whether a ToneBarrier score meets this requirement can be determined by calculating the Power Spectral Density (PSD). 

Following is a plot for a 3-minute discrete-time signal made up of Gaussian-distributed random tone pairs that shows the minimal PSD for an effective score.

For a 3-second segment of the signal, the Power Spectral Density (PSD) values range approximately from:

  • Minimum PSD: 2.13 × 10⁻¹⁰ V²/Hz
  • Maximum PSD: 8.38 × 10⁻³ V²/Hz
This range reflects the expected concentration of power within the active tone frequency bands (500–1500 Hz and 2000–3000 Hz). 

The power spectral density for a discrete time period of 3 minutes of random frequencies in pairs of two (tone pairs), 30 seconds of which contain tone pairs, where each tone in a pair is a random frequency between 2000 Hz to 3000 Hz, and 2 minutes and 30 seconds of tone pairs, where each tone in a pair is a random frequency between 500 Hz and 1500 Hz; and, where the overall duration of each tone pair is 2 seconds, where the first tone in a pair is a random value between 0.25 and 1.75 seconds, and the second tone is the difference between the overall pair duration of 2 seconds and the duration of the first tone.

Source: ChatGPT 5