当前位置: 首页 > news >正文

从playfield开源代码复制的opensl es初始化代码

从playfield开源代码复制的opensl es初始化代码

/* -*- coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*- *//** Copyright (c) 2025, Awe Morris. All rights reserved.*//** HAL for OpenSL ES on Android*//* Base */
#include "stratohal/platform.h"/* OpenSLES */
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>/* POSIX */
#include <pthread.h>
#include <sys/types.h>/* C */
#include <stdlib.h>
#include <string.h>
#include <math.h>/** sound Buffer Parameters*/
#define SAMPLING_RATE        (44100)
#define CHANNELS        (2)
#define FRAME_SIZE        (4)
#define BUF_FRAMES        (SAMPLING_RATE / 4)/** OpenSL ES Objects*/
static SLObjectItf engine_object;
static SLEngineItf engine_engine;
static SLObjectItf output_mix_object;
static SLObjectItf bq_player_object[SOUND_TRACKS];
static SLPlayItf bq_player_play[SOUND_TRACKS];
static SLAndroidSimpleBufferQueueItf bq_player_buffer_queue[SOUND_TRACKS];/* Buffers */
static uint32_t sample_buf[SOUND_TRACKS][BUF_FRAMES];/* Mutex objects to synchronize accesses to sample_buf */
static pthread_mutex_t sound_mutex[SOUND_TRACKS];/* Input Streams */
static struct wave *wave[SOUND_TRACKS];/* Volume Values */
static float volume[SOUND_TRACKS];/* Finish Flags */
static bool pre_finish[SOUND_TRACKS];     /* Shows if we reached an end-of-stream. */
static bool post_finish[SOUND_TRACKS];     /* Shows if we finished a playback of a final buffer. *//** Forward Declarations*/
static void play_callback(SLAndroidSimpleBufferQueueItf bq, void *context);
static void enqueue(int stream);
static void scale_samples(uint32_t *buf, int frames, float vol);/** Initialize OpenSL ES.*/
void init_opensl_es(void)
{for (int i = 0; i < SOUND_TRACKS; i++)pthread_mutex_init(&sound_mutex[i], NULL);slCreateEngine(&engine_object, 0, NULL, 0, NULL, NULL);(*engine_object)->Realize(engine_object, SL_BOOLEAN_FALSE);(*engine_object)->GetInterface(engine_object, SL_IID_ENGINE, &engine_engine);const SLInterfaceID outids[1] = {SL_IID_PLAYBACKRATE};const SLboolean outreq[1] = {SL_BOOLEAN_FALSE};(*engine_engine)->CreateOutputMix(engine_engine, &output_mix_object, 1, outids, outreq);(*output_mix_object)->Realize(output_mix_object, SL_BOOLEAN_FALSE);SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,2,SL_SAMPLINGRATE_44_1,SL_PCMSAMPLEFORMAT_FIXED_16,SL_PCMSAMPLEFORMAT_FIXED_16,SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,SL_BYTEORDER_LITTLEENDIAN};SLDataSource audio_src = {&loc_bufq, &format_pcm};SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, output_mix_object};SLDataSink audioSnk = {&loc_outmix, NULL};const SLInterfaceID bqids[1] = {SL_IID_BUFFERQUEUE};const SLboolean bqreq[1] = {SL_BOOLEAN_TRUE};for (int i = 0; i < SOUND_TRACKS; i++) {(*engine_engine)->CreateAudioPlayer(engine_engine, &bq_player_object[i], &audio_src, &audioSnk, 1, bqids, bqreq);(*bq_player_object[i])->Realize(bq_player_object[i], SL_BOOLEAN_FALSE);(*bq_player_object[i])->GetInterface(bq_player_object[i], SL_IID_PLAY, &bq_player_play[i]);(*bq_player_object[i])->GetInterface(bq_player_object[i], SL_IID_BUFFERQUEUE, &bq_player_buffer_queue[i]);(*bq_player_buffer_queue[i])->RegisterCallback(bq_player_buffer_queue[i], play_callback, (void *)(intptr_t)i);(*bq_player_play[i])->SetCallbackEventsMask(bq_player_play[i], SL_PLAYEVENT_HEADATEND);(*bq_player_play[i])->SetPlayState(bq_player_play[i], SL_PLAYSTATE_PLAYING);}
}void sl_pause_sound(void)
{for (int i = 0; i < SOUND_TRACKS; i++) {if (bq_player_play[i] != NULL)(*bq_player_play[i])->SetPlayState(bq_player_play[i], SL_PLAYSTATE_STOPPED);}
}void sl_resume_sound(void)
{for (int i = 0; i < SOUND_TRACKS; i++) {if (bq_player_play[i] != NULL)(*bq_player_play[i])->SetPlayState(bq_player_play[i], SL_PLAYSTATE_PLAYING);}
}static void play_callback(SLAndroidSimpleBufferQueueItf bq, void *context)
{int stream = (intptr_t)context;pthread_mutex_lock(&sound_mutex[stream]);enqueue(stream);pthread_mutex_unlock(&sound_mutex[stream]);
}static void enqueue(int stream)
{if (wave[stream] == NULL)return;/* Set a post-finish flag if an end-of-stream was detected in a previous filling. */if (pre_finish[stream]) {wave[stream] = NULL;post_finish[stream] = true;return;}/* Get PCM samples. */int read_samples = get_wave_samples(wave[stream], sample_buf[stream], BUF_FRAMES);/* Fill the remaining samples by zeros for a case where we have reached an end-of-stream. */if (read_samples < BUF_FRAMES)memset(sample_buf[stream] + read_samples, 0, (size_t)(BUF_FRAMES - read_samples) * FRAME_SIZE);/* Scale samples by a volume value. */scale_samples(sample_buf[stream], BUF_FRAMES, volume[stream]);/* Write the buffer. */(*bq_player_buffer_queue[stream])->Enqueue(bq_player_buffer_queue[stream], sample_buf[stream], read_samples * FRAME_SIZE);/* Set a pre-finish flag if we reached an end-of-stream. */if (is_wave_eos(wave[stream]))pre_finish[stream] = true;
}static void scale_samples(uint32_t *buf, int frames, float vol)
{float scale;uint32_t frame;int32_t il, ir;    /* intermediate L/R */int16_t sl, sr;    /* source L/R*/int16_t dl, dr;    /* destination L/R */int i;__sync_synchronize();/* Convert a scale factor to an exponential value. */scale = (powf(10.0f, vol) - 1.0f) / (10.0f - 1.0f);/* Scale samples. */for (i = 0; i < frames; i++) {frame = buf[i];sl = (int16_t)(uint16_t)frame;sr = (int16_t)(uint16_t)(frame >> 16);il = (int)(sl * scale);ir = (int)(sr * scale);il = il > 32767 ? 32767 : il;il = il < -32768 ? -32768 : il;ir = ir > 32767 ? 32767 : ir;ir = ir < -32768 ? -32768 : ir;dl = (int16_t)il;dr = (int16_t)ir;buf[i] = ((uint32_t)(uint16_t)dl) | (((uint32_t)(uint16_t)dr) << 16);}
}/** HAL*/bool play_sound(int stream, struct wave *w)
{if (bq_player_play[stream] == NULL)return true;pthread_mutex_lock(&sound_mutex[stream]);{wave[stream] = w;pre_finish[stream] = false;post_finish[stream] = false;enqueue(stream);}pthread_mutex_unlock(&sound_mutex[stream]);return true;
}bool stop_sound(int stream)
{if (bq_player_play[stream] == NULL)return true;pthread_mutex_lock(&sound_mutex[stream]);{wave[stream] = NULL;pre_finish[stream] = false;post_finish[stream] = false;}pthread_mutex_unlock(&sound_mutex[stream]);return true;
}bool set_sound_volume(int stream, float vol)
{volume[stream] = vol;__sync_synchronize();return true;
}bool is_sound_finished(int stream)
{__sync_synchronize();if (!post_finish[stream])return false;return true;
}

 

http://www.hskmm.com/?act=detail&tid=32094

相关文章:

  • 第九届电气、机械与计算机工程国际学术会议(ICEMCE 2025)
  • 2025 年螺带混合机优质厂家最新推荐排行榜:聚焦综合实力、产品性能与服务质量的权威筛选榜单
  • P2151 HH 去散步
  • 2025年钢结构建材厂家最新推荐排行榜,彩钢瓦,镀锌板,折弯件,C型钢,Z型钢,压型瓦,楼承板,钢结构安装,次檩条公司推荐
  • 2025年发电机组厂家最新权威推荐榜:柴油/燃气/船用/静音箱式/移动拖车/集装箱发电机组,上柴/玉柴/潍柴/康明斯/沃尔沃/道依茨/帕金斯/MTU品牌全覆盖
  • 2025年铣刀厂家最新权威推荐榜:雕刻机铣刀/金刚石铣刀/木工铣刀/绝缘材料铣刀/碳纤维铣刀/亚克力铣刀/金属加工铣刀/铝合金铣刀/石墨铣刀/不锈钢铣刀/金属切削铣刀/电木铣刀/塑胶铣刀/PC铣刀
  • 2025年下半年权威信息公布:西安学区房/书包房/五大名校/交大书包新楼盘口碑推荐榜前十强出炉,高得房率/推荐好房/地铁口/小高层/低总价/低单价/高性价比/高赠送/四代宅
  • 第六届大数据、人工智能与物联网工程国际会议(ICBAIE 2025)
  • .NET 10中GC(垃圾收集器)更新
  • 【转】扫盲:Windows桌面应用开发框架:原生、跨平台、云桌面
  • vxe-table v4版本使用注意事项
  • ​​电容瞬态放电原理:大电流的产生机制深度解析​
  • Chrome浏览器离线版下载,谷歌(Google)浏览器离线安装包下载,手机版,Mac版,window版都有,不上网也可以安装
  • 基于Java+Springboot+Vue开发的在线摄影预约管理系统源码+运行步骤
  • 2025 年超微粉碎机厂家最新推荐榜:聚焦企业专利技术、品质管控及知名客户合作案例的权威解析
  • 若干树形dpの总结
  • 2025 年最新推荐!国内冷库厂商综合实力排行榜出炉,涵盖冷冻 / 装配式 / 超低温等多类型冷库解决方案
  • 2025 年景观石厂家最新推荐榜单:千层石 / 泰山石 / 鹅卵石等各类石材企业全面盘点,助力客户精准选择优质景观石品牌
  • python之函数
  • 剑指offer-35、数组中的逆序对
  • 2025 年最新推荐!西宁种植牙医院推荐榜单:助您精准选靠谱口腔机构
  • 2025 年太阳能厂家最新推荐:全场景系统企业综合实力榜,含热水 / 发电 / 光伏热等领域优质品牌测评
  • 苦逼,通宵肝了两个月!测试开发导航网站终于上线了!
  • 鸿蒙应用开发从入门到实战(二十三):一文搞懂ArkUI弹性布局
  • 2025 金属复合板厂家最新推荐排行榜:实力厂家产能定制服务全景解析,选购指南必备
  • CCPC2024成都 游记(VP) 未完成以及一些找补的话
  • CF1439C Greedy Shopping
  • 完整教程:AI应用生成平台:数据库、缓存与存储
  • CCPC2022绵阳 游记(VP)
  • 2025 年电缆桥架生产厂家最新推荐排行榜:含北方 / 河北 / 瓦楞 / 防火 / 模压 / 镀锌桥架品牌及合作案例盘点