5aaf4136bf
Usage: device /dev/audio/compress0p play /data/test.sbc This function requires the platform to support compress decoding and playback Signed-off-by: shipei <shipei@xiaomi.com>
214 lines
6.6 KiB
C
214 lines
6.6 KiB
C
/****************************************************************************
|
|
* apps/system/nxplayer/nxplayer_sbc.c
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you 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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <nuttx/audio/audio.h>
|
|
|
|
#include "system/nxplayer.h"
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#define SBC_SYNC_WORD 0x9C
|
|
#define SBC_AM_LOUDNESS 0x00
|
|
#define SBC_AM_SNR 0x01
|
|
#define SBC_FRAME_HEADER_SIZE 32
|
|
|
|
/****************************************************************************
|
|
* Private Type Declarations
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* SBC frame header
|
|
* syncword 8 BsMsbf
|
|
* sampling_frequency 2 UiMsbf
|
|
* blocks 2 UiMsbf
|
|
* channel_mode 2 UiMsbf
|
|
* allocation_method 1 UiMsbf
|
|
* subbands 1 UiMsbf
|
|
* bitpool 8 UiMsbf
|
|
* crc_check 8 UiMsbf
|
|
****************************************************************************/
|
|
|
|
struct sbc_frame_header
|
|
{
|
|
uint8_t syncword;
|
|
uint32_t sampling_frequency;
|
|
uint8_t blocks;
|
|
uint8_t nchannels;
|
|
uint8_t allocation_method;
|
|
uint8_t subbands;
|
|
uint8_t bitpool;
|
|
uint8_t crc_check;
|
|
uint8_t reserve;
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* SBC header bits define
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* sampling_frequency
|
|
* bits rate(HZ)
|
|
* 00 16000
|
|
* 01 32000
|
|
* 10 44100
|
|
* 11 48000
|
|
****************************************************************************/
|
|
|
|
static const uint32_t g_sampling_freq[4] =
|
|
{
|
|
16000, 32000, 44100, 48000
|
|
};
|
|
|
|
/****************************************************************************
|
|
* blocks
|
|
* bits nrof_blocks
|
|
* 00 4
|
|
* 01 8
|
|
* 10 12
|
|
* 11 16
|
|
****************************************************************************/
|
|
|
|
static const uint8_t g_nblocks[4] =
|
|
{
|
|
4, 8, 12, 16
|
|
};
|
|
|
|
/****************************************************************************
|
|
* channel mode
|
|
* bits channel mode channel numbers
|
|
* 00 MONO 1
|
|
* 01 DUAL_CHANNEL 2
|
|
* 10 STEREO 2
|
|
* 11 JOINT_STEREO 2
|
|
****************************************************************************/
|
|
|
|
static const uint8_t g_nchannels[4] =
|
|
{
|
|
1, 2, 2, 2
|
|
};
|
|
|
|
/****************************************************************************
|
|
* allocation_method
|
|
* bits allocation_method
|
|
* 0 LOUDNESS
|
|
* 1 SNR
|
|
****************************************************************************/
|
|
|
|
static const uint8_t g_allocation_method[2] =
|
|
{
|
|
SBC_AM_LOUDNESS, SBC_AM_SNR
|
|
};
|
|
|
|
/****************************************************************************
|
|
* subbands
|
|
* bits nrof_subbands
|
|
* 0 4
|
|
* 1 8
|
|
****************************************************************************/
|
|
|
|
static const uint8_t g_nsubbands[2] =
|
|
{
|
|
4, 8
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Functions
|
|
****************************************************************************/
|
|
|
|
static void init_sbc_frame_header(FAR struct sbc_frame_header *sbc,
|
|
FAR char *buffer)
|
|
{
|
|
sbc->syncword = buffer[0];
|
|
sbc->sampling_frequency = g_sampling_freq[buffer[1] >> 6];
|
|
sbc->blocks = g_nblocks[buffer[1] >> 4 & 0x03];
|
|
sbc->nchannels = g_nchannels[buffer[1] >> 2 & 0x03];
|
|
sbc->allocation_method = g_allocation_method[buffer[1] >> 1 & 0x01];
|
|
sbc->subbands = g_nsubbands[buffer[1] & 0x01];
|
|
sbc->bitpool = buffer[2];
|
|
sbc->crc_check = buffer[3];
|
|
sbc->reserve = 0;
|
|
}
|
|
|
|
static int check_sbc_frame_header_info(FAR struct sbc_frame_header *sbc)
|
|
{
|
|
if (sbc->syncword != SBC_SYNC_WORD)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: nxplayer_parse_sbc
|
|
*
|
|
* nxplayer_parse_sbc() parse sbc header, get samplerate, channels, bps.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int nxplayer_parse_sbc(int fd, FAR uint32_t *samplerate,
|
|
FAR uint8_t *chans, FAR uint8_t *bps)
|
|
{
|
|
char buffer[SBC_FRAME_HEADER_SIZE];
|
|
struct sbc_frame_header sbc;
|
|
int ret = OK;
|
|
|
|
ret = read(fd, buffer, SBC_FRAME_HEADER_SIZE);
|
|
if (ret < SBC_FRAME_HEADER_SIZE)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
init_sbc_frame_header(&sbc, buffer);
|
|
ret = check_sbc_frame_header_info(&sbc);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
*samplerate = sbc.sampling_frequency;
|
|
*chans = sbc.nchannels;
|
|
*bps = 16;
|
|
lseek(fd, 0, SEEK_SET);
|
|
|
|
return ret;
|
|
}
|