解决中标麒麟下SDL无法打开音频设备的问题:
root登录
首先就是一定要用root登录,这个可能是权限问题,否则后面实验不能成功
安装ALSA库
首先下载alsa-lib:https://www.alsa-project.org/main/index.php/Main_Page
tar -jxvf alsa-lib-1.1.2.tar.bz2
cd alsa-lib-1.1.2
./configure
make && make install
这样alsa-lib库就安装好了,不需要去管安装到哪里,系统自动安装了,测试时发现使用此版本库在播放音频时会出现:ALSA lib pcm.c:8251:(snd_pcm_recover) underrun occurred
此时音频播放会断断续续,怀疑是安装alsa-lib的版本太低了,于是换到了alsa-lib-1.2.2,就可以正常播放了
测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL2/SDL.h"
static unsigned char *pAudio_chunk;
static unsigned int audio_len;
static unsigned char *pAudio_pos;
void fill_audio_buffer(void *userdata, Uint8 * stream, int len)
{
SDL_memset(stream, 0, len);
// 判断是否有读到数据
if (audio_len == 0)
return;
len = (len > audio_len ? audio_len : len);
SDL_MixAudio(stream, pAudio_pos, len, SDL_MIX_MAXVOLUME);
pAudio_pos += len;
audio_len -= len;
}
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER))
{
printf("Initialize SDL failed: %s\n", SDL_GetError());
return -1;
}
/*** 初始化初始化SDL_AudioSpec结构体 ***/
SDL_AudioSpec audioSpec;
audioSpec.freq = 44100; // 音频数据的采样率。常用的有48000,44100等
audioSpec.format = AUDIO_S16SYS; // 音频数据的格式
audioSpec.channels = 2; // 声道数。例如单声道取值为1,立体声取值为2
audioSpec.silence = 0; // 设置静音的值
audioSpec.samples = 1024; // 音频缓冲区中的采样个数,要求必须是2的n次方
audioSpec.callback = fill_audio_buffer; // 填充音频缓冲区的回调函数
// 打开音频设备
if (SDL_OpenAudio(&audioSpec, NULL) < 0)
{
printf("Can not open audio!");
return -1;
}
printf("Open audio success!\n");
return 0;
}
MakeFile
############################################################
# main makefile
############################################################
############################################################
# Target setting
############################################################
TARGET_DEMO = sdl_test
TOP_DIR = .
BIN_DIR = $(TOP_DIR)/.bin
OBJ_DIR = $(TOP_DIR)/.obj
SRC_DIR = $(TOP_DIR)
TPARTY_DIR = $(TOP_DIR)/../install/x86/SDL2/lib
INC_DIR = $(TOP_DIR)/../install/x86/SDL2/include
############################################################
# Project options
############################################################
INCLUDES += \
-I$(INC_DIR)
LIBINCLUDES += \
-L$(TPARTY_DIR)
LINK_LIBRARIES += \
-lSDL2 -lm -ldl -lpthread -lrt
VPATH := \
./
SRCS_CPP :=
SRCS_C :=
SRCS_DEMO_CPP := \
$(SRCS_CPP)
SRCS_DEMO_C := \
$(SRCS_C) \
main.c
############################################################
# Compiler
############################################################
CXX = g++
CC = gcc
LINKXX = g++
LINK = gcc
AR = $(CROSS_PREFIX)ar -r
AS = $(CROSS_PREFIX)as
LD = $(CROSS_PREFIX)ld
MAKE = make
SUBMAKE = $(MAKE) --no-print-directory -f
PY = python
SED = sed
MKDIR = mkdir -p
CP = cp
RM = rm -f
MV = mv
ECHO = echo
CXXFLAGS += -O3 -Wall -std=c++11
CFLAGS += -O3 -Wall
############################################################
# build rules
############################################################
CC_TITLE = @$(ECHO) "==> Compiling $@ "
LINK_TITLE = @$(ECHO) "==> Linking $(BIN_DIR)/$@ "
CXXFLAGS += $(INCLUDES)
CFLAGS += $(INCLUDES)
define MK_OBJ_DIR
if test ! -d $(OBJ_DIR); then $(MKDIR) $(OBJ_DIR); fi
endef
define MK_BIN_DIR
if test ! -d $(BIN_DIR); then $(MKDIR) $(BIN_DIR); fi
endef
$(OBJ_DIR)/%.o: %.cpp
$(CC_TITLE)
@$(MK_OBJ_DIR)
@$(CXX) -o $@ -c $(CXXFLAGS) $<
$(OBJ_DIR)/%.o: %.c
$(CC_TITLE)
@$(MK_OBJ_DIR)
@$(CC) -o $@ -c $(CFLAGS) $<
OBJS_C = $(patsubst %.c, $(OBJ_DIR)/%.o, $(SRCS_C))
OBJS_CPP = $(patsubst %.cpp, $(OBJ_DIR)/%.o, $(SRCS_CPP))
OBJS_DEMO_C = $(patsubst %.c, $(OBJ_DIR)/%.o, $(SRCS_DEMO_C))
OBJS_DEMO_CPP = $(patsubst %.cpp, $(OBJ_DIR)/%.o, $(SRCS_DEMO_CPP))
############################################################
# make target
############################################################
all: $(TARGET_DEMO)
$(TARGET_DEMO):$(OBJS_DEMO_CPP) $(OBJS_DEMO_C)
@$(LINK_TITLE)
@$(MK_BIN_DIR)
@$(LINK) $^ -o $(BIN_DIR)/$(TARGET_DEMO) $(LIBINCLUDES) $(LINK_LIBRARIES)
.PHONY:install clean distclean
install:
@$(MKDIR) install/$(CROSS_NAME)/include
@$(CP) -rf include/* install/$(CROSS_NAME)/include
@$(MKDIR) install/$(CROSS_NAME)/lib
@if [ -e $(BIN_DIR)/$(TARGET_SO) ]; then $(CP) -f $(BIN_DIR)/$(TARGET_SO) install/$(CROSS_NAME)/lib;fi
@if [ -e $(BIN_DIR)/$(TARGET_A) ]; then $(CP) -f $(BIN_DIR)/$(TARGET_A) install/$(CROSS_NAME)/lib;fi
@if [ -e $(BIN_DIR)/$(TARGET_DEMO) ]; then $(MKDIR) install/$(CROSS_NAME)/sbin; $(CP) -f $(BIN_DIR)/$(TARGET_DEMO) install/$(CROSS_NAME)/sbin; fi
clean:
@$(RM) -r $(OBJ_DIR) $(BIN_DIR)
distclean:
@$(RM) -r $(OBJ_DIR) $(BIN_DIR)
运行的时候一定要在前面加上SDL_AUDIODRIVER=alsa
SDL_AUDIODRIVER=alsa ./sdl_test