This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
CrazedProgrammer's profile picture

Music Composer and Audio API

Started by CrazedProgrammer, 02 April 2015 - 11:50 AM
CrazedProgrammer #1
Posted 02 April 2015 - 01:50 PM
You can make music with this program and API in ComputerCraft!
You can also play sounds and play multiple songs at the same time with the API.
All you need is a command computer or an advanced computer with a connected command block.

Download Composer + Audio API (a sample song is included):
pastebin get rrfPrUxT extract
You'll need to run this file to extract everything.
Once you've extracted everything, you can simply type composer and press enter to launch the composer.
You can also download the Audio API separately:
pastebin get tw2JcyaT audio

Screenshot:


What everything means:

1 - File name (used for saving and loading music)
2 - New song
3 - Load song from path
4 - Save song to path
5 - Play song
6 - Pause song
7 - Go to start
8 - Main volume
9 - Current channel
10 - Add channel
11 - Delete current channel
12 - Channel volume
13 - Channel output
14 - Channel sound - List of sounds that you can use
15 - Move view left
16 - Channel
17 - Move view right
18 - Time (you can scroll to move the view up or down)
19 - Note pitch
20 - Note volume

Key bindings:


This program plays a bass sound with the pitch E4:

-- Loads the Audio API
os.loadAPI("audio")
-- Sets output 1 to the commands API (exclusive to command computers)
audio.setOutput()
-- Plays note.bass with the pitch E4
audio.playSound("note.bass", audio.pitch.e4)
-- Unloads the Audio API
os.unloadAPI("audio")

This program plays the music in the file music.acp until it ends:

-- Load the Audio API
os.loadAPI("audio")
-- Sets output 1 to the commands API (exclusive to command computers)
audio.setOutput()
-- Loads the music into the variable music
local music = audio.loadMusic("music.acp")
-- Adds the music
audio.addMusic(music)
-- Sets music to be played
music.playing = true
-- While the music is playing (the music will automatically be stopped when it ends)
while music.playing do
  -- Plays the music
  audio.update()
  -- Sleeps for 1/20 of a second
  os.sleep(0.05)
end
-- Unloads the Audio API
os.unloadAPI("audio")

All functions are documented here:
audio.setOutput
audio.setVolume
audio.getVolume
audio.playSound
audio.addMusic
audio.removeMusic
audio.loadMusic
audio.update
Edited on 12 June 2015 - 01:13 PM
kornichen #2
Posted 02 April 2015 - 02:15 PM
I have to try it out later but I would like to thank you in advance for that. I've been waiting for that so long. Can't wait to see what the community does with that.
Edited on 02 April 2015 - 12:16 PM
CrazedProgrammer #3
Posted 02 April 2015 - 02:19 PM
I have to try it out later but I would like to thank you in advance for that. I've been waiting for that so long. Can't wait to see what the community does with that.
Thanks!
I'd love to hear your opinion on this program.
I think my tutorial is a little bit vague, if you have any tips for it that would be great.
Possseidon #4
Posted 02 April 2015 - 02:25 PM
haha… once did something kinda similar with openperipherals using a noteblock as peripheral xD

laughed a bit after seeing how you wrote constants for every note, since there is a pretty easy formular behind it :P/>

If you want to use it:

soundConst = math.log(2) / 12

function noteToPitch(note)
  return 0.5 * math.exp(soundConst * note)
end

function pitchToNote(pitch)
  return (math.log(2 * pitch)) / soundConst
end

It calculates:
note 0 - 24 <> pitch 0.5 - 2.0

This also gives you accurate values than your constants which only have like up to 4 floating points even if that is enough :D/>
CrazedProgrammer #5
Posted 02 April 2015 - 02:29 PM
haha… once did something kinda similar with openperipherals using a noteblock as peripheral xD

laughed a bit after seeing how you wrote constants for every note, since there is a pretty easy formular behind it :P/>

If you want to use it:

soundConst = math.log(2) / 12

function noteToPitch(note)
  return 0.5 * math.exp(soundConst * note)
end

function pitchToNote(pitch)
  return (math.log(2 * pitch)) / soundConst
end

It calculates:
note 0 - 24 <> pitch 0.5 - 2.0

This also gives you accurate values than your constants which only have like up to 4 floating points even if that is enough :D/>
Wow, I didn't know that (but I saw some kind of pattern when writing it :P/>).
I will make a quick update with more accurate values.
Possseidon #6
Posted 02 April 2015 - 02:32 PM
Found something you should probably change in your API… It's nothing big :P/>

In your audio-API you save all "private" values with a "_" in front of them. The problem is, that you can still access and change those without using the functions.
All you have to do to fix that is adding a "local" in front of the variable you want to have "private" and it won't be accesable from outside the API and only get changed via the function.

-snip-
Wow, I didn't know that (but I saw some kind of pattern when writing it :P/>).
I will make a quick update with more accurate values.
You saw a pattern? Well thats weird, cause it is an e^x-Function… If you can see patterns in that, then you are good xD
Possseidon #7
Posted 02 April 2015 - 02:55 PM
Looked a bit more through my old file and found a code snippet, that you might want to use for initing the your note constants:

-- init note consts
n = {"C","Cis","D","Dis","E","F","Fis","G","Gis","A","Ais","H"}
note = {}
pitch = {}
local name
for i=0,24 do
  local name = n[math.fmod(i,12)+1]..math.ceil((i+1)/12)
  note[name] = i
  pitch[name] = noteToPitch(i)
end
With this exact code you get note.C1 to note.C3 and pitch.C1 to pitch.C3 which are equal to 0 to 24 and 0.5 to 2.0
This code isn't really accurate to real music, since it defines pitch 0.5 to C1 but I think you can still use it if you shift arounf the notes and use your brain a bit ^^
Edited on 03 April 2015 - 11:08 AM
CrazedProgrammer #8
Posted 02 April 2015 - 02:59 PM
Found something you should probably change in your API… It's nothing big :P/>

In your audio-API you save all "private" values with a "_" in front of them. The problem is, that you can still access and change those without using the functions.
All you have to do to fix that is adding a "local" in front of the variable you want to have "private" and it won't be accesable from outside the API and only get changed via the function.

-snip-
Wow, I didn't know that (but I saw some kind of pattern when writing it :P/>).
I will make a quick update with more accurate values.
You saw a pattern? Well thats weird, cause it is an e^x-Function… If you can see patterns in that, then you are good xD
Thanks for your feedback.
I have made the pitches more precise and the variables with a _ in front of them private.
You can download the new version with the same command as before.
The usage is also exactly the same.
Possseidon #9
Posted 03 April 2015 - 01:01 PM
I have made the pitches more precise and the variables with a _ in front of them private.
Well… I thought more of calculating the constants when the API gets loaded… xD
Even gave you a little piece of code in a post above that uses the function to generate it :P/>
CrazedProgrammer #10
Posted 03 April 2015 - 07:27 PM
I have made the pitches more precise and the variables with a _ in front of them private.
Well… I thought more of calculating the constants when the API gets loaded… xD
Even gave you a little piece of code in a post above that uses the function to generate it :P/>
Well I didn't think of that :P/> (I am really lazy sometimes)
But I used your code to generate the pitches when you're playing music, so I don't need to make a separate table.
Anyway, thanks for the code! I really appreciate it.
Lur_ #11
Posted 17 April 2015 - 08:06 PM
Was this inspired by FamiTracker? I love it!
CrazedProgrammer #12
Posted 17 April 2015 - 09:16 PM
Was this inspired by FamiTracker? I love it!
Yes it was :D/>
I wrote the sample song (Yoshi's Island: Flower Garden) from this video.
Edited on 17 April 2015 - 07:16 PM
Eyeballcode #13
Posted 27 May 2015 - 07:15 PM
If you use command blocks, then this will be useless in survival. Mabye try noteblocks?
ItsRodrick #14
Posted 27 May 2015 - 11:35 PM
This is supposed to be used with Command Blocks, that's why it's in the Command Programs section.

And there are some music programs that work with noteblocks (or Iron Noteblocks, peripheral), such as Left4Cake's one.
Agent Silence #15
Posted 28 May 2015 - 07:51 PM
I found a better sound list.