1. Components
  2. Tabs

Tabs

A set of layered sections of content that display one panel of content at a time.

Requires the 'use client' directive if React Server Components are being used.

Orientation

Content 1
Content 1

Disabled

Content 1
Content 1

Icons/stats

SoliditySolidity's logo.
GenerateAudioOutput.s.sol
1
// SPDX-License-Identifier: MIT
2
pragma solidity ^0.8.21;
3
4
import {Script} from "forge-std/Script.sol";
5
import {console} from "forge-std/Test.sol";
6
import {Base64} from "solady/utils/Base64.sol";
7
import {DynamicBufferLib} from "solady/utils/DynamicBufferLib.sol";
8
import {LibString} from "solady/utils/LibString.sol";
9
import {FixedPointMathLib as Math} from "solady/utils/FixedPointMathLib.sol";
10
11
import {FiveFiveFiveAudio} from "src/utils/FiveFiveFiveAudio.sol";
12
13
/// @notice A script to create and write the WAV audio file of the arrangement
14
/// of “Gonna Fly Now” by Bill Conti completely with smart contracts.
15
/// @dev You must run this script with a high `--memory-limit` option (e.g.
16
/// `50_000_000_000` works) and `--via-ir`.
17
contract GenerateAudioOutputScript is Script {
18
using DynamicBufferLib for DynamicBufferLib.DynamicBuffer;
19
using LibString for uint256;
20
using Math for int256;
21
using Math for uint256;
22
23
// -------------------------------------------------------------------------
24
// Constants
25
// -------------------------------------------------------------------------
26
27
/// @notice The total number of ticks for 1 cycle of the audio.
28
/// @dev Note that the length of the WAV file is written into the header
29
/// returned by {FiveFiveFiveAudio.getAudioWavFileHeader} to take in a
30
/// maximum of `776*2**10` samples. To change this, update the header
31
/// returned accordingly.
32
uint256 internal constant TICKS_PER_CYCLE = 776 << 10;
33
34
// -------------------------------------------------------------------------
35
// Script `run()`
36
// -------------------------------------------------------------------------
37
38
/// @notice Calls the {FiveFiveFiveAudio} library to generate the audio data
39
/// and writes the WAV file to `./output/wav/rocky.wav`.
40
function run() public {
41
DynamicBufferLib.DynamicBuffer memory buffer;
42
43
// First, write the WAV file header.
44
buffer.p(FiveFiveFiveAudio.getAudioWavFileHeader());
45
46
// Next, we form the audio data by calling `getSoundValueAtSample` for
47
// each sample in the range `[0, 776*2**10)` and write each result to
48
// `data`.
49
bytes memory data = new bytes(TICKS_PER_CYCLE);
50
for (uint256 tick; tick < TICKS_PER_CYCLE; ) {
51
data[tick] = bytes1(FiveFiveFiveAudio.getSoundValueAtSample(tick));
52
53
unchecked {
54
++tick;
55
}
56
}
57
58
buffer.p(data);
59
vm.writeFile("./output/wav/rocky.wav", string(buffer.data));
60
}
61
}

The above is from 555 (1000 × ⁵⁄₉), a ⁵⁄₉-themed NFT to commemorate me running 10000km in 555 days of running everyday. The code snippet above highlights the fully onchain audio aspect of the project.

To have the tab trigger buttons act as links, pass in a URL to the href prop. To open the link in a new tab, use the newTab prop. Note that the final component will be rendered as a <a> element, so browser features like right-clicking to open in a new tab will work.