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

Truly random (or sequential) music player

Started by JonathanVB, 05 July 2012 - 05:18 PM
JonathanVB #1
Posted 05 July 2012 - 07:18 PM
Having looked (and not found) for something to play all the minecraft tracks indefiniately (rather than just one or two tracks) and having found nothing, I decided to write my own.

This program, instead of bringing the disks to the computer, brings the computer to the disks.

How to set up:
[attachment=291:UI.jpg]
[attachment=292:Setup.jpg]
  1. Make a rectangle of disk drives (the default is 3 long, 4 high which can be changed in the code). If many of the last ones are empty, they can be excluded to reduce the number of misses (which don't take much time anyway). Further information is in the comments.
  2. Place a turtle (with this program) in front of one of the disk drives (it will automatically move to position 0.
  3. Tweak the settings in the interface to suit yourself.
Some snippets of code were adapted from Negeator's "Minecraft Music Player with BuildCraft", who almost solved the problem, though in a completely different way (and would be more elegant if it worked perfectly).

[attachment=290:turtlemusic.zip]


-- Minecraft Random Disk Player --
-- By: Jonathan
-- Settings, feel free to modify
local timeout = 120	 -- The time between tracks
						   -- Can be set in the program
local width = 3		 -- The width of the rectangle of disk drives
local height = 4		-- The height of the rectangle of disk drives
local filledDrives = 12 -- The number of drives in the rectangle to check
						   -- Drives count left-to-right from the bottom
						   -- Drives after this number will be ignored
local random = true	 -- Whether the system shoud start off shuffleing
-- Initial setup, modify if you know what you're doing -- edit need an extra ' to prevent comenting on site
local side = "left"
local location = 0
-- Variables, Do not modify
local state = "play"
local quit = false
local startTime = 0
-- Check for a disk
function checkDisk()
if disk.isPresent(side) then
  return true
else
  return false
end
end
-- Clears the screen
function clear()
term.clear()
term.setCursorPos(1,1)
end
-- Prints the gui
function show()
clear()
if (state == "change") then
  print("Changing Disk")
else
  if (state == "stop") then
   print("Currently stopped")
   print()
  else
   print("Currently playing, ")
   print("Time Remaining: " .. math.floor(timeout - (os.time()*60 - startTime)) .. " seconds.")
  end
  print("Time between tracks: " .. timeout)
  if (checkDisk()) then
   print("Disk Inserted: " .. disk.getAudioTitle(side))
  else
   print("No audio disk inserted")
  end
  if (random) then
   print("Random order")
  else
   print("Sequential order")
  end
  print("---------------------")
  if (state == "stop") then
   print("1: Play")
  else
   print("1: Stop")
  end
  if (random) then
   print("2: Sequential Order")
  else
   print("2: Random Order")
  end
  print("3: Change disk")
  print("4: Change timeout")
  print("0: Exit")
end
end
-- Change Disk
function change()
disk.stopAudio(side)
local oldstate = state
state = "change"
show()
if (random) then
  move(math.random(0,filledDrives-1))
else
  move((location+1)%filledDrives)
end
while (checkDisk() == false) do
  if (random) then
   move(math.random(0,filledDrives-1))
  else
   move((location+1)%filledDrives)
  end
end
state = oldstate
if (state == "play") then
  startTime = os.time()*60
  disk.playAudio(side)
end
end
-- Move to disk
function move(tarDisk)
local x, y, xtar, ytar = location%width, math.floor((location+0.01)/width), tarDisk%width, math.floor((tarDisk+0.01)/width)
while (x < xtar) do
  turtle.forward()
  x = x+1
end
while (y > ytar) do
  turtle.down()
  y = y-1
end
while (x > xtar) do
  turtle.back()
  x = x-1
end
while (y < ytar) do
  turtle.up()
  y = y+1
end
location = tarDisk
end
-- Change Timeout, messy implementation
function changeTimeout()
if (timeout == 10) then
  timeout = 30
elseif (timeout == 30) then
  timeout = 60
elseif (timeout == 60) then
  timeout = 90
elseif (timeout == 90) then
  timeout = 120
elseif (timeout == 120) then
  timeout = 150
elseif (timeout == 150) then
  timeout = 180
elseif (timeout == 180) then
  timeout = 240
elseif (timeout == 240) then
  timeout = 300
elseif (timeout == 300) then
  timeout = 420
elseif (timeout == 420) then
  timeout = 540
elseif (timeout == 540) then
  timeout = 900
else
  timeout = 10
end
end
-- Logical step
function step()
if (state == "play") then
  local curTime = os.time()*60
  if (startTime > curTime) then --day clocked over
   startTime = startTime - 24*60
  end
  if (curTime - startTime >= timeout) then
   change()
  end
end
end
-- Main function
function main()
while (quit == false) do
  step()
  show()
  if (state ~= "change") then
   os.startTimer(1)
   local event, p1, p2 = os.pullEvent()
   if (event == "key") then
	if (p1 == 2) then
	 if (state == "stop") then
	  state = "play"
	  startTime = os.time()*60
	  disk.playAudio(side)
	 else
	  state = "stop"
	  disk.stopAudio(side)
	 end
	end
	if (p1 == 3) then
	 if (random) then
	  random = false
	 else
	  random = true
	 end
	end
	if (p1 == 4) then
	 change()
	end
	if (p1 == 5) then
	 changeTimeout()
	end
	if (p1 == 11) then
	 quit = true
	end
   end
  end
end
disk.stopAudio(side)
move(0)
end
-- Moves the turtle into position (or resets it)
function moveIn()
clear()
print("Moving into position")
while(disk.isPresent("right") == false) do
  turtle.turnRight()
end
while (disk.isPresent("right") and turtle.detect() == false) do
  turtle.forward()
end
turtle.turnRight()
turtle.turnRight()
if (disk.isPresent(side) == false) then
  turtle.forward()
end
while (disk.isPresent(side) and turtle.detectDown() == false) do
  turtle.down()
end
if (disk.isPresent(side) == false) then
  turtle.up()
end
end
-- Start Program
moveIn()
main()
kazagistar #2
Posted 06 July 2012 - 02:43 AM
This is both brilliant and convenient.You could set this up under a floor or in a wall pretty simply, and control it via a short range wireless signal.
JonathanVB #3
Posted 06 July 2012 - 03:32 PM
Not a bad idea, by changing a few of the commands in the move[to disk n] function you can set this up horizantal instead of vertical. Though you would wave to do more turning (i.e. some) when switching disks.

The simplest change would be to change each the turtle.down() to a turtle.turnRight(), a turtle.forward() loop, and a turtle.turnLeft(), and similarly changing the turtle.up() loop. You would also have to do the same for the moveIn[to initial position] function.

Edit: And your side would now be "down" (including in the moveIn function checks).
Negeator #4
Posted 28 July 2012 - 08:05 PM
Wow, I never would have thought of bringing the computer to the disk drives. This solves my problem where only a couple songs would end up being played indefinitely.

Good work!
luingar #5
Posted 29 July 2012 - 03:59 AM
When i did this my turtle just spun around endlessly turning right…
ArchAngel075 #6
Posted 18 August 2012 - 06:24 PM
Haha, is this Jonathan from CTWUG?
If so i knew i recognized that wierd looking wall!

Funny finding that here.
Andale #7
Posted 28 January 2013 - 03:49 AM
When i did this my turtle just spun around endlessly turning right…
They'll spin but not move if out of fuel

I know this topic's old but someone else might find it still