Hi! I'm making an animation program, and I want to add sound support with the microphone, but I'm not sure how to save samples recorded by the microphone. Seeing pd.datastore, the only way to save it would be to add it to a table and save that, but I'm not sure if that'll work out. I would greatly appreciate any help!
Looking at the docs, microphone input gives you a sample object. Use playdate.sound.sample:save(filename) to save the file. Use datastore only for things like settings IMO.
by any chance do you know where it saves it, because it's confirmed saving, but I swear I cannot find the file. Is it in data or in the files
Ha, yeah. It's in your playdate SDK location. In Disk/Data/(your game id)/
Thanks! I looked there and I couldn't find it, I guess it was a error on my part
Yeah, so I ran it on device and it didn't show up there either.
function recording_done_callback()
recording_recording = false
recording_buffer:save(animation[1])
recording_buffer:play()
end
this is my code. It works, as the recording buffer is played. Animation[1] contains a string. I really don't know why it doesn't work.
I was doing a similar thing in a game I've been working on recently, and dealing with the sample files can be a little confusing.
Here's a simplified example of what ended up working for me:
recordPlayer
handles the listening, and playRecording
creates a sample player to play the result, then performs a callback action when the sample is finished playing.
function self:init( scene )
self.buffer = playdate.sound.sample.new( 2, playdate.sound.kFormat16bitMono )
self.listening = false
self.playerSamplePath = 'playerSample'
end
function self:recordPlayer()
Sound.micinput.startListening()
Sound.micinput.recordToSample( self.buffer, function ( sample )
Sound.micinput.stopListening()
self.listening = false
sample:save( self.playerSamplePath )
end)
end
function self:playRecording()
if type( self.playerSamplePath ~= 'string' then
self:progressDialogue()
return
end
self.buffer:load( self.playerSamplePath )
if self.buffer == nil then
return
end
local player = Sound.sampleplayer.new( self.buffer )
player:play()
player:setFinishCallback( function()
self:progressDialogue()
end)
end
Hope this is helpful!
Based on your code it seemed like I already did everything well, I'm not sure why it doesn't work.I really tried my best with it, but it just refuses to save. I've given up trying to debug it myself, here is the code for the recording scene:
function recording_init()
menu:removeAllMenuItems()
recording_recording = false
local _menu_button, _error_1 = menu:addMenuItem("menu", function()
menu_init()
scene = "menu"
end)
end
function recording_update()
image_rec_booth:draw(0, 0)
if recording_recording == false then
if pd.buttonJustPressed(pd.kButtonA) then
recording_recording = true
recording_buffer = playdate.sound.sample.new(#animation[2]/playing_fps, playdate.sound.kFormat16bitMono)
pd.sound.micinput.startListening()
pd.sound.micinput.recordToSample(recording_buffer, recording_done_callback)
playing_frame = 1
end
recording_buffer:save(animation[1])
end
if recording_recording == true then
if playing_frame == 1 then
pd.display.setRefreshRate(playing_fps)
animation[2][playing_frame]:draw(0, 0)
playing_frame += 1
elseif playing_frame == #animation[2] then
animation[2][playing_frame]:draw(0, 0)
pd.display.setRefreshRate(30)
else
animation[2][playing_frame]:draw(0, 0)
playing_frame += 1
end
image_recording:draw(298, 8)
if pd.buttonJustPressed(pd.kButtonB) then
pd.sound.micinput.stopRecording()
playing_frame = #animation[2]
end
end
end
function recording_done_callback()
pd.sound.micinput.stopListening()
recording_recording = false
recording_buffer:save(animation[1])
recording_buffer:play()
end
@sheep42 a quick question, where did it save the files for you? It would truly help me out.
Wait a second.... I just saved it as a wav to see if that worked, and it totally did! I'm not sure why though. I'll try using this, maybe it'll work.
For me the file is saved at Data/com.my.namespace/playerSample on the Playdate disk.
I'm not sure you'll be able to play the sound if you save it as a wav, but definitely give it a go.
Not able to test and debug your code at the moment, but just looking at it, I'd say:
-
Actually, just remembered that new takes the buffer time in seconds as the first arg, not the path, so don't mind this one.
Make sure that the path on the linerecording_buffer = playdate.sound.sample.new(#animation[2]/playing_fps, playdate.sound.kFormat16bitMono)
is a string:recording_buffer = playdate.sound.sample.new( tostring( #animation[2] ) .. '/playing_fps', playdate.sound.kFormat16bitMono)
-
Maybe don't do the buffer save inside of your first if branch, just save it in
recording_done_callback
.
Thanks for the tips! I do already save the sound in the recording done callback, and the timing is correct as well, regarding the fact that the wav file it created was exactly what I recorded. I did find something in the middle of writing this though, and it seemed to fix my problem! The thing is, there's already a folder with the exact same name as the sound because it stores the animation, so what I did is I just saved the sample in the folder under the name sound and it completely worked. I also managed to load it. I'll close it with this message, and I'll try to confirm it's a bug, then write a bug report. Thanks guys!