This commit is contained in:
Nathan Rashleigh committed 2026-07-15 17:23:23 +10:00
commit 01bf18eb8d
9 files changed
+5409

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
/target
/~ambium.kicad_sch.lck
/.history
/.DS_Store
+6
View File
@@ -0,0 +1,6 @@
[package]
name = "ambium"
version = "0.1.0"
edition = "2024"
[dependencies]
+272
View File
@@ -0,0 +1,272 @@
# ambium
Analog **brown-noise generator** with a slow amplitude swell (LFO). All-analog,
breadboard-friendly, single **+12 V** supply. Deep, drifting rumble that slowly
breathes in and out over ~20 s.
Each stage is drawn as ASCII below. **Reference designators and model numbers are
consistent across every diagram, the BOM, and the connection list** — that list is
the authoritative netlist.
## Parts used (model numbers)
- **U1, U2** = **LM358** (dual op-amp, DIP-8). U1 = amp + integrator; U2 = LFO + buffer.
(LM258P is the same part — fine.)
- **Q1, Q2** = **2N3904** (NPN). Q1 = avalanche noise source; Q2 = shunt VCA.
## Nets
`+12V` · `GND` · `VREF` (6 V mid-supply) · `NOISE` · `AMP` · `BROWN` · `LFO` ·
`LFO_CV` · `VCA` · `AUDIO_OUT`
## Signal chain
```
[noise] [amplify] [integrate] [VCA] [buffer]
Q1 2N3904 → U1A LM358 ×1000 → U1B LM358 −6dB/oct → Q2 2N3904 → U2B LM358 → AUDIO_OUT
NOISE AMP BROWN VCA (line out)
▲
swell
U2A LM358 LFO (~0.05 Hz)
```
Legend for the diagrams:
```
[Rxx val] resistor ──┤├── capacitor ● junction (connected)
│\ × no-connect
────┤−\ op-amp: IN− top, IN+ bottom, ► net continues (same label)
│ >── OUT right. Powered from +12V/GND
────┤+ / via LM358 pins 8/4 (see Power).
│/
(C)
│
(B)┤< NPN 2N3904 (C=collector, B=base, E=emitter)
│
(E)
```
---
## Power · VREF divider (R2, R3, Cref)
```
+12V
│
[R2 10k]
│
●───────────────┬────────► VREF (6 V)
│ │
[R3 10k] ──┤├── Cref 10µF
│ │
GND GND
```
`R2`/`R3` = 20 kΩ across 12 V → 0.6 mA, midpoint = **6 V**. `Cref` holds VREF steady.
VREF is the AC ground every stage rides on (single supply, no negative rail).
---
## Stage 1 — White noise (R1, Q1, C1)
Reverse-biased base–emitter junction of `Q1` driven into avalanche = broadband white
noise. `R1` limits current; `C1` couples the noise out.
```
+12V
│
[R1 100k]
│
●──────┤├──────► NOISE
│ C1 10µF
(C) × (collector: no connect)
│
(B)─┤< Q1 2N3904
│
(E)
│
GND ← base to GND; avalanche appears across B-E, out at the R1/collector node
```
> Avalanche quality varies part-to-part. Try one 2N3904; if quiet, swap for another.
> Needs the full +12 V (9 V is often too low to avalanche).
---
## Stage 2 — Amplifier ×1000 (U1A, Rin1, Rf1)
Inverting amp, gain ≈ −Rf1/Rin1 = **×1000**. Output centred on VREF.
```
┌──────[Rf1 1M]──────┐
│ │
NOISE ──[Rin1 1k]──● │
│ │\ │
└───┤−\ │
│ >──●───────┴────► AMP
VREF ───────┤+ / U1A
│/ (LM358, unit A)
```
---
## Stage 3 — Integrator → brown (U1B, Rin2, Cint, Rf2)
Leaky integrator = **−6 dB/octave** → turns white into brown. `Rf2` bounds DC so the
output can't rail. Corner ≈ 1/(2π·Rf2·Cint) ≈ 1.6 Hz.
```
┌──────[Rf2 1M]──────┐
│ │
├───────┤├───────────┤ Cint 100nF (Rf2 ∥ Cint)
│ │
AMP ──[Rin2 10k]──● │
│ │\ │
└───┤−\ │
│ >──●───────┴────► BROWN
VREF ───────┤+ / U1B
│/ (LM358, unit B)
```
Darker/deeper: ↑ Cint or Rf2. Lighter (toward pink): ↓ Cint.
---
## Stage 4 — LFO (U2A, Rt, Ct, Ra, Rh)
Single-op-amp relaxation oscillator. Period ≈ 2.2·Rt·Ct ≈ **~22 s**. The control
voltage is the ramp on `Ct` (net `LFO_CV`) — it drives the VCA in Stage 5.
```
┌──────────[Rt 1M]──────────┐
│ │
●──────┤├──── VREF │ Ct 10µF (non-polar)
│ Ct │
│ │\ │
LFO_CV ●──────┤−\ │
│ │ >──●──────────────┴──► LFO (and to Rh)
┌──────┤+ / │ U2A
│ │/ │ (LM358, unit A)
●──[Ra 100k]──┤
│ └── VREF
[Rh 100k]
│
└───────────────────────────────────► LFO (hysteresis feedback)
```
`Ra`/`Rh` set the hysteresis (both 100k). `LFO_CV` ramps ~3.5–8.5 V.
> `Ct` sees a bipolar swing about VREF — use a **non-polar** 10 µF (film or bipolar
> electrolytic), not a standard polarised cap.
---
## Stage 5 — VCA + buffer + output (Rs, Q2, Rb2, U2B, Cout, Rvol)
`Q2` shunts the brown-noise signal to VREF (AC ground) by an amount set by `LFO_CV` →
amplitude swells and fades. `U2B` buffers; `Cout` blocks DC; `Rvol` sets level.
```
(C)
│
BROWN ──[Rs 47k]──●───────┤< Q2 2N3904
│ │
VCA (E)
│ │
│ VREF
│
LFO_CV ──[Rb2 100k]──(B) ← control voltage into Q2 base
│
│ │\
└───┤+\
│ >──●──────┤├──────●──[Rvol 10k]──► AUDIO_OUT
┌───┤−/ U2B Cout (wiper)
│ │/ (LM358 10µF │
│ unit B) GND
└──────────● (buffer: OUT tied back to IN−)
```
When `LFO_CV` is low → Q2 off → signal passes (loud). High → Q2 conducts → shunts to
VREF (quiet). ~20 s swell. Soften the swell: 1 µF from `LFO_CV` to VREF.
---
## LM358 power + decoupling
Each LM358 (U1, U2) is powered once via its package pins — **not** per op-amp unit:
```
+12V ──┬── U1 pin 8 (V+) GND ──┬── U1 pin 4 (V−)
│ │
└── U2 pin 8 (V+) └── U2 pin 4 (V−)
Decoupling: 0.1µF from +12V to GND at EACH chip, plus one 47µF bulk on the +12V rail.
```
LM358 unit A = pins 1(OUT) 2(IN−) 3(IN+); unit B = 7(OUT) 6(IN−) 5(IN+); power 8(V+) 4(V−).
---
## Bill of materials
| Ref | Value | Part / model | Function |
|-----|-------|--------------|----------|
| U1 | — | **LM358** (DIP-8) | U1A amp, U1B integrator |
| U2 | — | **LM358** (DIP-8) | U2A LFO, U2B buffer |
| Q1 | — | **2N3904** | avalanche white-noise source |
| Q2 | — | **2N3904** | shunt VCA |
| R1 | 100k | resistor | avalanche current limit |
| R2, R3 | 10k | resistor | VREF divider |
| Rin1 | 1k | resistor | amp input |
| Rf1 | 1M | resistor | amp feedback (×1000) |
| Rin2 | 10k | resistor | integrator input |
| Rf2 | 1M | resistor | integrator leak / brown corner |
| Rs | 47k | resistor | VCA series |
| Rb2 | 100k | resistor | LFO_CV → Q2 base |
| Rt | 1M | resistor | LFO timing |
| Ra, Rh | 100k | resistor | LFO hysteresis |
| Rvol | 10k | potentiometer | output level |
| C1 | 10µF | electrolytic | noise coupling |
| Cref | 10µF | electrolytic | VREF bypass |
| Cint | 100nF | film | integrator (brown shaping) |
| Cout | 10µF | electrolytic | output coupling |
| Ct | 10µF | **non-polar** | LFO timing (bipolar swing) |
| — | 0.1µF ×2 | ceramic | chip decoupling |
| — | 47µF | electrolytic | +12V bulk |
**Chip count: 2× LM358 + 2× 2N3904.** Single +12 V supply.
---
## Connection list (authoritative netlist)
```
+12V : R1.1, R2.1, U1.8, U2.8, (47µF+)
GND : R3.2, Q1.base, Cref.−, U1.4, U2.4, Rvol.3, (47µF−), (0.1µF ×2)
VREF : R2.2, R3.1, Cref.+, U1A.IN+(3), U1B.IN+(5), Ct(VREF end), Ra.1, Q2.emitter
NOISE : R1.2 / Q1.emitter-node, C1.+ (C1.− → Rin1.1)
AMP : U1A.OUT(1), Rf1, Rin2.1 (Rin1.2, Rf1, U1A.IN−(2) = summing node)
BROWN : U1B.OUT(7), Cint, Rf2, Rs.1 (Rin2.2, Cint, Rf2, U1B.IN−(6) = summing)
LFO : U2A.OUT(1), Rt, Rh
LFO_CV : Rt, Ct(CV end), U2A.IN−(2), Rb2 (ramp that swells the VCA)
VCA : Rs.2, Q2.collector, U2B.IN+(5)
(U2B.OUT(7) = U2B.IN−(6) = Cout.+ → buffer)
AUDIO_OUT : Rvol.wiper(2) (Cout.− → Rvol.1; Rvol.3 → GND)
Q1 : collector = no-connect
```
---
## Build & test order
Build one stage at a time — verify before adding the next.
1. **VREF** — R2/R3/Cref up. Confirm ~6.0 V.
2. **Noise (R1 + Q1)** — scope Q1 node → hiss (~mV). No noise? swap the 2N3904 or nudge supply to 12–15 V.
3. **Amp (U1A)** — scope AMP → loud hiss (~volts).
4. **Integrator (U1B)** — BROWN sounds darker/deeper than AMP. That's brown noise.
5. **LFO (U2A)** — scope LFO_CV → slow ramp, ~20 s.
6. **VCA + buffer (Q2, U2B)** — full chain: noise swells and fades on the LFO cycle.
## Tuning
| Want | Change |
|------|--------|
| Deeper/darker | ↑ Cint or Rf2 |
| Lighter (toward pink) | ↓ Cint |
| Slower swell | ↑ Rt or Ct |
| Faster swell | ↓ Rt or Ct |
| Softer swell onset | 1µF from LFO_CV to VREF |
| Louder | ↑ Rf1 (watch clipping) |
+2
View File
@@ -0,0 +1,2 @@
(kicad_pcb (version 20260206) (generator "pcbnew") (generator_version "10.0")
)
+105
View File
@@ -0,0 +1,105 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"shapes": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"prototype_zone_fills": false,
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
"vias",
"footprint_text",
"footprint_anchors",
"ratsnest",
"grid",
"footprints_front",
"footprints_back",
"footprint_values",
"footprint_references",
"tracks",
"drc_errors",
"drawing_sheet",
"bitmaps",
"pads",
"zones",
"drc_warnings",
"drc_exclusions",
"locked_item_shadows",
"conflict_shadows",
"shapes",
"board_outline_area",
"ly_points"
],
"visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
"zone_display_mode": 0
},
"git": {
"integration_disabled": false,
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": {
"filename": "ambium.kicad_prl",
"version": 5
},
"net_inspector_panel": {
"col_hidden": [],
"col_order": [],
"col_widths": [],
"custom_group_rules": [],
"expanded_rows": [],
"filter_by_net_name": true,
"filter_by_netclass": true,
"filter_text": "",
"group_by_constraint": false,
"group_by_netclass": false,
"show_time_domain_details": false,
"show_unconnected_nets": false,
"show_zero_pad_nets": false,
"sort_ascending": true,
"sorting_column": -1
},
"open_jobsets": [],
"project": {
"files": []
},
"schematic": {
"hierarchy_collapsed": [],
"selection_filter": {
"graphics": true,
"images": true,
"labels": true,
"lockedItems": false,
"otherItems": true,
"pins": true,
"ruleAreas": true,
"symbols": true,
"text": true,
"wires": true
}
}
}
+443
View File
@@ -0,0 +1,443 @@
{
"board": {
"3dviewports": [],
"ipc2581": {
"bom_rev": "",
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": "",
"sch_revision": ""
},
"layer_pairs": [],
"layer_presets": [],
"viewports": []
},
"boards": [],
"component_class_settings": {
"assignments": [],
"meta": {
"version": 0
},
"sheet_component_classes": {
"enabled": false
}
},
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"field_name_whitespace": "warning",
"footprint_filter": "ignore",
"footprint_link_issues": "warning",
"four_way_junction": "ignore",
"ground_pin_not_ground": "warning",
"hier_label_mismatch": "error",
"isolated_pin_label": "warning",
"label_dangling": "error",
"label_multiple_wires": "warning",
"lib_symbol_issues": "warning",
"lib_symbol_mismatch": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"same_local_global_label": "warning",
"similar_label_and_power": "warning",
"similar_labels": "warning",
"similar_power": "warning",
"simulation_model_issue": "ignore",
"single_global_label": "ignore",
"stacked_pin_name": "warning",
"unannotated": "error",
"unconnected_wire_endpoint": "warning",
"undefined_netclass": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "ambium.kicad_pro",
"version": 3
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"priority": 2147483647,
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"tuning_profile": "",
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 5
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"idf": "",
"netlist": "",
"plot": "",
"specctra_dsn": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"annotation": {
"method": 0,
"sort_order": 0
},
"bom_export_filename": "${PROJECTNAME}.csv",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
},
{
"group_by": true,
"label": "Exclude from BOM",
"name": "${EXCLUDE_FROM_BOM}",
"show": true
},
{
"group_by": true,
"label": "Exclude from Board",
"name": "${EXCLUDE_FROM_BOARD}",
"show": true
},
{
"group_by": true,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"include_excluded_from_bom": true,
"name": "Default Editing",
"sort_asc": true,
"sort_field": "Reference"
},
"bus_aliases": {},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"hop_over_size_choice": 0,
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"ngspice": {
"fix_include_paths": true,
"meta": {
"version": 0
},
"model_mode": 4,
"workbook_filename": ""
},
"page_layout_descr_file": "",
"plot_directory": "",
"reuse_designators": true,
"subpart_first_id": 65,
"subpart_id_separator": 0,
"top_level_sheets": [
{
"filename": "ambium.kicad_sch",
"name": "Root",
"uuid": "5ab6832c-376c-4ebe-b1c2-82e1b27b6200"
}
],
"used_designators": "U1",
"variants": []
},
"sheets": [
[
"5ab6832c-376c-4ebe-b1c2-82e1b27b6200",
"Root"
]
],
"text_variables": {},
"tuning_profiles": {
"meta": {
"version": 0
},
"tuning_profiles_impedance_geometric": []
}
}
+4550
View File
File diff suppressed because it is too large. Load diff
+24
View File
@@ -0,0 +1,24 @@
.title KiCad schematic
U1 __U1
Rf1 /VREF /AMP 1Meg
Rin2 /AMP /VREF 10k
U2 __U2
Cout Net-_U2B--_ Net-_Cout-Pad2_ 10u
Rin1 Net-_C1-Pad2_ /VREF 1k
R2 +12V /VREF 10k
Q1 __Q1
C1 Net-_Q1-E_ Net-_C1-Pad2_ 10u
R3 /VREF GND 10k
R1 +12V Net-_Q1-E_ 100k
Cref /VREF GND 10u
Ra /VREF Net-_U2A-+_ 100k
Ct /LFO_CV /VREF 10u
Rt /LFO_CV Net-_Rh-Pad2_ 1Meg
Rb2 /LFO_CV Net-_Q2-B_ 100k
Rs /BROWN Net-_Q2-C_ 47k
Q2 __Q2
Rh Net-_U2A-+_ Net-_Rh-Pad2_ 100k
Cint /VREF /BROWN 100n
Rf2 /VREF /BROWN 1Meg
Rvol __Rvol
.end
+3
View File
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}