Skip to content

Commit

Permalink
version 1.3!
Browse files Browse the repository at this point in the history
check out release notes for details :)
  • Loading branch information
Nanobot567 committed Dec 10, 2023
1 parent 6a22e59 commit 40ee543
Show file tree
Hide file tree
Showing 31 changed files with 871 additions and 184 deletions.
43 changes: 40 additions & 3 deletions MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,28 @@ To edit the pitch of the note, cycle through the crank mode menu until you reach

You can start or stop the sequence by pressing A.

### recording

If you would like to input notes in real time, there is a `record` function in CS-16. You can toggle recording via the `record` menu option while on the `pattern` screen.

While in record mode, the `A`, `B`, `up`, `down`, `left`, and `right` buttons are mapped to tracks in the song. When pressed, a note is placed at that step in the corresponding track. If quantization is enabled (not 1), then each note you place will be quantized to the nearest multiple of the quantization value.

![](assets/liverecord.gif)

### track

![](assets/track.png)
![](assets/track-2.png)

On the `track` screen, you can edit the instruments of your tracks, mute tracks by pressing `right` in the track list, or mute/unmute all tracks by pressing `left`.
On the `track` screen, you can edit the instruments of your tracks, mute tracks by pressing `right` in the track list, or mute/unmute all tracks by pressing `left`.

#### copying and pasting track data

In the system menu, there are two options, `copy` and `cpy mode`. To copy a track, move to the track you would like to copy, then enter the system menu and select `copy`. Move to the track you'd like to copy to, then press `paste`. The `cpy mode` option controls what is pasted to the track, which can be either everything (`all`), just the instrument (`inst`), or just the pattern (`ptn`).

![](assets/copypaste.gif)

#### instrument editor

To edit an instrument, select the track you want in the list. It will be marked with the number and the instrument type. Instrument types can be any of the following:

Expand All @@ -65,6 +81,8 @@ By turning the `WAV` knob, you can select the waveform that your track uses, but

The `SHFT` module transposes every note in the current track. Its range is -24 to 24 semitones.

#### sampling

When you go to select a sample, you will arrive at a list, usually with four options within it. These options are as follows:

1. `record sample` - here you can record a sample using the microphone. (ui pictured below)
Expand All @@ -81,9 +99,13 @@ Within the file picker, you can enter folders or select a file using `A`, and ex

If you have already selected a sample, however, there will be an extra option in the list: `edit sample`. In the `edit sample` screen, you can trim your samples. Pressing `left` or `right` changes the selected side, and pressing `up` or `down` changes the interval at which you trim the sample using the crank.

If you are editing a sample that was recorded with the Playdate's microphone, you will see a waveform above the start and end frame locations.

> note: the location of the playtime marker may not be accurate.
![](assets/sampleedit.png)

> note: double and triple check your sample before you save it, when you trim it you cannot revert to the original sound.
> note: double and triple check your sample before you save it! when you trim it you cannot revert to the original sound.
### song

Expand All @@ -105,7 +127,11 @@ To add your own samples, follow these steps:
- Using FFMPEG: `ffmpeg -i input_file -c:a pcm_s16le output_file.wav`
- to reduce file size, you can also add these flags: `-ac 1` (converts to mono) `-b:a 128k` (makes bitrate 128kbps [reduces audio quality slightly, you can go lower if you want])
- Using Audacity: File -> Export as WAV... -> Signed 16 bit PCM
2. compile them using `pdc` from the [Playdate SDK](https://play.date/dev/) into a playdate PDX, which will convert the audio files into PDA files (i have provided a pre-made folder for this in `/assets/`. Simply place your .WAVs into that folder, run `pdc convert`, and grab your .PDAs from convert.pdx.)

2. Now you can either...
- use [this converter](https://ejb.github.io/wav-pda-converter/) to convert the .wav to .pda
- compile them using `pdc` from the [Playdate SDK](https://play.date/dev/) into a playdate PDX, which will convert the audio files into PDA files (i have provided a pre-made folder for this in `/assets/`. Simply place your .WAVs into that folder, run `pdc convert`, and grab your .PDAs from convert.pdx.)

3. put your playdate into [data disk mode](https://help.play.date/games/backups/)
4. drag the PDAs into the `Data/user.*****.com.nano.cs16/samples/` folder on your playdate (feel free to use folders to organize your samples, CS-16 supports them) and eject it when finished.

Expand All @@ -116,3 +142,14 @@ To manage your songs:
1. put your playdate into [data disk mode](https://help.play.date/games/backups/)
2. navigate to `Data/user.*****.com.nano.cs16/songs/`
3. add, copy, delete, or rename your songs, then eject your playdate when you are done.

### ways to improve performance

All of these are things you can do to improve CS-16's performance and reduce frame drops.

- In `settings/ui/`...
- Disable `visualizer`.
- Disable `show note names`.
- Disable `animate scrn move`.
- Enable `50fps`.
- Use lower quality samples (ex. lower bitrate)
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@ a synthesizer for playdate

## screenshots

![](assets/pattern.png)

*pattern view*

![](assets/track.png)
![pattern view](assets/pattern.png "patte![track view](assets/track.png "track view")s/track.png "pattern view")

*track view*

![](assets/track-2.png)
![track edit view](assets/track-2.png "track edit view")

*track edit view*

![](assets/song.png)
![song view](assets/song.png "song view")

*song view*

Expand Down
Binary file added assets/copypaste.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/liverecord.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example-songs/init/song.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[[["sin","squ","saw","tri","nse","poP","poD","poV","sin","squ","saw","tri","nse","poP","poD","poV"],[[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]],[[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046],[0,0,0.30000001192093,0.40000000596046]],[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false],[[0,0],[0.5,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.5,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],[16,32],["nanobot567",{"year":2023,"millisecond":205,"second":31,"minute":23,"hour":22,"day":22,"weekday":3,"month":11}]]
Binary file added samplepacks/drummy/Clap.pda
Binary file not shown.
Binary file added samplepacks/drummy/Clav.pda
Binary file not shown.
Binary file added samplepacks/drummy/CongaHi.pda
Binary file not shown.
Binary file added samplepacks/drummy/CongaLow.pda
Binary file not shown.
Binary file added samplepacks/drummy/CongaMid.pda
Binary file not shown.
Binary file added samplepacks/drummy/Cowbell.pda
Binary file not shown.
Binary file added samplepacks/drummy/HHClosed.pda
Binary file not shown.
Binary file added samplepacks/drummy/HHOpen.pda
Binary file not shown.
Binary file added samplepacks/drummy/KickDrum.pda
Binary file not shown.
Binary file added samplepacks/drummy/Maraca.pda
Binary file not shown.
Binary file added samplepacks/drummy/Rimshot.pda
Binary file not shown.
Binary file added samplepacks/drummy/SnareDrum.pda
Binary file not shown.
Binary file added samplepacks/drummy/TomHi.pda
Binary file not shown.
Binary file added samplepacks/drummy/TomLow.pda
Binary file not shown.
Binary file added samplepacks/drummy/TomMid.pda
Binary file not shown.
151 changes: 97 additions & 54 deletions src/buttons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,92 @@ pattern = {}
instrument = {}
song = {}

pattern.recording = false

instrument.selectedInst = 0
instrument.allMuted = false
instrument.samplePreviewElems = {playdate.sound.track.new(), playdate.sound.sequence.new()}
instrument.sample = playdate.sound.sample.new(5)

instrument.copymode = "all"
instrument.copytrack = 0

instrument.movetrack = 0

function pattern.AButtonDown()
if seq:isPlaying() then
seq:stop()
seq:goToStep(1)
sinetimer:pause()
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["aRecTrack"])
else
seq:play()
sinetimer:reset()
sinetimer:start()
if seq:isPlaying() then
seq:stop()
seq:goToStep(1)
sinetimer:pause()
else
seq:play()
sinetimer:reset()
sinetimer:start()
end
end
end

function pattern.BButtonDown()
crankMode = table.cycle(crankModes,crankMode)
local append = ""
if settings["num/max"] == true then
append = " - "..table.find(crankModes,crankMode).."/"..#crankModes
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["bRecTrack"])
else
crankMode = table.cycle(crankModes,crankMode)
local append = ""
if settings["num/max"] == true then
append = " - "..table.find(crankModes,crankMode).."/"..#crankModes
end
displayInfo(crankMode..append)
end
displayInfo(crankMode..append)
end

function pattern.upButtonDown()
if cursor[2] ~= 0 then
cursor[2] -= 1
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["upRecTrack"])
else
if cursor[2] ~= 0 then
cursor[2] -= 1
end
end
end

function pattern.downButtonDown()
if (cursor[2]+1)*16 < stepCount then
cursor[2] += 1
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["downRecTrack"])
else
if (cursor[2]+1)*16 < stepCount then
cursor[2] += 1
end
end
end

function pattern.rightButtonDown()
if cursor[1] ~= 15 then
cursor[1] += 1
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["rightRecTrack"])
else
if cursor[1] ~= 15 then
cursor[1] += 1
end
end
end

function pattern.leftButtonDown()
if cursor[1] ~= 0 then
cursor[1] -= 1
if pattern.recording == true then
toggleNote(math.quantize(currentSeqStep, settings["recordQuantization"]), settings["leftRecTrack"])
else
if cursor[1] ~= 0 then
cursor[1] -= 1
end
end
end

function instrument.AButtonDown() -- sorry, "track" screen in manual is referred to as "instrument" in source code. silly me :P
local selRow = listview:getSelectedRow()
if listviewContents[1] ~= "Ā" then
if listviewContents[1] ~= "*Ā*" then
instrument.selectedInst = instrumentTable[selRow]
listview:set({"Ā"})
listview:set({"*Ā*"})
knobs[1]:setClicks(table.find(waveNames,trackNames[selRow])-1)

local adsr = instrumentADSRtable[selRow]
Expand All @@ -72,17 +103,7 @@ function instrument.AButtonDown() -- sorry, "track" screen in manual is referred
knobs[8]:setClicks(instrumentTransposeTable[selRow])
knobs[9]:setClicks(instrument.selectedInst:getVolume()*10)
elseif currentElem == 1 then
local finalListViewContents = {}

for i = 1, #trackNames, 1 do
local append = ""
if tracksMutedTable[i] == true then
append = " ć"
end
table.insert(finalListViewContents, tostring(i).." - "..trackNames[i]..append)
end

listview:set(finalListViewContents)
instrument.updateList()
elseif currentElem == 7 then
instrumentLegatoTable[selRow] = not instrumentLegatoTable[selRow]
instrument.selectedInst:setLegato(instrumentLegatoTable[selRow])
Expand All @@ -91,7 +112,15 @@ function instrument.AButtonDown() -- sorry, "track" screen in manual is referred
if trackNames[listview:getSelectedRow()] == "smp" then
mode = "newsmp"
end
filePicker.open(function(file)
filePicker.open(function(data)
local file,image = nil, nil
if type(data) == "table" then
file = data[1]
image = data[2]
else
file = data
end

local newSample,err
if type(file) == "string" then
newSample,err = snd.sample.new(file)
Expand All @@ -113,6 +142,11 @@ function instrument.AButtonDown() -- sorry, "track" screen in manual is referred
if settings["savewavs"] == true then
newSample:save("temp/"..listview:getSelectedRow()..".wav")
end

if image ~= nil then
pd.datastore.writeImage(image, "temp/"..listview:getSelectedRow()..".pdi")
end

displayInfo("loaded "..filename)
elseif file == "none" then
print("ERROR INTENTIONAL! No sample selected.")
Expand Down Expand Up @@ -155,7 +189,7 @@ end

function instrument.BButtonDown()
local cur,max = table.find(crankModes,crankMode),#crankModes
if listviewContents[1] == "Ā" then
if listviewContents[1] == "*Ā*" then
crankMode = table.cycle(crankModes,crankMode)
else
crankMode = "screen"
Expand All @@ -170,7 +204,7 @@ function instrument.BButtonDown()
end

function instrument.upButtonDown()
if listviewContents[1] ~= "Ā" then
if listviewContents[1] ~= "*Ā*" then
listview:selectPreviousRow()
else
if currentElem <= 6 then
Expand All @@ -186,7 +220,7 @@ function instrument.upButtonDown()
end

function instrument.downButtonDown()
if listviewContents[1] ~= "Ā" then
if listviewContents[1] ~= "*Ā*" then
listview:selectNextRow()
else
if currentElem == 1 then
Expand All @@ -202,47 +236,56 @@ end

function instrument.rightButtonDown()
local selRow = listview:getSelectedRow()
if currentElem ~= #knobs+#buttons and listviewContents[1] == "Ā" then
if currentElem ~= #knobs+#buttons and listviewContents[1] == "*Ā*" then
currentElem += 1
elseif listviewContents[1] ~= "Ā" then
elseif listviewContents[1] ~= "*Ā*" then
tracksMutedTable[selRow] = not tracksMutedTable[selRow]
tracks[selRow]:setMuted(tracksMutedTable[selRow])
if tracksMutedTable[selRow] == true then
instrumentTable[selRow]:stop()
end

local append = ""
if tracksMutedTable[selRow] == true then
append = " ć"
end

listviewContents[selRow] = tostring(selRow).." - "..trackNames[selRow]..append
instrument.updateList()
end
end

function instrument.leftButtonDown()
local selRow = listview:getSelectedRow()
if currentElem ~= 1 and listviewContents[1] == "Ā"then
if currentElem ~= 1 and listviewContents[1] == "*Ā*" then
currentElem -= 1
elseif listviewContents[1] ~= "Ā" then
elseif listviewContents[1] ~= "*Ā*" then
instrument.allMuted = not instrument.allMuted
local newVal = instrument.allMuted

for i=1, #tracks do
tracksMutedTable[i] = newVal
tracks[i]:setMuted(newVal)
if newVal == true then
instrumentTable[i]:stop()
end
end

instrument.updateList()
end
end

function instrument.updateList()
local finalListViewContents = {}

local append = ""
for i = 1, #trackNames, 1 do
local append = ""
if tracksMutedTable[i] == true then
append = " *ć*"
end

if i == instrument.copytrack then
if tracksMutedTable[i] == true then
append = " ć"
append = " *ćč*"
else
append = append.." *č*"
end

listviewContents[i] = tostring(i).." - "..trackNames[i]..append
end
table.insert(finalListViewContents, tostring(i).." - "..trackNames[i]..append)
end

listview:set(finalListViewContents)
end


Expand Down
2 changes: 2 additions & 0 deletions src/consts.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ crankModesList = {
}

fnt = gfx.font.new("fnt/modified-tron")
gfx.setFont(gfx.getSystemFont(), gfx.font.kVariantItalic)
gfx.setFont(fnt, gfx.font.kVariantBold)
gfx.setFont(fnt)

fnt8x8 = gfx.font.new("fnt/modified-tron-8x8")
Expand Down
Loading

0 comments on commit 40ee543

Please sign in to comment.