Mauru OS sound

735 views
Skip to first unread message

Dionis L

unread,
Nov 11, 2016, 6:11:49 PM11/11/16
to Maru OS dev
Hello ,

I undestand that sound in debian do not work for now .
My idea is to make the debian apps to write to a named pipe file ,and a Android app that read from this pipe and output for example to Andorid AudioTrack. What do you think ?

Dionis L

unread,
Nov 11, 2016, 7:22:17 PM11/11/16
to Maru OS dev
if you add this to : /etc/asound.conf
pcm.!default {
    type asym
    playback.pcm {
        type plug
        slave {
            pcm {
                type file
                file "/tmp/sound_pipe"
                slave.pcm null
                format raw
            }
            rate 48000
            format s16_le
            channels 2
        }
    }
}

You will redirect alsa sound to a file .Now if you open  vlc and play a file you will see that the file /tmp/sound_pipe is created and contains sound .
I have to create a android app that read from this file and output to AudioTrack Android Class

Preetam

unread,
Nov 11, 2016, 8:45:08 PM11/11/16
to Maru OS dev
Hey Dionis,

That's a really cool idea!

If you can get this to work, I would be very happy to accept this into Maru OS so we can get audio support in Debian!

Best,
Preetam
Message has been deleted

Dionis L

unread,
Nov 11, 2016, 9:57:12 PM11/11/16
to Maru OS dev
Vlc , aplay , firefox youtube  have sound ,I think it must work for all apps

Dionis L

unread,
Nov 11, 2016, 11:33:59 PM11/11/16
to maru-...@googlegroups.com
mp4 videos have the best sound with ffplay , I see vlc is not very good not so videos and not for audio.

Is good youtube videos in firefox have very good sound !

Dionis L

unread,
Nov 12, 2016, 2:45:51 AM11/12/16
to Maru OS dev
Ok , here is all you need to do to have sound in debian .

I'll put "----------------------------------------------------------------------------" as delimiters from code to another comments

first you must to install in debian alsa and alsa-utils .
add to /etc/asound.conf
----------------------------------------------------------------------------

pcm.!default {
    type asym
    playback.pcm {
        type plug
        slave {
            pcm {
                type file
                file "/tmp/sound_pipe"
                slave.pcm null
                format raw
            }
            rate 44100
            format s16_le
            channels 2
        }
    }
}
-----------------------------------------------------------------------------
Create a file named sound.c  ,it will create a named pipe and will receive data from alsa thru this named pipe and output to a socked , code is simple like for beginers ,of course can be inproved.

sound.c
-----------------------------------------------------------------------------
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>


#define MY_PORT 8080


void main()
{

    int sockfd;

        struct sockaddr_in self;

    int MAXBUF  =       50;

        unsigned char buffer[MAXBUF];

    FILE *ptr;

    size_t num;

    char pipe_file[] = "/tmp/sound_pipe";

    mkfifo(pipe_file, 0666);

    printf("\nServer Started\n");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
        {
                perror("Socket");
                return;
        }

    int enable = 1;

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
    {
       printf("setsockopt(SO_REUSEADDR) failed");
       return;
    }

    memset(&self, 0, sizeof(self));

        self.sin_family = AF_INET;
        self.sin_port = htons(MY_PORT);
        self.sin_addr.s_addr = INADDR_ANY;

    if ( bind(sockfd, (struct sockaddr*)&self, sizeof(self)) != 0 )
        {
                perror("socket--bind");
                return;
        }

        if ( listen(sockfd, 20) != 0 )
        {
                perror("socket--listen");
                return;
        }



                int clientfd;

                struct sockaddr_in client_addr;

                int addrlen=sizeof(client_addr);


                clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);

                int go = 1 ;
                int s ;

                printf("connected %s:%d \n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

                ptr = fopen(pipe_file,"rb");


        while(go)
        {

                num = fread(buffer,sizeof(buffer[0]),MAXBUF,ptr);

            if ( num > 0)
            {
                 if ( (  s = send(clientfd, buffer, num , 0) ) == -1 )
                                {
                                        go = 0;
                                }
            }

        }



        close(clientfd);


        close(sockfd);

}
----------------------------------------------------------------------------
do into your debian : apt-get install build-essential
and compile sound.c : gcc -o sound sound.c

Next create a simple android app project name it for example play and I added just MainActivity for now , but it must at least run as a service .
MainActivity.java
----------------------------------------------------------------------------
package com.example.play;


import java.io.DataInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.util.Log;


 
public class MainActivity extends Activity

{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        runThread();
     
    }
   
    public void runThread()
    {
       
        Thread thread = new Thread(new Runnable(){
            @Override
            public void run()
            {
 
                 playSound();
      
            }
        });

      thread.start();
     
    }
   
    public void playSound()
    {
       

        int minBufferSize = AudioTrack.getMinBufferSize(44100 , AudioFormat.CHANNEL_OUT_STEREO , AudioFormat.ENCODING_PCM_16BIT );
 
 
        AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO , AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
 
        int bufferSize = 512 * 1024; // 512 kb
       
        int received = 0;
       
        byte[] buffer = new byte[bufferSize];
       
        try
        {
            Socket  socket = new Socket("127.0.0.1", 8080 );
 
            DataInputStream dis = new DataInputStream(socket.getInputStream());

            at.play();
           
            while( (received = dis.read(buffer, 0, bufferSize) ) > -1)
            {
                at.write(buffer, 0, received);

            }
           
            at.stop();
            at.release();
            dis.close();
            socket.close();

        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
       
    }
   
}
------------------------------------------------------------------------------------------------------
Add : <uses-permission android:name="android.permission.INTERNET"/>
to your play app manifest.

Do a : /etc/init.d/alsa-utils restart
run your sound.c  : ./sound
run your Android play app into your phone .
You can test your sound : aplay test.wav

sound.c is the first that must to be run , next the play android app .



Dionis L

unread,
Nov 12, 2016, 2:57:40 AM11/12/16
to Maru OS dev
Here are also attached compiled bianries for the ones who do not have time to compile :
you still have to install and configure alsa ,like in previous post.
debian_sound.tar.gz
Message has been deleted

Dionis L

unread,
Nov 12, 2016, 10:08:14 AM11/12/16
to Maru OS dev
I tried also via udp , but it is like sound is doung fast skipping , so a connected stream tcp socket is better,

Dionis L

unread,
Nov 13, 2016, 4:40:42 AM11/13/16
to Maru OS dev
Hello ,

Have you tested the demo about how to make sound work ?
For me works .
Have a good day!

Preetam

unread,
Nov 13, 2016, 6:20:00 PM11/13/16
to maru-...@googlegroups.com
Hi Dionis,

Wow, awesome work and thanks for sharing your solution! I will test this out and get back to you.

If you are interested in sending a pull request on GitHub for this, you can add your customizations like so:

You can easily build the desktop image with your customizations with:


$ ./build.sh -b debian -n jessie


There is even a Dockerfile for your convenience which lists all the dependencies needed.


And finally, you can see the Developer Guide to understand how to build your own complete Maru OS image with your changes.


There are many repositories to touch and it can be a long process to set up your system for building Maru OS so I can add your changes for you once I've tested everything.


Thanks again,
Preetam

Dionis L

unread,
Nov 13, 2016, 9:04:53 PM11/13/16
to Maru OS dev
Thank you very much for infos! I'll start using git as soon as possible ,I still wait to download fies ,so I can buildmyselfall this and test the image.
Thanks again!

ImOnLinux

unread,
Nov 29, 2016, 2:54:34 PM11/29/16
to Maru OS dev
I was looking at the same thing myself. I went with a different solution though. I found  kaytat's blog in which he explains how to setup pulseaudio to use the module-simple-protocol to get audio from his linux based HTPC to his android phone so that he could use the phones headphones. I installed pulseaudio and pavucontrol using synaptic on the maruOS desktop. I then followed the kaytat's process to configure pulseaudio.  When I ran the command to list sources I only had a dummy device with an index value of 0, so that is the one that I used. When I edited /etc/pulse/default.pa my addition was as follows:

load-module module-simple-protocol-tcp source=0 record=true port=12345

I then restarted pulseaudio per the blog and installed and configured the android app. I configured the android app to connect to the IP address of the maruOS desktop.

I now have sound on my monitor via the hdmi cable from the maruOS desktop. Just starting to mess around with this so no info on latency or what works or doesn't yet.

Preetam

unread,
Nov 29, 2016, 4:11:16 PM11/29/16
to Maru OS dev
Awesome! Thanks for sharing! I'd like to get one of these approaches integrated into Maru OS so that desktop sound works out of the box. Keep us posted on how your testing goes!

Georgian Chituc

unread,
Dec 15, 2016, 6:40:02 PM12/15/16
to maru-...@googlegroups.com
Hello ,

Pulseaudio  redirect to a port is interesting.  Works for vlc but dnt seams to work for youtube in firefox if vlc plugin is enabled , all is good over all!

Twaik Yont

unread,
Jun 17, 2017, 6:26:02 AM6/17/17
to maru-...@googlegroups.com
I tried to output audio through OpenSLES. I didn't find instruments to open named piped directly so I read it to buffer. I have borrowed some test code from OpenSLES source.
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *
http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* interactive buffer queue test program */
#ifdef ANDROID
#define USE_ANDROID_SIMPLE_BUFFER_QUEUE // change to #undef for compatibility testing
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <poll.h>
#include <fcntl.h>


#include <SLES/OpenSLES.h>
#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE
#include <SLES/OpenSLES_Android.h>
#endif
#ifdef USE_ANDROID_SIMPLE_BUFFER_QUEUE
#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
#define IID_BUFFERQUEUE SL_IID_ANDROIDSIMPLEBUFFERQUEUE
#define BufferQueueItf SLAndroidSimpleBufferQueueItf
#define BufferQueueState SLAndroidSimpleBufferQueueState
#define INDEX index
#else
#define DATALOCATOR_BUFFERQUEUE SL_DATALOCATOR_BUFFERQUEUE
#define IID_BUFFERQUEUE SL_IID_BUFFERQUEUE
#define BufferQueueItf SLBufferQueueItf
#define BufferQueueState SLBufferQueueState
#define INDEX playIndex
#endif
#define checkResult(r) do { if ((r) != SL_RESULT_SUCCESS) fprintf(stderr, "error %d at %s:%d\n", \
 
(int) r, __FILE__, __LINE__); } while (0)
typedef struct {
 
short left;
 
short right;
} frame_t;
#define SINE_FRAMES (44100*5)
frame_t sine
[SINE_FRAMES];
BufferQueueItf expectedCaller = NULL;
void *expectedContext = NULL;
static void callback(BufferQueueItf caller, void *context)
{
 putchar
('.');
 
if (caller != expectedCaller)
 printf
("caller %p expected %p\r\n", caller, expectedCaller);
 
if (context != expectedContext)
 printf
("context %p expected %p\r\n", context, expectedContext);
 fflush
(stdout);
}


int sleepTimeFromRate(int sampleRate /* per microsecond */, int bitsPerSample, int channelCount, int samplesGot) {
 
return sampleRate / samplesGot * bitsPerSample * channelCount;
}


int main(int argc, char **argv)
{
 
if (argc != 2) {
 printf
("usage: %s <pulseaudio pipe>\n", argv[0]);
 
exit(1);
 
}
 
 
SLresult result;
 
// create engine
 
SLObjectItf engineObject;
 result
= slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); checkResult(result);
 result
= (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); checkResult(result);
 
SLEngineItf engineEngine;
 result
= (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); checkResult(result);
 
// create output mix
 
SLObjectItf outputmixObject;
 result
= (*engineEngine)->CreateOutputMix(engineEngine, &outputmixObject, 0, NULL, NULL); checkResult(result);
 result
= (*outputmixObject)->Realize(outputmixObject, SL_BOOLEAN_FALSE); checkResult(result);
 
// create audio player
 
SLDataSource audiosrc;
 
SLDataSink audiosnk;
 
SLDataFormat_PCM pcm;
 
SLDataLocator_OutputMix locator_outputmix;
 
SLDataLocator_BufferQueue locator_bufferqueue;
 locator_bufferqueue
.locatorType = DATALOCATOR_BUFFERQUEUE;
 locator_bufferqueue
.numBuffers = 255;
 locator_outputmix
.locatorType = SL_DATALOCATOR_OUTPUTMIX;
 locator_outputmix
.outputMix = outputmixObject;
 pcm
.formatType = SL_DATAFORMAT_PCM;
 pcm
.numChannels = 2;
 pcm
.samplesPerSec = SL_SAMPLINGRATE_44_1;
 pcm
.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
 pcm
.containerSize = 16;
 pcm
.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
 pcm
.endianness = SL_BYTEORDER_LITTLEENDIAN;
 audiosrc
.pLocator = &locator_bufferqueue;
 audiosrc
.pFormat = &pcm;
 audiosnk
.pLocator = &locator_outputmix;
 audiosnk
.pFormat = NULL;
 
SLObjectItf playerObject;
 
SLInterfaceID ids[1] = {IID_BUFFERQUEUE};
 
SLboolean flags[1] = {SL_BOOLEAN_TRUE};
 result
= (*engineEngine)->CreateAudioPlayer(engineEngine, &playerObject, &audiosrc, &audiosnk,
 
1, ids, flags); checkResult(result);
 result
= (*playerObject)->Realize(playerObject, SL_BOOLEAN_FALSE); checkResult(result);
 
SLPlayItf playerPlay;
 result
= (*playerObject)->GetInterface(playerObject, SL_IID_PLAY, &playerPlay); checkResult(result);
 
BufferQueueItf playerBufferqueue;
 result
= (*playerObject)->GetInterface(playerObject, IID_BUFFERQUEUE, &playerBufferqueue); checkResult(result);
 
SLuint32 state;
 state
= SL_PLAYSTATE_PLAYING;
 result
= (*playerPlay)->SetPlayState(playerPlay, state); checkResult(result);
 
/*unsigned i;
 float pi2 = 3.14*2;
 float hz = 441;
 float sr = 44100;
 for (i = 0; i < SINE_FRAMES; ++i) {
 sine[i].left = sin((float) (i / (sr / hz)) * pi2 ) * 32000.0;
 sine[i].right = sine[i].left;
 }
 for (i=0; i<500; i++) {
 usleep(10000);
 result = (*playerBufferqueue)->Enqueue(playerBufferqueue, sine, sizeof(sine));
 }*/

 
#define MAX_BUFF_SIZE 4096
 
 frame_t buff
[MAX_BUFF_SIZE];
 memset
(buff, 0, sizeof(buff));
 
 
int fd,ret,len;
 
struct pollfd fdinfo[1];


 
if((fd = open(argv[1], O_RDONLY)) == -1) {
 perror
("Error opening pulseaudio pipe");
 
exit(1);
 
}
 


 fdinfo
[0].fd = fd;
 fdinfo
[0].events = POLLIN|POLLPRI ;
 
//printf("start reading...\n");
 
int playtime;


 
while(1){
 ret
= poll(fdinfo,1,-1);
 
if (ret < 0) printf("\n error \n");
 
if ( ((fdinfo[0].revents&POLLIN) == POLLIN) || ((fdinfo[0].revents&POLLPRI) == POLLPRI) ){
 len
= read(fdinfo[0].fd, buff, sizeof(buff));
 
//printf("read (%d)...\n", len);
 
if (len > 0){
 result
= (*playerBufferqueue)->Enqueue(playerBufferqueue, buff, len);
 playtime
= pcm.samplesPerSec/(len/sizeof(frame_t))*10;
 
//printf("play time is\t%d\n", playtime);
 usleep
(playtime*0.9);
 
}
 
}
 
}
}
It works with lags while playing music through vlc but it works cool with mplayer. I didn't test it with Chrome or Firefox.

I think you need to set alsa to redirect sound to PulseAudio. /etc/asound.conf:
pcm.pulse {
type pulse
}
ctl.pulse {
type pulse
}
pcm.!default {
type pulse
}
ctl.!default {
type pulse
}
Maybe my code works with alsa pipes but i didn't test it. 

Twaik Yont

unread,
Jun 17, 2017, 6:36:57 AM6/17/17
to maru-...@googlegroups.com
And, if you are interested in Java, I found the project https://github.com/dront78/PulseDroid . It connects to PulseAudio using simple protocol. You need to add this line to the pulseaudio.conf:
load-module module-simple-protocol-tcp rate=44100 format=s16le channels=2 record=true port=12345" listen=127.0.0.1
I think we can use libandroid_runtime to use AudioTrack API without Java, but on my PC libandroid_runtime building fails with error and I didn't fix it yet.
P.S. I think AudioTrack can play pulseaudio pipe like Xserver XSDL does. Android SDL in commandergenius project uses AudioTrack API to play /data/data/x.org.server/files/pulse/audio-out pipe

Georgian Chituc

unread,
Jun 17, 2017, 9:26:58 PM6/17/17
to Maru OS dev
Sound works , In a way or another , using a named piper , or like your or others said a socket , and pulse audio .
What is not working for now is 3d acceleration , I could not find a good doc , how to make it work .
I was first thinking at libhybris , but then I think at freedreno , but the freedreno dev said is about some luck to make it work ,thining we have a 3.x kernel .
I know this post is about sound , and I'm talking about video , but sound works in few ways , bt no way yet for 3d video .
Maybe we focus on what we dnt have .

Twaik Yont

unread,
Jun 18, 2017, 6:05:08 AM6/18/17
to maru-...@googlegroups.com

Sound works , In a way or another , using a named piper , or like your or others said a socket , and pulse audio .
It works after manually setting up, I want it to work after firmware installation.

 What is not working for now is 3d acceleration
You can use libhybris to use Android device drivers in chroot/lxc. But there is no driver for Xorg. The way to use 3d accelleration I know is to use Mer. My friend tried to create Glamor-based Xorg driver but it worked like a shit.

Twaik Yont

unread,
Jun 19, 2017, 3:53:38 PM6/19/17
to Maru OS dev
I fixed my OpenSLES pipe player. Now it can play sound from pipe created with pulseaudio or alsa (pipe should be created before running the program). Parameters of sound need to be "rate=44100 format=s16le channels=2". I used this config for PA.
It can be easily integrated into mflinger.
android_pulseplay.tar.gz

Preetam

unread,
Jun 23, 2017, 10:00:43 PM6/23/17
to Maru OS dev
Great work Twaik and Georgian!

I finally had a chance to try your demos and I think the best approach is a combination of your approaches:

1) I modified Twaik's PulsePipePlayer that uses OpenSLES (avoids need for Java app) to run as a daemon like mflinger--I have called it maudioflinger for now. I also made changes to make the implementation much more robust by always having maudioflinger create the pipe and hold on to a dummy writer to prevent the pipe from closing when a user stops an audio program in Maru Desktop. I also added a sleep in the main thread loop to prevent it from hogging CPU.
 
2) I used Georgian's approach of using the "file" plugin for ALSA with his custom /etc/asound.conf to pipe all audio to maudioflinger. I was able to avoid needing to use sockets like in Georgian's original approach (sound.c) by creating the named pipe on a shared mount between Android and the Maru Desktop container, so both sides could directly read and write to it. (One interesting thing I found is that the ALSA file plugin creates a normal file if the target file doesn't exist, but if you pre-create the target file as a named pipe like maudioflinger does, ALSA will not overwrite it but just write to it, so it plays nicely with named pipes.)

I have found that simple programs like aplay for .wavs, mpg321 for .mp3s work great with very low latency but YouTube on Firefox is very laggy when audio is enabled...it even slows down the video playback! VLC is laggy too. Maybe we can make adjustments to make the performance better? It would be awesome if YouTube was able to play without lag... I feel like we will need to look at hardware acceleration to truly improve this since it is very CPU-intensive to be doing both graphics and audio simultaneously without hardware acceleration.

So others can try this out and improve on it, I have pushed everything needed to get this running out of the box on Maru OS on an experimental branch "experimental/audio" in vendor_maruos (selinux policies, addition of maudioflinger to boot process via init.maru.rc, etc):

https://github.com/maruos/vendor_maruos/commit/c34535a1cca09030e801813020eebf3c44720532

The only thing you will need to do after building Maru OS with the experimental/audio branch and flashing your device is:
1) sudo apt-get install alsa-utils
2) as Georgian described earlier, create this /etc/asound.conf on Maru Desktop and then run "sudo /etc/init.d/alsa-utils restart":

maru@jessie:~$ cat /etc/asound.conf                                                        
pcm
.!default {

    type asym
    playback
.pcm {
        type plug
        slave
{
            pcm
{

                type file
                file
"/mnt/maru/maudio"

                slave
.pcm null
                format raw
           
}
            rate
44100
            format s16_le
            channels
2
       
}
   
}
}

Then you can start any program with audio and it should just work.

Anyone interested in helping out: please set up a Maru OS development environment as described on our wiki if you'd like to work on this and send over a PR with your improvements--I am very happy to merge in your contributions so that this gets good enough to be shipped officially!

Thanks again Georgian and Twaik for putting in the work to get this going!

Georgian Chituc

unread,
Jun 24, 2017, 12:35:39 AM6/24/17
to Maru OS dev
That's great work  ! Sound got into Maru !

I remember I also had problems with lag of sound in firefox , but I have fixed it . I was close to : no noticeable  lag .

I have to investigate and check out my final sound solution fr lag , but I recommend you to first try the simplest  one : install into firefox the vlc plugin and check to see if things go better .

Any way , very great news! Thank you!

Twaik Yont

unread,
Jan 1, 2018, 8:37:36 PM1/1/18
to Maru OS dev
Hi! I have a good news. I created Pulseaudio OpenSL ES backend driver, so it can write sound directly to Android. The only nuance is that pulseaudio should be built with Android NDK, Building scripts and OpenSL ES pulseaudio sink module source is here. Pulseaudio developer reported that it work without lags. Alsa playback works well using pulseaudio module. 
Script to run built pulseaudio on rooted device:
#!/bin/sh
adb root
adb shell mount
-o remount,rw /
adb push
out-arm/usr /usr
adb push android
-pulseaudio.conf /


adb shell HOME
=/pulse TMPDIR=/pulse LD_LIBRARY_PATH=/usr/lib:/usr/lib/pulseaudio/:/usr/lib/pulse-11.1/modules/ /usr/bin/pulseaudio --disable-shm -n -F android-pulseaudio.conf --daemonize=false --use-pid-file=false --log-target=stderr --log-level=debug --system=false --dl-search-path=/usr/lib/pulse-11.1/modules/


Config for ALSA in debian container:
# Default to PulseAudio
pcm
.!default {
 type pulse
 hint
{
 show on
 description "Default ALSA Output (currently PulseAudio Sound Server)"
 
}
} ctl.!default { type pulse }

pcm
.pulse {
 type pulse
 hint
{
 show on
 description
"PulseAudio Sound Server"
 
}
}

ctl
.pulse {
 type pulse
}


Georgian Chituc

unread,
Jan 21, 2018, 3:19:25 PM1/21/18
to maru-...@googlegroups.com
I 've used different ways to play sound from debian , some better than others , but in all cases it had to have some android app or android code running .
The problem was that the sound was redirected to my monitor who do not have speakers and sound did not played in phone speakers .
Using android developers options to do not route sound thru hdmi did not helped , so the only way was to insert cable into monitor jack .

But now I found a way to directly output sound from linux to the phoen speakers , by using directly the pcm device .
No android code or linux code needs to be writen , andd there is no sound lag .
The 'hard' part is just to find out what is the hw id of spearks , for the htc 10 it was hw:0,15 ,but I have a way to easly find that too .

So now i play nicely sound from firefox :) direct;y to phone speakers :D

Twaik Yont

unread,
Jan 21, 2018, 3:32:30 PM1/21/18
to Maru OS dev
Are system sounds play to HDMI too? If it is not I can patch pulseaudio-sles-ndk to force use SL_ANDROID_STREAM_SYSTEM instead of default SL_ANDROID_STREAM_MEDIA.

Georgian Chituc

unread,
Jan 21, 2018, 3:55:00 PM1/21/18
to Maru OS dev
Yes , all android sounds go thru hdmi if hdmi monitor cable is inserted .

Using the method that i found today it write directly to speakers, even if I insert headphones it still play thru speakers . It looks good ,for now I use pulseaudio with alsa and aplay . I try to do some tweaks and I'll post here how to do it . Is not hard to do it , it looks alsa is able to write to hw:0,15 direcly , but pulseaudio must be used cause firefox supports just pulseaudio .
I try to find a way to pipe from pulseaudio to alsa directly . Now I use aplay .

In big works I do this :

$amixer cset numid=1055,iface=MIXER,name='QUAT_MI2S_RX Audio Mixer MultiMedia5' on

(this command is device specific)

to take control over the hw mixer .

Then add to pulseaudio /etc/pulse/default.pa :
load-module module-simple-protocol-tcp rate=44100 format=s16le channels=2 source=auto_null.monitor record=true port=8000 listen=127.0.0.1

then i use nc to get the stream from pulseaudio 8000 tcp port and pipe to aplay
$nc 127.0.0.1 8000 | aplay -D hw:0,15 -f cd -

and it play in phone speakers because hw:0,15  is the output for speakers .
All is good , I used nc and aplay to experiment and see sound working but I try to get ride of them and pipe directly from pulseaudio to alsa .
alsa is configured ok :
cat /etc/asound.conf
pcm.!default {
    type hw
    card 0
        device 15
}

ctl.!default {
    type hw        
    card 0
}

I have just to find the config for pulseaudio to pipe to alsa

Georgian Chituc

unread,
Jan 21, 2018, 5:21:06 PM1/21/18
to Maru OS dev
Ok , all is done , linux sound outputs  to kernel without to have to mod android .All is good and no lag of course :)

No need for testing tools like aplay etc .

It just need a magic command to enable the phone speakers at linux boot , because sound is routed thru hdmi and spekers are off when hdmi is attached .

All now is simple and works .These are for HTC 10 .

In lxc config mount /dev/snd bind to container , same like /dev/input .I always have to reboot phone so new configs to works when I modify the lxc config mounts
Then all you need to modify is inside debian :


/etc/asound.conf :
pcm.!default {
    type hw
    card 0
        device 15
}

ctl.!default {
    type hw        
    card 0
}

/etc/pulse/default.pa uncomment :

load-module module-alsa-sink


To work this 'magic' command must be run at boot :
$ amixer -c 0 cset numid=1055,iface=MIXER,name='QUAT_MI2S_RX Audio Mixer MultiMedia5' on
It enable the speakers so alsa can output to hw,0,15 .

So when you know how to enable the speakers all is easy .Here is how to get the magic command  that enable speakers .

---------------------------------------------------------------------
This command is device specific but can be easly obtained .You have to run inside debian :
#alsactl monitor
then start inside android some music .Start stop music inside android till you have something .
I got "numid=1055" for it .
Then run:
#amixer controls | egrep "numid=1055,"
It will output a long string you gave to 'cget' it .
For me I had to run :
amixer cget numid=1055,iface=MIXER,name='QUAT_MI2S_RX Audio Mixer MultiMedia5'
It output 'on' , so 'on' is the one who make mixer on , for some other devices it can differ , that you have to extract it .

So I got the magic command taht enable the speakers so alsa can write to hw:0,15 who is my speakers .
amixer -c 0 cset numid=1055,iface=MIXER,name='QUAT_MI2S_RX Audio Mixer MultiMedia5' on
---------------------------------------------------------------------

A B

unread,
Jan 21, 2018, 5:39:48 PM1/21/18
to Maru OS dev
If you are not interested to play sound in phone speakers and you fine to have sound out via hdmi ,then is even simpler .
You just have to see the hw id for /etc/asound.conf and you dnt need to run nothing on boot .
To know what values to put inside /etc/asound.conf you can do this .
Attach the hdmi cable to the phone , start some music from android and go into debian and run this :

#
cd  /proc/asound/card0/

#grep -v closed */sub0/status

For me I got this on HTC 10 :
root@localhost:/proc/asound/card0# grep -v closed */sub0/status
pcm15p/sub0/status:state: RUNNING
pcm15p/sub0/status:owner_pid   : 308
pcm15p/sub0/status:trigger_time: 5025.030141572
pcm15p/sub0/status:tstamp      : 5658.914714459
pcm15p/sub0/status:delay       : 12768
pcm15p/sub0/status:avail       : 75432
pcm15p/sub0/status:avail_max   : 0
pcm15p/sub0/status:-----
pcm15p/sub0/status:hw_ptr      : 28639800
pcm15p/sub0/status:appl_ptr    : 28652568

This means the hw for alsa is hw:0,15 .

So next you just need to config alsa and pulse like I writed in previous msg ,and all is done .
But I wanted to have sound in phone speakers so taht I had to use that 'magic' command .

--
You received this message because you are subscribed to a topic in the Google Groups "Maru OS dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/maru-os-dev/HzqAdt2bpNw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to maru-os-dev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/maru-os-dev/66574a4e-20ac-4cc7-80c0-f62966c35426%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Twaik Yont

unread,
Jan 22, 2018, 6:44:38 AM1/22/18
to Maru OS dev
Did you try that to avoid using Pulseaudio? https://github.com/i-rinat/apulse
To unsubscribe from this group and all its topics, send an email to maru-os-dev...@googlegroups.com.

Georgian Chituc

unread,
Jan 22, 2018, 7:20:48 AM1/22/18
to Maru OS dev
Pulseaudio is fine ,I did not tried to avoid using it , because I use the pulseaudio volume control from panel.And all works good.
By the way ,I just mute android sound when I play sounds from debian. I can control the volume from pulseaudio panel widget .So is good . This was a test Debian to native use sound hardware from lxc and looks good .I do not say is the perfect solution but I see no problems , I just tried to play sounds fromdebian directly to hardware without to mod android part .

Georgian Chituc

unread,
Jan 23, 2018, 8:15:55 PM1/23/18
to Maru OS dev
@Twaik I try now your pulseaudio-sles-ndk .
 
It looks likea  very interesting project . Thank you for sharing :)


Georgian Chituc

unread,
Jan 23, 2018, 9:48:28 PM1/23/18
to Maru OS dev
Ok , it works great . You did it !
And also I can play music from android apps too . Good job!

Twaik Yont

unread,
Jan 24, 2018, 2:16:50 AM1/24/18
to Maru OS dev
Thanks :)

Georgian Chituc

unread,
Jan 24, 2018, 6:20:46 PM1/24/18
to Maru OS dev
Your pulseaudio android sles is great ,but it have a memory leak somewhere .
After playing music from debian for 2-3 hours I got just 20 mb avaible memory and when I killed the android pulseaudio it restored me 2,3 Gb avaible memory !
I have a htc 10 with 4 gb ram .
Can you please investigate ?

Twaik Yont

unread,
Jan 24, 2018, 7:00:08 PM1/24/18
to Maru OS dev
Thanks for the reply. I will check it. By the way you are the first one who noticed the memory leak.

Georgian Chituc

unread,
Jan 24, 2018, 7:18:58 PM1/24/18
to Maru OS dev
That is what happened to me , you can just open in Debian a vlc player with a long YouTube mix and configure vlc to disable video , don't open another apps in android or Debian just a top in Debian terminal ,and in half a hour you must to have little avaible men .
this men will become again avaible if you kill android pulseaudio.

Georgian Chituc

unread,
Jan 24, 2018, 9:43:15 PM1/24/18
to maru-...@googlegroups.com
Sadly I could reproduce the memory leak also using Ubuntu 16.04 inside lxc .

When ubuntu starts there are around 2.1 Gb avaible mem .
Playing for 2 hours sound using vlc and firefox ,avaible mem go down to 900 MB .
Closing all Ubuntu programs avaible memory go up to 1.3 gb .
Killing pulseaudio android , mem go up again around 2.1 avaible mem .

When I saw first time it leaks mem , I saw it because android already started to randomly kill processes because of low memory .
This did not happend before and I run a clean AOSP like android version ,so I suspected the new added binary , pulseaudio is the cause .
When I killed it , avaible mem go from 40 mb to 2 Gb . ( That was first time I had the problem with leak )

Twaik Yont

unread,
Jan 25, 2018, 2:05:12 PM1/25/18
to Maru OS dev
Looks like memory leak is fixed now. Try it again.

Georgian Chituc

unread,
Jan 25, 2018, 5:38:03 PM1/25/18
to Maru OS dev
Ok , that's great , I will try now . Will let it play for few hours and see how is going .
Thanks!

Georgian Chituc

unread,
Jan 25, 2018, 6:19:46 PM1/25/18
to Maru OS dev
Is the sound good for you? I hear a lot of noise like when sample rate is wrong ....

Georgian Chituc

unread,
Jan 25, 2018, 9:23:21 PM1/25/18
to Maru OS dev
I do not know from where taht strange noice comes but I have some ideeas .
I tryed this :

static uint8_t xbuffer[102400]; //what max value it may have?

static void process_render(struct userdata *u, pa_usec_t now) {
    size_t ate = 0;

    pa_assert(u);

    /* This is the configured latency. Sink inputs connected to us
    might not have a single frame more than the maxrequest value
    queued. Hence: at maximum read this many bytes from the sink
    inputs. */

    /* Fill the buffer up the latency size */
    while (u->timestamp < now + u->block_usec)
    {
        void *p;
        size_t xsize;
       
        pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk);
       
        p = pa_memblock_acquire(u->memchunk.memblock);

        memcpy(xbuffer,(uint8_t*) p + u->memchunk.index, u->memchunk.length);

        xsize = u->memchunk.length;

        pa_memblock_release(u->memchunk.memblock);
        pa_memblock_unref(u->memchunk.memblock);

        (*u->bqPlayerBufferQueue)->Enqueue(u->bqPlayerBufferQueue, xbuffer, xsize);



        u->timestamp += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
        ate += u->memchunk.length;
        if (ate >= u->sink->thread_info.max_request) break;
    }
}


And I also had the background noise . You can see in preetam sles demo there is a callback that is called when the player finish playing a buffer . Maybe you should do the same maybe you should run " (*u->bqPlayerBufferQueue)->Enqueue " from that callback like preetam does .

Twaik Yont

unread,
Jan 26, 2018, 6:22:37 AM1/26/18
to Maru OS dev
Using callbacks makes sound terrible. I found the reason of the background noise. Enqueue call is just writes buffer location and length into the queue and when Android tries to read the buffer after the pa_memblock_unref call (resetting a memblock) the glitch appears. Not using unref call makes sound better, but causing memory gobbling. The only way to avoid glitches and memory leaks is to plan unref call right after the moment memblock used, but I still don't know how to do that right. Callbacks have no instruments to identify current buffer.

Georgian Chituc

unread,
Jan 26, 2018, 3:49:04 PM1/26/18
to Maru OS dev

Maybe you save   references of the memblocks before Enqueue , and then using the call back you free them in callback .


Any way the unref was called just after Enqueue call , but why he did not free up memory ? Is a little strange . Maybe Enqueue dnt let it free it ?

Georgian Chituc

unread,
Jan 26, 2018, 3:57:28 PM1/26/18
to Maru OS dev
Please also check how they do it to write to a fd on :
https://fossies.org/linux/misc/pulseaudio-11.1.tar.gz/pulseaudio-11.1/src/modules/module-pipe-sink.c

Al line 123process_render()

Twaik Yont

unread,
Jan 26, 2018, 4:11:46 PM1/26/18
to Maru OS dev
Writing to file descriptor differs from enqueuing. I think I will implement something like unref queue. When Pulseaudio gives memory block I will Enqueue() it and add it to UnrefQueue. Then when OpenSL ES calls the Callback function I will unref() the memory block exected to be already played. 

Georgian Chituc

unread,
Jan 26, 2018, 4:19:43 PM1/26/18
to Maru OS dev
Yes  , will be great to try that !

Twaik Yont

unread,
Jan 27, 2018, 3:43:07 PM1/27/18
to Maru OS dev
Check it out.

Georgian Chituc

unread,
Jan 27, 2018, 5:36:15 PM1/27/18
to Maru OS dev

I set it up . Sound is good ,without noise . I have to see how is memory doing .
I will let it to play for a while to see what happens , but I thing you did it again :)
Thanks !

Georgian Chituc

unread,
Jan 27, 2018, 5:51:05 PM1/27/18
to Maru OS dev
It looks like the problem is resolved . But I will stress it for a while and let it play for a longer time .
But I think is resolved :)

Georgian Chituc

unread,
Jan 27, 2018, 8:40:01 PM1/27/18
to Maru OS dev


It looks good , the little problem with pulseaudio is taht it can not be let to run for ever because it keep the speakers powered .
I do not know it it can be et up to just use sles only when a new stream arrive . If you listen close to your speakers you will notice a little sound that comes from spearks being under power ,cause pulseaudio is running .

Georgian Chituc

unread,
Jan 27, 2018, 9:34:58 PM1/27/18
to Maru OS dev
I made a little script that run at startup . It start /stop pulseaudio depending if mclient is running .So pulseaudio android starts only if debian is started .

#!/system/bin/sh

export HOME=/data/pulse

export TMPDIR=/data/pulse

export LD_LIBRARY_PATH=/system/usr2/lib:/system/usr2/lib/pulseaudio/:/system/usr2/lib/pulse-11.1/modules/


while :
do

mclient_pid=$(pidof mclient)


if [ "$mclient_pid" != "" ]; then

   echo "mclient is running"
  
   pulseaudio_pid=$(pidof pulseaudio_android)

   if [ "$pulseaudio_pid" = "" ]; then

      echo "Pulseaudio not running.Starting now ..."
      /system/usr2/bin/pulseaudio_android --disable-shm -n -F /system/usr2/etc/pulse/android-pulseaudio.conf --daemonize=true --use-pid-file=true --log-level=0 --system=false --dl-search-path=/system/usr2/lib/pulse-11.1/modules/ --exit-idle-time=-1 --disallow-exit=true   
   fi

else

  echo "mclient not running"

  pulseaudio_pid=$(pidof pulseaudio_android)

  if [ "$pulseaudio_pid" != "" ]; then

      echo "Pulseaudio running.Stopping now ..."
      killall -9 pulseaudio_android
   
  fi

fi
sleep 10
done

Twaik Yont

unread,
Jan 28, 2018, 2:54:35 AM1/28/18
to Maru OS dev
mclient is running all the time, not only when HDMI-cable is connected, isn't it? Pulseaudio can be suspended when no client is connected. This feature is activated on PC's. One pulseaudio process runs systemwide and one pulseaudio process per user. When new stream is avaliable user's pulseaudio wakes up systemwide pulseaudio and plays incoming stream. This behaviour is define here, here an here. The user's part of pulseaudio can be run inside of LXC container. 

Georgian Chituc

unread,
Jan 28, 2018, 3:30:30 AM1/28/18
to Maru OS dev
mclient is running as long as Ubuntu is running . By the way I switched to Ubuntu 16.04 . The stories about Debian being faster and lighter than Ubuntu in reality seams to dnt be true ,or just old stories. I find Ubuntu 16.04 much faster than Debian 9 .And everything works better ,and also more software for armhf .After testing Debian 9 for 3 weeks I made the decision to stay with Ubuntu ,this was because a lot of true reasons .
For the moment I just use the script who ckecks every 15 seconds to see if mclient is running , and if that is running it start pulseaudio .
If is no longer running it stops it .But I wold like to try another alternatives too

Georgian Chituc

unread,
Jan 28, 2018, 4:01:48 AM1/28/18
to maru-...@googlegroups.com
I added in .conf :

load-module module-suspend-on-idle timeout=20

And it already works lool . It really put the speakers off power :)

D: [sles-sink] sink-input.c: Requesting rewind due to uncorking
D: [pulseaudio_andr] module-suspend-on-idle.c: Sink OpenSL_ES_sink becomes busy, resuming.
D: [sles-sink] sink-input.c: Requesting rewind due to corking
D: [pulseaudio_andr] module-suspend-on-idle.c: Sink OpenSL_ES_sink becomes idle, timeout in 20 seconds.
D: [pulseaudio_andr] module-suspend-on-idle.c: Sink OpenSL_ES_sink becomes idle, timeout in 20 seconds.
D: [pulseaudio_andr] core.c: Hmm, no streams around, trying to vacuum.
I: [pulseaudio_andr] sink-input.c: Freeing input 0 "audio stream"
I: [pulseaudio_andr] client.c: Freed 3 "VLC media player"
I: [pulseaudio_andr] protocol-native.c: Connection died.
I: [pulseaudio_andr] module-suspend-on-idle.c: Sink OpenSL_ES_sink idle for too long, suspending ...
D: [pulseaudio_andr] sink.c: Suspend cause of sink OpenSL_ES_sink is 0x0004, suspending
D: [pulseaudio_andr] core.c: Hmm, no streams around, trying to vacuum.


Great lol :) so simple.
I just really hope the is no longer a mem leak in sles module .
For now I will let it run for a long time and see how is doing :)
Good job !

Twaik Yont

unread,
Jan 28, 2018, 4:19:25 AM1/28/18
to Maru OS dev
I didn't try that but I think the comandline should be changed to something like 
/usr/bin/pulseaudio --start --log-target=syslog -F daemon.conf



On Sunday, January 28, 2018 at 11:01:48 AM UTC+2, Georgian Chituc wrote:
I added in .conf : load-module module-suspend-on-idle timeout=20
so here is the config file :

android_pulseaudio.conf
-------------------------------------------------------
#!/usr/bin/pulseaudio -nF

.nofail

.fail

load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 port=4712 auth-anonymous=true

load-module module-default-device-restore
load-module module-rescue-streams

load-module module-always-sink

load-module module-intended-roles

load-module module-position-event-sounds

load-module module-role-cork

load-module module-filter-heuristics
load-module module-filter-apply

load-module module-switch-on-port-available

load-module module-sles-sink

load-module module-suspend-on-idle timeout=20

--------------------------------------------------------------------------------


But it just reveice a killed :

.......................
I: [pulseaudio_andr] module.c: Loaded "module-sles-sink" (index: #14; argument: "").
D: [pulseaudio_andr] module-suspend-on-idle.c: Sink auto_null becomes idle, timeout in 20 seconds.

D: [pulseaudio_andr] module-suspend-on-idle.c: Sink OpenSL_ES_sink becomes idle, timeout in 20 seconds.
I: [pulseaudio_andr] module.c: Loaded "module-suspend-on-idle" (index: #15; argument: "timeout=20").
I: [pulseaudio_andr] main.c: Daemon startup complete.
I: [pulseaudio_andr] module.c: Unloading "module-null-sink" (index: #7).
D: [pulseaudio_andr] module-rescue-streams.c: No sink inputs to move away.
I: [pulseaudio_andr] core.c: default_sink: auto_null -> OpenSL_ES_sink
I: [pulseaudio_andr] core.c: default_source: auto_null.monitor -> OpenSL_ES_sink.monitor
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to change event.
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to change event.
D: [pulseaudio_andr] module-rescue-streams.c: No source outputs to move away.
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to remove event.
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to remove event.
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to remove event.
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to remove event.
D: [null-sink] module-null-sink.c: Thread shutting down
I: [pulseaudio_andr] sink.c: Freeing sink 0 "auto_null"
I: [pulseaudio_andr] source.c: Freeing source 0 "auto_null.monitor"
I: [pulseaudio_andr] module.c: Unloaded "module-null-sink" (index: #7).
D: [pulseaudio_andr] core-subscribe.c: Dropped redundant event due to remove event.
Killed

Georgian Chituc

unread,
Jan 28, 2018, 4:22:25 AM1/28/18
to maru-...@googlegroups.com
It was killed by my mistake .

It works just to add to android conf :

load-module module-suspend-on-idle timeout=20

:) all is great . It dnt even need the pulseaudio to run inside container , just the libs :)
Great! I just hope no memleak .But it looks very good!

This setup is perfect ,and also mobile power friendly . I just hope there no longer mem leaks .Is cool !
Reply all
Reply to author
Forward
0 new messages