1

I am using Picroft on raspberry pi 3. In picroft, every mp3 files run with mpg123. I am creating my own device using this OS. when I say it to sing a song it starts singing by playing mp3 files and when I interrupt it with its wakeup word. It stops playing the song and after the command has been worked off it again starts to play.

But it is a sudden stop and plays I want to do slowly decrease in volume then pause and after the interruption is done start playing with slowly increasing volume.

I am not able to find any command or any way to control like this. I can't open multiple terminals in this so I want it to be done via code.

I have tried an alternative using alsaaudio to control the speaker output to slowly increase and decrease volume. But it overrides the source(default microphone input) and stops microphone from being detected. so I want a solution which doesn't creates a problem like this.

Here is the code of it's singing:

import random
from os.path import dirname, join

from adapt.intent import IntentBuilder
from mycroft import MycroftSkill, intent_handler
from mycroft.skills.audioservice import AudioService
from mycroft.audio import wait_while_speaking

class SingingSkill(MycroftSkill):
    def __init__(self):
        super(SingingSkill, self).__init__(name="SingingSkill")
        self.process = None
        self.play_list = {
            0: join(dirname(__file__), "popey-favourite.mp3"),
            1: join(dirname(__file__), "popey-jackson.mp3"),
            2: join(dirname(__file__), "popey-jerusalem.mp3"),
            3: join(dirname(__file__), "popey-lose-yourself.mp3"),
            4: join(dirname(__file__), "popey-lovemetender.mp3"),
            5: join(dirname(__file__), "popey-rocketman.mp3"),
        }

    def initialize(self):
        self.audioservice = AudioService(self.bus)
        self.add_event("mycroft.sing", self.sing, False)

    def sing(self, message):
        self.process = play_mp3(self.play_list[3])

    @intent_handler(IntentBuilder('').require('Sing'))
    def handle_sing(self, message):
        path = random.choice(self.play_list)
        try:
            self.speak_dialog('singing')
            wait_while_speaking()
            self.audioservice.play(path)
        except Exception as e:
            self.log.error("Error: {0}".format(e))

    def stop(self):
        if self.process and self.process.poll() is None:
            self.speak_dialog('singing.stop')
            self.process.terminate()
            self.process.wait()


def create_skill():
    return SingingSkill()

This was my code with alsaaudio:

import alsaaudio
import random
from os.path import dirname, join

from adapt.intent import IntentBuilder
from mycroft import MycroftSkill, intent_handler
from mycroft.skills.audioservice import AudioService
from mycroft.audio import wait_while_speaking

class SingingSkill(MycroftSkill):
    def __init__(self):
        super(SingingSkill, self).__init__(name="SingingSkill")
        self.process = None
        self.play_list = {
            0: join(dirname(__file__), "popey-favourite.mp3"),
            1: join(dirname(__file__), "popey-jackson.mp3"),
            2: join(dirname(__file__), "popey-jerusalem.mp3"),
            3: join(dirname(__file__), "popey-lose-yourself.mp3"),
            4: join(dirname(__file__), "popey-lovemetender.mp3"),
            5: join(dirname(__file__), "popey-rocketman.mp3"),
        }

    def initialize(self):
        self.audioservice = AudioService(self.bus)
        self.add_event("mycroft.sing", self.sing, False)

    def sing(self, message):
        self.process = play_mp3(self.play_list[3])

    @intent_handler(IntentBuilder('').require('Sing'))
    def handle_sing(self, message):
        path = random.choice(self.play_list)
        try:
            self.speak_dialog('singing')
            wait_while_speaking()
            self.audioservice.play(path)
        except Exception as e:
            self.log.error("Error: {0}".format(e))

    def stop(self):
        if self.process and self.process.poll() is None:
            self.speak_dialog('singing.stop')
            self.set_volume()
            self.process.terminate()
            self.process.wait()

    def set_volume(self):
        print("Hello")
        m=alsaaudio.Mixer()
        m.setvolume(80)
        volume=0.5
        new_volume=80
        for i in rane(0,80):
            new_volume = new_volume - volume
            m.setvolume(new_volume)

def create_skill():
    return SingingSkill()
  • Hi El_Dorado,One solution is to use a cheapy US$8, digital class D power amp module which has DC level volume control. With an I2C or SPI DAC, you can use Rpi to output say, as fine as 32 analog voltage levels to control volume, such as fading out effects. PAM8610 10W Stero Class-D Audio Power Amplifier 32 Step DC Volume Control diodes.com/assets/Datasheets/PAM8610.pdf – tlfong01 Jul 17 at 7:22
  • AliExpress PAM8610 12V Small Power Mini Class D Digital Audio Power Amplifier Board - US$8 fr.aliexpress.com/item/… – tlfong01 Jul 17 at 7:24
  • OK, so if I want to control directly from code with amixer sset 'master',0 45% command how can I do it? for slowly turning up and down the volume and where to implement it? And for PAM8610 board with raspberry pi 3B is there any example how to control it through the code for slowly turning up and down the volume? – El_Dorado Jul 17 at 7:33
  • Well, fading out effect boils down to rpi controlling DAC to gradually decrease analog output signal controlling power amp volume. My get around is the following: (1) buy the cheapy power amp.module, (2) tear down the manual volume.thing, which is just a stupid pot. (3) connect the DAC output to the centre point of the pot. Of course you can use a digital pot, but that is an overkill. A cheapy low resolution DAC module (eg 8 bit pcf8591 ADC/DAC module) is good enough. – tlfong01 Jul 17 at 7:45
  • I have created an amplifier using TDA2007A IC and there is a potentiometer at the signal input of this Circuit which is between raspberry pi 3.5mm jack and amplifier input. I am using this potentiometer to amplify the output sound from the 3.5mm jack . speakers are of 3W 4Ohms. So if I add another amp module it will be overkill. – El_Dorado Jul 17 at 7:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.