ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2015年9月22日 星期二

古老的...

如果不對 structure 內 field 操作。
就不需要知道 structure 的內部宣告。

所以像 tinyalsa 中 struct control
雖然 control_open 的傳回值是 struct control*
但是alsa stub 只會把 得到的 control struct*交給 tinyalsa 的 function 來操作。
所以 alsa stub 只需要宣告:
struct control;
就可以。

struct control {
    int fd;
    struct snd_ctl_card_info *card_info;
    struct ctl_pcm_info      *pcm_info_p;
    unsigned int              count_p;
    struct ctl_pcm_info      *pcm_info_c;
    unsigned int              count_c;
};

count_p 的 p 是 playback
coubt_c 是 capture

count 是數量,也就是 play, capture 的數量。

2015年9月18日 星期五

NuPlayer.cpp 的
void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
..
..
        case kWhatStart:
        {
         ..
         ..
            mOffloadAudio =
                canOffloadStream(audioMeta, (videoFormat != NULL),
                                 true /* is_streaming */, streamType);
            if (mOffloadAudio) {
                flags |= Renderer::FLAG_OFFLOAD_AUDIO;
            }


這個 kWhatStart 是由:
void NuPlayer::start() {
    (new AMessage(kWhatStart, id()))->post();
}
送出。

這邊的 caller:
android::NuPlayerDriver::start()
android::MediaPlayerService::decode(..)
..Binder..
mediaserver

typedef int snd_pcm_hw_param_t;
#define SNDRV_PCM_HW_PARAM_ACCESS       0       /* Access type */
#define SNDRV_PCM_HW_PARAM_FORMAT       1       /* Format */
#define SNDRV_PCM_HW_PARAM_SUBFORMAT    2       /* Subformat */
#define SNDRV_PCM_HW_PARAM_FIRST_MASK   SNDRV_PCM_HW_PARAM_ACCESS
#define SNDRV_PCM_HW_PARAM_LAST_MASK    SNDRV_PCM_HW_PARAM_SUBFORMAT

#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS  8       /* Bits per sample */
#define SNDRV_PCM_HW_PARAM_FRAME_BITS   9       /* Bits per frame */
#define SNDRV_PCM_HW_PARAM_CHANNELS     10      /* Channels */
#define SNDRV_PCM_HW_PARAM_RATE         11      /* Approx rate */
#define SNDRV_PCM_HW_PARAM_PERIOD_TIME  12      /* Approx distance between
                                                 * interrupts in us
                                                 */
#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE  13      /* Approx frames between
                                                 * interrupts
                                                 */
#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14      /* Approx bytes between
                                                 * interrupts
                                                 */
#define SNDRV_PCM_HW_PARAM_PERIODS      15      /* Approx interrupts per
                                                 * buffer
                                                 */
#define SNDRV_PCM_HW_PARAM_BUFFER_TIME  16      /* Approx duration of buffer
                                                 * in us
                                                 */
#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE  17      /* Size of buffer in frames */
#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18      /* Size of buffer in bytes */
#define SNDRV_PCM_HW_PARAM_TICK_TIME    19      /* Approx tick duration in us */

把有範圍的歸在一起,再用:
#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL       SNDRV_PCM_HW_PARAM_SAMPLE_BITS
#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL        SNDRV_PCM_HW_PARAM_TICK_TIME
然後就可以用這個function :
static inline int param_is_interval(int p)
{
    return (p >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL) &&
        (p <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL);
}
決定該參數是有範圍的 (upper, lower) 還是就一個值。

然後 structure:
struct snd_pcm_hw_params {
        unsigned int flags;
        struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
                               SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
        struct snd_mask mres[5];        /* reserved masks */
        struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
                                        SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
        struct snd_interval ires[9];    /* reserved intervals */
        unsigned int rmask;             /* W: requested masks */
        unsigned int cmask;             /* R: changed masks */
        unsigned int info;              /* R: Info flags for returned setup */
        unsigned int msbits;            /* R: used most significant bits */
        unsigned int rate_num;          /* R: rate numerator */
        unsigned int rate_den;          /* R: rate denominator */
        snd_pcm_uframes_t fifo_size;    /* R: chip FIFO size in frames */
        unsigned char reserved[64];     /* reserved for future */
};
也可以直接用 array ..
---- 所以適當安排 IOCTL code 還是有幫助的

2015年9月17日 星期四

Audio Input:

支援7 種 ananlog/digital source

analog input 提供 3 pairs of 2 inputs
Pair 可以規劃成:
stereo input with ground
single ended stereo input
differential stereo input
2 mono

提供 5 組 asynchronous digital I2S format input
每組可以有自己的 sample rate , clock phase
每組asynchronous I2S input 有自己的 bit clock, word select. 都是 input pin (slave)
I2S1 有 3 個 data line 可用做多 channel input
其他的 I2S 都只有 1 個 data line

Host I2S input 與 I2S output 共用 bit clock, word select
5 組 host input 區分為兩組:Host A, Host B
兩個 Host 各有自己的 bit clock, word select

Host A:
2 data input : IIS_SD_IN4, IIS_SD_IN5
bit clock, word select: IIS_SCK_IN45, IIS_WS_IN45

Host B:
3 data inputL IIS_SD_IN6, IIS_SD_IN7, IIS_SD_IN8
bit clock, word select: IIS_SCK_IN678, IIS_WS_IN678

上面兩組 Host 的 clk, ws pin: IIS_SCK_IN45, IIS_WS_IN45, IIS_SCK_IN678, IIS_WS_IN678 都可以做 input (slave) 或 output (master) 使用。

Host B 的 pin 可以configure 成 I2S mode 或是 TDM Mode



Audio Output:

3 stereo DACs.
4 synchronous Digital Port. (I2S and TDM)
另外,可藉由 I2C command, 將 5 組 asynchronous I2S input 設定變更為 asynchronous I2S output
Software Support asynchronous I2S output : IIS_SD_OUT3
每個 asynchronous I2S output 可以有不同的 sample rate 和 clock phase

asynchronous I2S output 的 bit clock, word select 都是 input (slave mode)
serial data pin 是 output

synchronous I2S output 使用 host I2S input 的 bit clock 和 word select
有 Host A, Host B 可以選

做 Most Mode 時, TDM output 使用 TDM_FSYNC_OUT, TDM_SCK_OUT 作為 frame sync和 bit clock
做 Slave Mode 時,改用 TDM_SYNC_IN, TDM_SCK_IN 作為 frame sync 和 bit clock

PIN 90.91 可設定為 S/PDIF output.

表列各 pin 的 三種功能。與所屬 groupe.
function 的變更以 groupe 為單位。


好像新版的 kernel 都已經 support uml (user-mode-linux) 了。
所以只要..
export ARCH=um
make defconfig
make all
就可以 build 出 uml

要注意的是, menuconfig 中的 UML Character Devices 裡面,最好全部都勾選。
這樣才有辦法在 xterm 中啟動。
否則會出現 channel error

2015年9月15日 星期二

5.1.1 - Z 的最後版本


有支援 exfat 喔。
-- 好像很久以前就支援了...

Kingmax 32G Pro 掛點


放在 Xperia Z 上用,還用不到半年說....

2015年9月11日 星期五

在 include/linux/kernel.h:
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
就是 n/d 無條件進位。

2015年9月10日 星期四

stack backtrace in C++, CallStack

Android 5, CallStack() 的使用方式好像變了。
現在只要在 需要的地方,用:
 CallStack(LOG_TAG);
就可以了。
-- 當然,還要 include utils/CallStack.h

這只有 c++ 能用。
C 就不行。

使用到 libunwind 的 project 有.. (查 Android.mk):
  • libbacktrace
  • ltrace
  • compiler-rt
  • libcxxabi

2015年9月9日 星期三

AudioCommand 只有 AudioPolicyService 使用。
command 有:
  • start/stopTone
  • volume
  • parameters
  • voiceVolume
  • stopOutput
  • releaseOutput
  • createAudioPatch
  • releseAudioPatch
  • updateAudioPortList
  • updateAudioPatchList
  • setAuidioPortConfig

AUDIO_STREAM_XX 定義在 system/core/include/system/audio.h
/* Audio stream types */
typedef enum {
    /* These values must kept in sync with
     * frameworks/base/media/java/android/media/AudioSystem.java
     */
    AUDIO_STREAM_DEFAULT          = -1,
    AUDIO_STREAM_MIN              = 0,
    AUDIO_STREAM_VOICE_CALL       = 0,
    AUDIO_STREAM_SYSTEM           = 1,
    AUDIO_STREAM_RING             = 2,
    AUDIO_STREAM_MUSIC            = 3,
    AUDIO_STREAM_ALARM            = 4,
    AUDIO_STREAM_NOTIFICATION     = 5,
    AUDIO_STREAM_BLUETOOTH_SCO    = 6,
    AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user
                                        * and must be routed to speaker
                                        */
    AUDIO_STREAM_DTMF             = 8,
    AUDIO_STREAM_TTS              = 9,

    AUDIO_STREAM_CNT,
    AUDIO_STREAM_MAX              = AUDIO_STREAM_CNT - 1,
} audio_stream_type_t;
有說明:這個順序要和 AudioSystem.java 一致。

AudioSystem 好像是所有 audio 的 hub
裡面都是 static function,
所以其他的 code 都可以置接用 AudioSystem::setAudioPortConfig( ), AudioSystem::get_audio_flinger( ).. etc
來使用 audio flinger, policy, manager 的服務。

2015年9月8日 星期二

先到 external/tinyalsa/Android.mk
LOCAL_MODULE:= libtinyalsa
然後 找有誰link ...
有關的有:
./hardware/imx/alsa/Android.mk
./hardware/libhardware/modules/usbaudio/Android.mk

./system/media/audio_route/Android.mk
./frameworks/base/cmds/bootanimation/Android.mk
bootanimation 的用的是自己的 audio_conf.
所以不看。

andio_route 的 target 是 libaidioroute, 查沒有我要用的。(只有 qcom. htc, asus, samsung 有用)
所以不看

hardware/imx/alsa/ 的 target 是 audio.primary$(TARGET_BOARD_PLATFORM)
source 只有 tinyalsa_hal.c (其他都是 header)

open_output_stream 是 function table.
AudioFlinger openOutput() 呼叫的。

在這裡印出 CallStack():
I/AudioFlinger(  152): loadHwModule() Loaded primary audio interface from Freescale i.MX Audio HW HAL (audio) handle 1
V/AudioFlinger(  152): openOutput(), module 1 Device 2, SamplingRate 48000, Format 0x000001, Channels 3, flags 2
D/AudioFlinger(  152): #00 pc 0000d061  /system/lib/libutils.so (android::CallStack::update(int, int)+52)
D/AudioFlinger(  152): #01 pc 0000d177  /system/lib/libutils.so (android::CallStack::CallStack(char const*, int)+38)
D/AudioFlinger(  152): #02 pc 00021c31  /system/lib/libaudioflinger.so
D/AudioFlinger(  152): #03 pc 00009d31  /system/lib/libaudiopolicyservice.so
D/AudioFlinger(  152): #04 pc 0001a029  /system/lib/libaudiopolicymanagerdefault.so (android::AudioPolicyManager::AudioPolicyManager(android::AudioPolicyClientInterface*)+1000)
D/AudioFlinger(  152): #05 pc 0000049d  /system/lib/libaudiopolicymanager.so (createAudioPolicyManager+16)
D/AudioFlinger(  152): #06 pc 00006afb  /system/lib/libaudiopolicyservice.so
D/AudioFlinger(  152): #07 pc 0000ec11  /system/lib/libutils.so (android::RefBase::incStrong(void const*) const+38)
D/AudioFlinger(  152): #08 pc 00001d5f  /system/bin/mediaserver
D/AudioFlinger(  152): #09 pc 0000169d  /system/bin/mediaserver
D/AudioFlinger(  152): #10 pc 000128f1  /system/lib/libc.so (__libc_init+44)
D/AudioFlinger(  152): #11 pc 00001938  /system/bin/mediaserver

2015年9月2日 星期三

imx6 sabreauto, audio_hw_primary logcat

I/AudioPolicyManager(  152): loadAudioPolicyConfig() loaded /system/etc/audio_policy.conf
W/audio_hw_primary(  152): card 0, id cs42888audio ,driver cs42888-audio, name cs42888-audio
W/audio_hw_primary(  152): out rate 48000
W/audio_hw_primary(  152): in rate 48000, channels 1 format 0
W/audio_hw_primary(  152): card 1, id imxspdif ,driver imx-spdif, name imx-spdif
W/audio_hw_primary(  152): out rate 0
W/audio_hw_primary(  152): in rate 44100, channels 2 format 3
V/audio_hw_primary(  152): headphone 0 ,headset 0 ,speaker 2, earpiece 0, 
I/AudioFlinger(  152): loadHwModule() Loaded primary audio interface from Freescale i.MX Audio HW HAL (audio) handle 1
W/audio_hw_primary(  152): open output stream devices 2, format 1, channels 3, sample_rate 48000, flag 2
V/audio_hw_primary(  152): adev_open_output_stream() normal buffer
W/audio_hw_primary(  152): opened out stream...1979414720, type 1
I/AudioFlinger(  152): HAL output buffer size 192 frames, normal sink buffer size 1152 frames
V/AudioFlinger(  152): MixerThread() id=2 device=0x2 type=0
V/AudioFlinger(  152): mSampleRate=48000, mChannelMask=0x3, mChannelCount=2, mFormat=1, mFrameSize=4, mFrameCount=192, mNormalFrameCount=1152
I/System  (  157): Loaded time zone names for "en_AU" in 100ms (69ms in ICU)
V/AudioMixer(  152): EffectQueryNumberEffects() numEffects=13
V/AudioMixer(  152): effect 0 is called Noise Suppression
V/AudioMixer(  152): effect 1 is called Acoustic Echo Canceler
V/AudioMixer(  152): effect 2 is called Automatic Gain Control
V/AudioMixer(  152): effect 3 is called Multichannel Downmix To Stereo
I/AudioMixer(  152): found effect "Multichannel Downmix To Stereo" from The Android Open Source Project

Install Hack font on Debian Jessie

就是這個 font: https://github.com/chrissimpkins/Hack

download 下來解開是 ttf 檔。

使用 font-manager 來安裝。
是 gnome 的 package.

啟動 font-manager 後,按齒輪icon. 選 install-fonts
然後去,一個一個 ttf 的選。
就完成了。

ttf font 會被 copy 到 ~/.fonts/Library/H/
-- 這是 link .. ~/.local/share/font-manager/Library

標籤

網誌存檔