How to stop or pause a sound when it is playing?

I am using Codea sound(soundBuffer(PCM data)) to play my music data.Is there anyway to stop the sound when it playing?
(I I have my music data divided into several small off, but it sounds bad?

my sound player works(it can pause and stop when playing a sound), but there are "Sonic Boom
" (the bad sound). I test two of my music tracks , one is perfect and another has “Sonic Boom”.
I think I should remix the bad one.

Hi @ccYen, can you post your code somewhere? Perhaps not here if you have PCM data… :slight_smile:

OK @Fred, I will add the player simple UI and then post the code. :slight_smile:

Hi @Fred, my code of the sound player and the PCM data of the test the link below

https://gist.github.com/3815951
https://gist.github.com/3815924

Sound format : smaple rate = 22050 16bits per sample mono

Sorry, forget to remove the test buttons from CcSound.lua , the last code

musicList = {
    "MUSIC_CallSome00",
    "MUSIC_DiDiDo00",
    "MUSIC_DiDiDo01",
    "MUSIC_Flute00",
    "MUSIC_G_Song00",
    "MUSIC_HardGt08",
    "MUSIC_LongDu03",
    "MUSIC_LoopAccGT00",
    "MUSIC_LoopAccGT01",
    "MUSIC_LoopAccGT05",
    "MUSIC_LoopSoundCrastal_Menu"
}
CcSound = class()

function CcSound:init()
    self.volume = .5
    watch("Volume")
    Volume = self.volume
    
    self.pickedSound = nil

    self.music = {
            MUSIC_CallSome00=MUSIC_CallSome00,
            MUSIC_DiDiDo00=MUSIC_DiDiDo00,
            MUSIC_DiDiDo01=MUSIC_DiDiDo01,
            MUSIC_Flute00=MUSIC_Flute00,
            MUSIC_G_Song00=MUSIC_CallSome00,
            MUSIC_HardGt08=MUSIC_HardGt08,
            MUSIC_LongDu03=MUSIC_LongDu03,
            MUSIC_LoopAccGT00=MUSIC_LoopAccGT00,
            MUSIC_LoopAccGT01=MUSIC_LoopAccGT01,
            MUSIC_LoopAccGT05=MUSIC_LoopAccGT05,
            MUSIC_LoopSoundCrastal_Menu=MUSIC_LoopSoundCrastal_Menu
            }

    self.lastTime = ElapsedTime

    local bw, bh = WIDTH*.1, HEIGHT*.1
    local posY, posX = HEIGHT*.2, (WIDTH - bw)*.5
    self.UI = { Play = CcButton( "Play", vec2(posX-bw*1.5, posY), bw, bh
                               , function() self:Play() end, nil
                               , "Planet Cute:Water Block", bh*.3 )
               , Pause = CcButton( "Pause", vec2(posX, posY), bw, bh
                                 , function() self:Pause() end, nil
                                 , "Planet Cute:Water Block", bh*.3)
               , Stop = CcButton( "Stop", vec2(posX+bw*1.5, posY), bw, bh
                                , function() self:Stop() end, nil
                                , "Planet Cute:Water Block", bh*.3 )
               , VolumeIn = CcButton( "Volume+", vec2(posX+bw, posY-bh*1.5), bw, bh
                                    , function(e) self:TuneVolume(e) end, {volume=.1}
                                    , "Planet Cute:Water Block", bh*.3 ) 
               , VolumeOut = CcButton( "Volume-", vec2(posX-bw, posY-bh*1.5), bw, bh
                                     , function(e) self:TuneVolume(e) end, {volume=-.1}
                                     , "Planet Cute:Water Block", bh*.3 )                  
               , pickedName = CcButton( "Picked Music : nil"
                                      , vec2(WIDTH*.5-bw*4, posY+bh), bw*8, bh*.5, nil, nil
                                      , "Cargo Bot:Register Slot", bh*.2 )          
                 }
    for i=1, #musicList do    --music list                      
        self.UI[musicList[i]] = CcButton( musicList[i], vec2(WIDTH*.5-bw*2, posY+bh*(2+i*.5-.5))
                                        , bw*4, bh*.5
                                        , function(e) self:PickMusic(e) end
                                        , {name = musicList[i]}
                                        , "Planet Cute:Selector", bh*.2 ) 
    end
end

function CcSound:Update()
    
    self.deltaTime = ElapsedTime - self.lastTime
    self.lastTime = ElapsedTime
    if self.pickedName then
        self:UpdateSound(self.music[self.pickedName])
    end
    
end

function CcSound:Draw()
    for k, btn in pairs(self.UI) do
        btn:Draw(color(255,255,255))
    end
end

function CcSound:UpdateTouch(touch) 
    for k, btn in pairs(self.UI) do
        btn:UpdateTouch(touch)
    end
end

function CcSound:UpdateSound(musicData)
    musicData.elapsedTime = musicData.elapsedTime + self.deltaTime
    local flag = math.ceil( musicData.elapsedTime % musicData.length/musicData.setRate)

    if musicData.flag ~= flag then
        --print("flag",flag) 
        musicData.flag = flag
        sound( soundbuffer(musicData[flag], musicData.format, musicData.sampleRate)
             , self.volume
                ) 
    end
end

------ UI events
function CcSound:PickMusic(e)
    self.pickedName = e.name
    self.UI.pickedName.caption = "Picked Music : "..e.name
                               .."\
Length : "..self.music[e.name].length.."s"
end

function CcSound:Play()
    if not self.pickedName then
        self.pickedName = self.pendingName
        self.pendingName = nil
    end
end

function CcSound:TuneVolume(e)
    self.volume = math.min(1, math.max(0, self.volume + e.volume))
    Volume = self.volume
end

function CcSound:Pause()
    self.pendingName = self.pickedName
    self.pickedName = nil    
end

function CcSound:Stop()
    self.UI.pickedName.caption = "Please pick a music wav "
    for k, musicData in pairs(self.music) do --reset poiter
        musicData.elapsedTime = 0
    end
    
    self.pickedName = nil
end

Hi @ccYen, sorry it took a while for me to listen to your code - I kept crashing safari because the data was too big. So I downloaded it from gisthub and copied it to the iPad with iExplorer.

This is a clever approach, especially the pause feature. You have broken up your samples in one-second chunks, and you are playing them in order, unless the pause button is used. I’m surprised it works so smoothly!

When you say ‘sonic boom’ did you mean a click when the sample stops suddenly? Which one?This only happened to me a few times, but looking at your data, there are lots of one-second samples that do not end smoothly on /127. /127 is the middle value that represents 0, the part of the sound wave that means the diaphragm of your loudspeaker is at rest. If you end or start a sample too far plus or minus from the middle, you get a harsh click sound.

If this is indeed the problem, you could try to smooth out the end of the sample by playing data that takes you from the last value gently to /127.

I haven’t made anything this good with soundbuffer, or solved the click problem myself before so I’m sorry I don’t have any code for you, just this idea.

Hi @Fred, thanks for the suggestion.Yes,there are lots of one-second samples that do not end smoothly on /127 at my data(MUSIC_LoopSoundCrastal_Menu.lua ).I get a harsh click sound.

I will try to smooth out the end of the data and tell you the result. :slight_smile: