pragma solidity ^0.7.1; contract MidiContract { struct NoteEvent { bytes pitch; uint8 duration; } struct Track { NoteEvent[] events; } function generateMidiFile() public pure returns (string memory) { Track[] memory tracks = new Track[](1); Track memory track = Track({ events: [ NoteEvent({ pitch: hex"45 34", duration: 4 }), NoteEvent({ pitch: hex"43", duration: 2 }), NoteEvent({ pitch: hex"45 34", duration: 4 }), NoteEvent({ pitch: hex"43", duration: 2 }), NoteEvent({ pitch: hex"43 43 43 43 44 44 44 44", duration: 8 }), NoteEvent({ pitch: hex"45 34", duration: 4 }), NoteEvent({ pitch: hex"43", duration: 2 }) ] }); tracks[0] = track; string memory midiData = ""; for (uint i = 0; i < tracks.length; i++) { Track memory t = tracks[i]; string memory trackData = ""; for (uint j = 0; j < t.events.length; j++) { NoteEvent memory e = t.events[j]; string memory noteData = string(abi.encodePacked( "pitch:", e.pitch, ";", "duration:", e.duration, ";" )); trackData = string(abi.encodePacked(trackData, noteData)); } midiData = string(abi.encodePacked(midiData, trackData)); } return string(abi.encodePacked("data:audio/midi;base64,", Base64.encode(midiData))); } } library Base64 { bytes constant private TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; function encode(bytes memory data) internal pure returns (string memory) { uint256 len = data.length; if (len == 0) return ""; uint256 encodedLen = 4 * ((len + 2) / 3); bytes memory result = new bytes(encodedLen); uint256 j = 0; for (uint256 i = 0; i < len; i += 3) { uint256 octets = (uint256(data[i]) << 16) | (i + 1 < len ? uint256(data[i + 1]) << 8 : 0) | (i + 2 < len ? uint256(data[i + 2]) : 0); result[j++] = TABLE[uint8(octets >> 18)]; result[j++] = TABLE[uint8((octets >> 12) & 0x3f)]; result[j++] = TABLE[uint8((octets >> 6) & 0x3f)]; result[j++] = TABLE[uint8(octets & 0x3f)]; } if (len % 3 == 1) { result[encodedLen - 2] = '='; result[encodedLen - 1] = '='; } else if (len % 3 == 2) { result[encodedLen - 1] = '='; } return string(result); } }
0.7.1