Skip to content

Latest commit

 

History

98 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

New features introduced

  • Looping: Samples can have loop points set, and one of the three loop modes can be engaged: FORWARD, SUSTAIN and PINGPONG.
  • Effects: Audio effects are included, but not calibrated yet.
  • GUI: Simple menu to have access to the basic features: sample set selection, effects and volume.

!Attention! ESP Arduino cores v.3.1.2 and 3.1.3 have some bug that won't allow i2s driver to install when PSRAM is enabled, please, avoid using these versions!

ESP32 SD Sampler

ESP32 SD Sampler is a polyphonic music synthesizer, which can play PCM WAV samples directly from an SD (microSD) card connected to an ESP32-S3 or ESP32-P4. Simple: one directory = one sample set. Plain text "sampler.ini" manages how samples to be spread over the keyboard. The main difference, comparing to the projects available on the net, is that this sampler WON'T try to preload all the stuff into the RAM/PSRAM to play it on demand. So it's not limited in this way by the size of the memory chip and can take really huge (per-note true sampled multi-velocity several gigabytes) sample sets. It only requires that the card is freshly formatted FAT32 and has no or very few bad blocks (actually it requires that the WAV files are written with little or no fragmentation at all). On start it analyzes existing file allocation table (FAT) and forms it's own sample lookup table to be able to access data immediately, using SDMMC with a 4-bit wide bus.

Features

  • Easy to build and to customize Arduino code for ESP32S3/ESP32P4
  • Hardware would cost you about $15, including a microSD card
  • Audio output is 44100Hz 16bit stereo
  • Direct read-only access to the sample sets on an SD/microSD card: it's based on custom sdmmc routines and it's fast
  • Size of a sample set is only limited by the card size
  • Polyphony of 15-20 stereo voices depending on your MCU and card's specs
  • 16/24 bit WAV files supported
  • Melodic and percussive sample sets supported
  • ADSR envelope, per-note configurable
  • Built-in Reverb FX
  • MIDI control currently supports the following messages:
    • Note On
    • Note Off
    • Sustain (CC64)
    • Pitchbend
    • Attack time (CC73)
    • Release time (CC72)
    • Decay time (CC75)
    • Sustain level (CC76)
    • Reverb time (CC87)
    • Reverb level (CC88)
    • Reverb send (CC91)
  • Human readable SAMPLER.INI controls initial parameters of a sample set globally, per-range and per-note

YouTube Video

Video

How To Build the Thing

Is it possible to run on a simple ESP32 not S3, not P4?

Absolutely not possible

Polyphony

With a freshly formatted good microSD, all effects set to THRU, it's about 17 stereo voices on S3 and 25 on P4.

Velocity layers

There are currently 16 velocity layers (i.e. dynamic variants of each sampled note) which corresponds to the maximum count that I have found (https://freepats.zenvoid.org/Piano/acoustic-grand-piano.html).

SAMPLER.INI and examples

One should put the sampler.ini file to the same folder where the corresponding WAV files are stored.

Ini syntax is described here: https://github.com/copych/ESP32_S3_Sampler/blob/main/sampler_ini_syntax.md the doc is under development and will be improved.

Here is an example of a sampler.ini file for the Salamander Grand Piano WAV-set:

[sampleset]
title = Salamander Grand Piano
; type=percussive/melodic
type=melodic
; Are all the samples of equal loudness? If true then we apply amplification according to the midi note velocity.
normalized=true
; Overall Amplification
amplify = 1.2

; ADSR times in seconds
attackTime = 0.0
decayTime = 12.0
releaseTime = 0.1
; ADSR sustain level 0.0 - 1.0
sustainLevel = 0.0

# !!!!!!!!!!!!!!! "enveloped=bool" is no longer supported, as the ADSR is always applyed

# !!!!!!!!!!!!!!! [envelope] section is no longer supported, [sampleset] now holds global settings

[filename]
# Filename elements recognized:
; <NAME> - note name in sharp (#) or flat(b) notation, i.e. both Eb and D# are valid
; <OCTAVE> - octave number
; <MIDINOTE> - sometimes sample file name contains midi note number
; <NUMBER> - parsed, but not used for now: i.e. some numbers initially used for naming, sorting or whatever
; <VELO> velocity layer
; <INSTR> instruments names (mostly percussion) used in filenames, initially they are collected from this ini file
; elements without brackets will be treated as some constant string delimeters

; these elements are case insensitive, heading and trailing spaces are trimmed.
template=<NAME><OCTAVE>v<VELO>

; we must provide these variants along with the template. The order is important: from the most quiet
; to the most loud, comma separated
veloVariants = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

; in addition we can provide optional info on how velocity layers shall be spread over
; the whole range of 0-127, giving the upper limits of each range
veloLimits = 26,34,36,43,46,50,56,64,72,80,88,96,104,112,121,127

[range]
# notes without dampers
first = F#6
last = G8
noteoff = false

# [note] sections 
; instr=instrument_name(as in filename)
; noteoff=0/1 (0=ignore, 1=end note)
; speed=float_number(1.0 means unchanged (default), 1.2 means 20% faster which is higher pitch, 0.9 is 10% lower)

another sampler.ini example is for a drumkit MuldjordKit-SFZ-20201018, all the samples moved to a single folder

[sampleset]
title = Generic Drum Kit

; type=percussive/melodic
; different technics used while spreading samples over the clavier
; percussive type allows per-note fx-send level
type=percussive

; Are all the samples of equal loudness? If true then we apply amplification according to the midi note velocity.
normalized=true

; ADSR times in seconds
attackTime = 0.0
decayTime = 0.05
releaseTime = 0.2
; ADSR sustain level 0.0 - 1.0
sustainLevel = 1.0

# !!!!!!!!!!!!!!! "enveloped=bool" is no longer supported, as the ADSR is always applyed

# !!!!!!!!!!!!!!! [envelope] section is no longer supported, [sampleset] now holds global settings

[filename]
# Filename elements recognized:
; <NAME> - note name=name in sharp (#) or flat(b) notation, i.e. both Eb and D# are valid
; <OCTAVE> - octave number
; <MIDINOTE> - sometimes sample file name contains midi note number
; <NUMBER> - parsed, but not used for now: i.e. some numbers initially used for naming, sorting or whatever
; <VELO> velocity layer
; <INSTR> instruments names (mostly percussion) used in filenames, initially they are collected from this ini file
; only instrument names mentioned in this ini (in [note] or [range] sections) will be recognized 
; elements without brackets will be treated as some constant string delimeters
; these elements are case insensitive, heading and trailing spaces are trimmed.
; template should be specified first in this section
template=<VELO>-<INSTR>

; we must provide these variants. The order is important: from the most quiet to the most loud, comma separated
veloVariants = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16


[group]
notes = F#1,A#1,G#1

notes = G#2,A2

notes = C#2,D2


# [note] sections
; name = notename in sharp (#) or flat(b) notation, i.e. both Eb and D# are valid
; instr = instrument_name(as in filename)
; noteoff = 0/1 (0 is 'ignore', 1 is 'end note'), also yes/no, true/false are recognized
; speed = float_number (1.0 means unchanged (default), 1.2 means 20% faster which is higher pitch, 0.9 is 10% lower)
; only instrument names mentioned in this ini (in [note] or [range] sections) will be recognized 

[note]
name=b0
instr=kdrumL
noteoff=false

[note]
name=c1
instr=kdrumR
noteoff=no

[note]
name=C#1
instr=SnareRest
noteoff=0

[note]
name=D1
instr=Snare
noteoff=yes

[note]
name=D#1
; assuming we have "#-SnareRest (2).WAV" files in the drumkit folder after copying all the files into a single dir.
instr=SnareRest (2)
noteoff=true

[note]
name=E1
; assuming we have "#-Snare (2).WAV" files in the drumkit folder after copying all the files into a single dir.
instr=snare (2)
noteoff=0

[note]
name=F1
instr=Tom1
noteoff=0

[note]
name=G1
instr=Tom2
noteoff=0

[note]
name=A1
instr=Tom3
noteoff=0

[note]
name=B1
instr=Tom4
noteoff=0

[note]
name=C2
instr=Tom4
noteoff=0
speed=1.15

[note]
name=F#1
instr=HiHatClosed
noteoff=0

[note]
name=A#1
instr=HiHatOpen
noteoff=1

[note]
name=C#2
instr=CrashL
noteoff=0

[note]
name=D2
instr=CrashL
noteoff=true

[note]
name=E2
instr=China
noteoff=0

[note]
name=G#2
instr=CrashR
noteoff=0

[note]
name=A2
instr=CrashR
noteoff=yes

[note]
name=D#2
instr=RideL
noteoff=0

[note]
name=B2
instr=RideR
noteoff=0

[note]
name=F2
instr=RideLBell
noteoff=0

[note]
name=A#2
instr=RideRBell
noteoff=0

About

ESP32-S3 / ESP32-P4 based sampler handles gigabytes of PCM WAV files, up to 19 stereo voices polyphony, CD quality

Topics

Resources

Stars

75 stars

Watchers

5 watching

Forks

Releases

Contributors

Languages