Skip to content

FairyDevicesRD/thinklet.app.sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 

Repository files navigation

THINKLET App SDK

THINKLET本体にインストールするアプリケーションに使用することができるSDKを提供します.

ご利用にあたって

  • このライブラリ(AARファイル)を許可なく再配布・再利用はしてはいけません.
  • 本レポジトリに含まれるドキュメントに明示的に許可されている用途以外の利用を禁止します.
  • 当社は、お客様による本ライブラリの利用に関しては保証しません.
  • ライブラリおよびこれを利用するサンプルソースコードは、THINKLET実機でのみ動作します.

thinklet/sdk (documents)

sample

機能一覧

Audio

  • 必須:android.Manifest.permission.RECORD_AUDIO

API Document

MultiChannelAudioRecord

  • THINKLET本体の5chマイクへアクセスを行う AudioRecord を提供します.
  • オプションで,バッファサイズ,チャンネル数の指定,サンプリングレートの指定が可能です.
# 6ch(5ch + 1ch(=empty)), SamplingRate 48kHz
val audioRecord = MultiChannelAudioRecord().get(Channel.CHANNEL_SIX, SampleRate.SAMPLING_RATE_48000).audioRecord

RawAudioRecordWrapper

  • AudioRecordを簡易的に扱うためのクラス.
  • 録音結果を出力する OutputStream,結果を受け取る IRawAudioRecorder を提供します.
  • オプションで,参照音ありの6ch,参照音なしの5chで録音,サンプリングレートを指定,出力チャンネル数をモノラル(1ch),ステレオ(2ch)に変換できます.
private val randomFileName: String
    get() = "6ch_48kHz_${SimpleDateFormat("yyyy-MM-dd-hh-mm-ss", Locale.getDefault()).format(Date())}.raw"
private val rawFileOutputStream: FileOutputStream
    get() = FileOutputStream(File(activity.getExternalFilesDir(null), randomFileName))
private val rawRecorder = RawAudioRecordWrapper(
    channel = MultiChannelAudioRecord.Channel.CHANNEL_SIX,
    sampleRate = MultiChannelAudioRecord.SampleRate.SAMPLING_RATE_48000,
    outputChannel =  RawAudioRecordWrapper.RawAudioOutputChannel.ORIGINAL
)
private val rawRecorderCallback = object : RawAudioRecordWrapper.IRawAudioRecorder {
    override fun onReceivedPcmData(pcmData: ByteArray) {
        Log.i(TAG, pcmData.size.toString())
    }

    override fun onFailed(throwable: Throwable) {
        Log.w(TAG, throwable.message.toString())
    }
}

//----

fun do() {
    if (!rawRecorder.prepare(context)) {
        return
    }
    rawRecorder.start(rawFileOutputStream, rawRecorderCallback)
}

MicGainControl

  • マイクのゲインを調整する機能を提供します.
  • ゲインレベルはアプリごとではなく,全てのアプリで共有されます.したがって,他のアプリへ悪影響が出ないように,アプリ終了時には,resetMicGain() を呼び出すようにしてください.
private val micGainControl = MicGainControl(context)

// increase gain
micGainControl.micGain(18)

// reset gain. (default:12)
micGainControl.resetMicGain()

VolumeControl

  • 音量を段階的に変更する機能を提供します.
  • 変更するストリームについては,APIドキュメントを参照ください.

Tip

この機能はFW 7.000.0以降で,利用可能です.

private val volumeCtrl = VolumeControl(context, lifecycle)
volumeCtrl.enable()

// enabled loop: stepUp volume. 0->1->2->3->0->1->...
volumeCtrl.stepUp()
// enabled loop: stepDown volume. 3->2->1->0->3->2->...
volumeCtrl.stepDown()

// disabled loop: stepUp volume. 0->1->2->3->3->3->...
volumeCtrl.stepUp(enableLoop = false)
// disabled loop: stepDown volume. 3->2->1->0->0->0->...
volumeCtrl.stepDown(enableLoop = false)

Suppress SystemSound

  • THINKLET固有のシステム音の再生を抑制します.
    • e.g. 「オンラインになりました」を抑えます.

Tip

この機能はFW 11.000.0以降で,利用可能です.

private val soundCtrl = SystemSound(context)

// Suppress THINKLET's system sound
soundCtrl.muteMild()
// Minimize THINKLET's system sound
soundCtrl.muteMinimum()
// Remove suppress THINKLET system sound
soundCtrl.reset()

(試験的機能) 音声処理

  • 弊社の音声処理技術を活用した装着者の音声を強調するようにマイクの設定を行います.
音声強調のイメージ
音声強調のイメージ

Note

FairyDevicesの音声処理技術については,こちらをご参照ください.
本機能では,ビームフォーマ のみ提供し,装着者方向の音声のみを強調,その他の周辺の音声を抑えます.

Tip

この機能はFW 11.000.0以降で,利用可能です.

Important

この機能は,試験的機能です.予期せぬエラー,APIの変更が発生することがあります.
また,THINKLET cube モデルはサポートしていません.

private val am = context.getSystemService(AudioManager::class.java)
private val xfeCtl = ThinkletXfe()

// enable xfe
if (!xfeCtl.configureXfe(audioManager = am, xfeEnable = true)) {
    return
}
val audioRecord = AudioRecord.Builder()
    .setAudioSource(AudioSource.MIC)
    .setAudioFormat(
        AudioFormat.Builder()
            .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
            .setSampleRate(48000) // or 16000
            .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
            .build()
    )
    .setBufferSizeInBytes(1920)
    .build()
// check xfe mode.
if (!audioRecord.canXfeRecord()) {
    audioRecord.release()
    return
}

audioRecord.startRecording()
// do something

audioRecord.stop()
audioRecord.release()
xfeCtl.configureXfe(audioManager = am, xfeEnable = false)

Camera

API Document

Angle

  • CameraCharacteristics.SENSOR_ORIENTATION で取得できる Cameraデバイスの角度の取得,変更できます.
  • デフォルトは 90 です.
  • 回転すると,CameraHalが一度再起動しますので,カメラ使用中には実行しないでください.予期せぬ動作をします.
val camAngle = Angle()
if (camAngle.current() != 90) {
    val ret = camAngle.rotate_90()
}
  • また,角度を意識しない場合は,setLandscape, isLandscape, setPortrait, isPortrait をご利用ください.

CameraX拡張機能

CameraX + ThinkletMic

  • CameraX の androidx.camera.video をフォークし,音声周りをカスタマイズできるようにしました.

Note

本機能は,THINKLET App SDKに含みません.サンプルやご利用方法については,thinklet.camerax.mic をご確認ください.

  • 通常のCameraXの Recorder では,マイクに関する機能は,CameraX内部に隠蔽されており,開発者が選ぶことはできません.
    この機能により,例えば,THINKLETの5つのマイクをすべて使い,装着者の音声を強調して録音できます.
    また,次のような音を使用するケースも理論上実現可能です.
    • 「人の声を検出しているときの音」(サンプルあり)
    • 「音声認識し,それを合成音声した音」
    • 「BGMを追加した音」
  • 利用するには,すでにCameraXのRecorderを利用している場合は,ライブラリの導入と,Recorder.BuildersetThinkletMic を追加します.
    • 5chマイクで録音する
    val recorder = Recorder.Builder()
        .setExecutor(recorderExecutor)
        .setQualitySelector(QualitySelector.from(Quality.FHD))
    +   .setThinkletMic(ThinkletMics.FiveCh)
        .build()
    val recorder = Recorder.Builder()
        .setExecutor(recorderExecutor)
        .setQualitySelector(QualitySelector.from(Quality.FHD))
    +   .setThinkletMic(ThinkletMics.Xfe(audioManager))
        .build()

Tip

一部機能については,一般的なAndroidデバイスでも動作できることを確認していますが,積極的なサポートはしておりません.

Gesture

API Document

GestureSensorEventCallback

  • 手を使ったジェスチャを取得,ジェスチャーセンサからのイベントコールバックを提供します.
  • 関数のそれぞれは,THINKLETを装着したときの向きに合わせて,定義し,上下,左右の4つのイベントを取得できます.

GestureSensorManager

  • ジェスチャセンサを簡易的に扱うためのクラス.GestureSensorEventCallbackのイベントを受け取れます.
private val gestureSensorManager =
    GestureSensorManager(object : GestureSensorEventCallback {
        override fun onGestureUpToDown() {
            Log.i(TAG, "onGestureUpToDown")
        }

        override fun onGestureDownToUp() {
            Log.i(TAG, "onGestureDownToUp")
        }

        override fun onGestureRightToLeft() {
            Log.i(TAG, "onGestureRightToLeft")
        }

        override fun onGestureLeftToRight() {
            Log.i(TAG, "onGestureLeftToRight")
        }
    })

fun start() {
    gestureSensorManager.startTracking(context)
}

fun stop() {
    gestureSensorManager.stopTracking()
}

(試験的機能) WearSensorManager

  • THINKLETの装着状態のセンサーイベントを簡易的に扱うためのクラス.
  • 試験的機能となります.利用時には,@OptIn(ExperimentalFeature::class) を付与してください.
  • WearSensorManager.IGyroscopeEvent で,ジャイロセンサーをもとにしたイベントコールバックを提供します.
    • 注意:onSideBlurred は,使い方によっては高頻度で通知されます.
  • WearSensorManager.IProximityEvent で,近接センサーをもとにしたイベントコールバックを提供します.
private val wearSensorManager = WearSensorManager(context)
private val proximityEvent = object: WearSensorManager.IProximityEvent {
    override fun onMounted() {
        Log.i(TAG, "onMounted")
    }

    override fun onRemoved() {
        Log.i(TAG, "onRemoved")
    }

}
private val gyroscopeEvent = object: WearSensorManager.IGyroscopeEvent {
    override fun onUpDownBlurred() {
        Log.i(TAG, "onUpDownBlurred")
    }

    override fun onSideBlurred() {
        Log.i(TAG, "onSideBlurred")
    }
}

fun start() {
    wearSensorManager.startTracking(proximityEvent, gyroscopeEvent)
}

fun stop() {
    wearSensorManager.stopTracking()
}

Launcher Extension

API Document

Extension

  • THINKLET 標準搭載のLauncherが,onResume 実行時に,Launcherの代わりにアプリケーションを起動する機能です.(以降,自動起動モード)
  • Launcherから起動するアプリケーションの設定,取得,自動起動モードの無効化,再有効化する機能を提供します.
  • 自動起動モードは,端末自体が再起動すると,自動的に有効化されます.起動対象の設定は不揮発として保存されますので,端末自体が再起動しても再設定は不要です.
val ext = Extension()
val current = ext.configure() // Pair<String, String> PackageName, className
if (current.first != "com.android.deskclock" || current.second != "com.android.deskclock.DeskClock") {
    ext.configure("com.android.deskclock", "com.android.deskclock.DeskClock")
}

if (!ext.isAutoLaunchMode()) {
    // 再度有効化
    ext.enableAutoLaunchMode()
} else {
    // 無効化
    ext.disableAutoLaunchMode()
}

LED

API Document

LedClient

  • カメラと反対,ジェスチャセンサ側の腕部に搭載する緑LEDのON/OFFを切り替える機能を提供します.
// ON
LedClient(context).updateCameraLed(true)

// OFF
LedClient(context).updateCameraLed(false)

Power

API Document

Power

  • 端末自体をシャットダウン,再起動するための機能を提供します.
  • このAPIを介して,シャットダウン,再起動を行うと,自動起動モードは,無効化され,自動起動モードの対象に設定したアプリは呼び出しされなくなります.上述した通り,端末自体が再起動すると,自動起動モードは,自動的に有効化されます.
Power().shutdown(context, wait = 30000 /* max wait 30s */)
Power().reboot(context, wait = 100 /* soon reboot */)

Language

API Document

Language

  • 端末の言語設定を変更する機能を提供します.
  • 本機能で,切り替え可能な一覧は,getAvailableLocales より取得できます.
val lang = Language(context)
lang.updateRequest(Locale.GERMAN)

開発者モード

API Document

adb

  • adbを有効,無効に切り替える機能を提供します.
  • 開発時などで,一時的に無効にする際は,再度有効にする手段を先に用意してください.
Log.v(TAG, "adb disable -> enable")
val adbClient = AdbClient(context)
adbClient.disableAsync().thenAccept { disableResult ->
    Log.v(TAG, "adb disable $disableResult")
    adbClient.enableAsync().thenAccept { enableResult ->
        Log.v(TAG, "adb enable $enableResult")
    }
}

プロジェクトでの利用方法

GitHub Packages経由

  • 詳細な設定は,GitHub 公開されたパッケージの利用 を参照ください.
  • また,バージョンの指定や依存ライブラリの追加が必要な場合は,Release に記載しておりますので,適宜ご確認ください.
  • 以下に,サンプルを記載します.
    • root build.gradle

      maven {
          name = "GitHubPackages"
          url = uri("https://maven.pkg.github.com/FairyDevicesRD/thinklet.app.sdk")
          credentials {
              Properties properties = new Properties()
              properties.load(project.rootProject.file('local.properties').newDataInputStream())
              username = properties.getProperty("username") ?: System.getenv("USERNAME")
              password = properties.getProperty("token") ?: System.getenv("TOKEN")
          }
      }
      
    • app/build.gradle

      dependencies {
          implementation 'ai.fd.thinklet:sdk-audio:XXX'
          implementation 'ai.fd.thinklet:sdk-gesture:XXX'
          implementation 'ai.fd.thinklet:sdk-led:XXX'
          implementation 'ai.fd.thinklet:sdk-maintenance:XXX'
      }
      // XXX にはVersionを指定ください.とにかく最新を使用する場合は,`+` に置き換えてください.
      

更新方法

  • implementation で指定するVersionを変更してください.
  • その後,プロジェクトをクリーン&ビルドしてください.

Tips

AARのバージョンの確認

  • 各種AARの BuildConfig.VERSION を参照してください.
val msg =
    "${ai.fd.thinklet.sdk.audio.BuildConfig.LIBRARY_PACKAGE_NAME}: ${ai.fd.thinklet.sdk.audio.BuildConfig.VERSION}" + "\n" +
    "${ai.fd.thinklet.sdk.gesture.BuildConfig.LIBRARY_PACKAGE_NAME}: ${ai.fd.thinklet.sdk.gesture.BuildConfig.VERSION}" + "\n" +
    "${ai.fd.thinklet.sdk.led.BuildConfig.LIBRARY_PACKAGE_NAME}: ${ai.fd.thinklet.sdk.led.BuildConfig.VERSION}" + "\n" +
    "${ai.fd.thinklet.sdk.maintenance.BuildConfig.LIBRARY_PACKAGE_NAME}: ${ai.fd.thinklet.sdk.maintenance.BuildConfig.VERSION}"
Log.v(TAG, msg);

プロジェクトを難読化する場合

minifyEnabled

  • minifyEnabled を用いて,SDKに依存するライブラリまで難読化すると,期待する動作をしなくなります.proguard-rules.pro に以下を追記ください.
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+ -keep class  ai.fd.thinklet.syspropmanager.**{ public *;}

開発ロードマップ

  • 開発中・または開発計画をしている機能です.なお,リリースを保証するものではありません.予告なく中止される可能性があります.

    • ネットワーク(Wi-Fi/APN) CRUD API
      • THINKLETのWi-Fi,APNのCRUD(追加・取得・更新・削除)
    • Bluetooth CRUD API
      • THINKLETと接続するBluetooth機器とのペアリング機能
    • (汎用Android向けライブラリ) ローカルTHINKLET操作API
      • THINKLETがオフラインでも,AndroidスマートフォンからTHINKLETを操作するライブラリ