libmad mp3 decode example code

音频压缩算法(MP3) 阅读详情
/*
 * libmad - MPEG audio decoder library
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: minimad.c,v 1.4 2004/01/23 09:41:32 rob Exp $
 */

# include <stdio.h>
# include <unistd.h>
# include <sys/stat.h>
# include <sys/mman.h>

# include "mad.h"

/*
 * This is perhaps the simplest example use of the MAD high-level API.
 * Standard input is mapped into memory via mmap(), then the high-level API
 * is invoked with three callbacks: input, output, and error. The output
 * callback converts MAD's high-resolution PCM samples to 16 bits, then
 * writes them to standard output in little-endian, stereo-interleaved
 * format.
 */

static int decode(unsigned char const *, unsigned long);

int main(int argc, char *argv[])
{
  struct stat stat;
  void *fdm;

  if (argc != 1)
    return 1;

  if (fstat(STDIN_FILENO, &stat) == -1 ||
      stat.st_size == 0)
    return 2;

  fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);
  if (fdm == MAP_FAILED)
    return 3;

  decode(fdm, stat.st_size);

  if (munmap(fdm, stat.st_size) == -1)
    return 4;

  return 0;
}

/*
 * This is a private message structure. A generic pointer to this structure
 * is passed to each of the callback functions. Put here any data you need
 * to access from within the callbacks.
 */

struct buffer {
  unsigned char const *start;
  unsigned long length;
};

/*
 * This is the input callback. The purpose of this callback is to (re)fill
 * the stream buffer which is to be decoded. In this example, an entire file
 * has been mapped into memory, so we just call mad_stream_buffer() with the
 * address and length of the mapping. When this callback is called a second
 * time, we are finished decoding.
 */

static
enum mad_flow input(void *data,
            struct mad_stream *stream)
{
  struct buffer *buffer = data;

  if (!buffer->length)
    return MAD_FLOW_STOP;

  mad_stream_buffer(stream, buffer->start, buffer->length);

  buffer->length = 0;

  return MAD_FLOW_CONTINUE;
}

/*
 * The following utility routine performs simple rounding, clipping, and
 * scaling of MAD's high-resolution samples down to 16 bits. It does not
 * perform any dithering or noise shaping, which would be recommended to
 * obtain any exceptional audio quality. It is therefore not recommended to
 * use this routine if high-quality output is desired.
 */

static inline
signed int scale(mad_fixed_t sample)
{
  /* round */
  sample += (1L << (MAD_F_FRACBITS - 16));

  /* clip */
  if (sample >= MAD_F_ONE)
    sample = MAD_F_ONE - 1;
  else if (sample < -MAD_F_ONE)
    sample = -MAD_F_ONE;

  /* quantize */
  return sample >> (MAD_F_FRACBITS + 1 - 16);
}

/*
 * This is the output callback function. It is called after each frame of
 * MPEG audio data has been completely decoded. The purpose of this callback
 * is to output (or play) the decoded PCM audio.
 */

static
enum mad_flow output(void *data,
             struct mad_header const *header,
             struct mad_pcm *pcm)
{
  unsigned int nchannels, nsamples;
  mad_fixed_t const *left_ch, *right_ch;

  /* pcm->samplerate contains the sampling frequency */

  nchannels = pcm->channels;
  nsamples  = pcm->length;
  left_ch   = pcm->samples[0];
  right_ch  = pcm->samples[1];

  while (nsamples--) {
    signed int sample;

    /* output sample(s) in 16-bit signed little-endian PCM */

    sample = scale(*left_ch++);
    putchar((sample >> 0) & 0xff);
    putchar((sample >> 8) & 0xff);

    if (nchannels == 2) {
      sample = scale(*right_ch++);
      putchar((sample >> 0) & 0xff);
      putchar((sample >> 8) & 0xff);
    }
  }

  return MAD_FLOW_CONTINUE;
}

/*
 * This is the error callback function. It is called whenever a decoding
 * error occurs. The error is indicated by stream->error; the list of
 * possible MAD_ERROR_* errors can be found in the mad.h (or stream.h)
 * header file.
 */

static
enum mad_flow error(void *data,
            struct mad_stream *stream,
            struct mad_frame *frame)
{
  struct buffer *buffer = data;

  fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
      stream->error, mad_stream_errorstr(stream),
      stream->this_frame - buffer->start);

  /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */

  return MAD_FLOW_CONTINUE;
}

/*
 * This is the function called by main() above to perform all the decoding.
 * It instantiates a decoder object and configures it with the input,
 * output, and error callback functions above. A single call to
 * mad_decoder_run() continues until a callback function returns
 * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and
 * signal an error).
 */

static
int decode(unsigned char const *start, unsigned long length)
{
  struct buffer buffer;
  struct mad_decoder decoder;
  int result;

  /* initialize our private message structure */

  buffer.start  = start;
  buffer.length = length;

  /* configure input, output, and error functions */

  mad_decoder_init(&decoder, &buffer,
           input, 0 /* header */, 0 /* filter */, output,
           error, 0 /* message */);

  /* start decoding */

  result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);

  /* release the decoder */

  mad_decoder_finish(&decoder);

  return result;
}

libmad的移植、交叉编译、安装——基于ubuntu16 这篇文章主要介绍了libmad的安装过程,目的在于方便其他人更快捷有效的使用libmad,减少产品开发时间和周期。涉及到嵌入式Linux下的库安装过程,总结了安装过程中的经验和遇到的麻烦。 阅读详情

相关推荐

STM32H750音乐播放器开发全解析:从硬件架构到软件实现

在嵌入式系统开发中,音频处理是一个常见且具有挑战性的应用场景,它涉及数字信号处理、实时数据传输和硬件协同工作等多个核心概念。其基本原理是通过微控制器对音频文件进行解码,生成PCM数字音频流,再通过专用接口传输至音频编解码芯片进行数模转换。这项技术的价值在于能够实现高质量的本地音频播放,广泛应用于智能家居、便携设备和工业控制等领域。以STM32H750高性能单片机为例,其内置的SAI、I2S接口和强大的处理能力,为音频播放器开发提供了理想的硬件平台。通过结合FATFS文件系统和DMA双缓冲机制,可以高效实现从

weixin_29178069的博客 260

基于MM32实现音频播放系统的应用实例

其中,libmad是一个开源的高精度MPEG音频解码库,是专门面向嵌入式应用的MP3解码程序,可以简单地实现MP3数据解码工作,支持MPEG-1、MPEG-2,以及MPEG-2.5标准,它可以提供24位PCM输出,用定点运算模拟浮点运算,因此不需要处理器有浮点运算功能,非常适合没有浮点支持的平台上使用;WAV支持多种音频数字、采样频率和声道,标准格式化的WAV文件和CD的格式一样,也是44.1kHz的采样频率、16位量化数据,具有真实记录声音波形的特点,基本无数据压缩,所以数据体量也变得相对大些。

guoruibin123的博客 242

stm32 libmad helix MP3软解移植

STM32软解MP3的移植工程,艰难找到了两种解码库libmad 和 helix。资料里面也有具体的资料,请大家支持

MP3解码入门(基于libhelix)

这个函数用于初始化MP3解码器,创建一个解码器实例,并返回一个句柄(HMP3Decoder),该句柄在后续的解码过程中被用来引用这个解码器实例。此函数用于释放先前通过MP3InitDecoder创建的MP3解码器实例。它接受解码器句柄作为参数,并释放与之关联的所有资源。这个函数是MP3解码的核心,它将MP3编码的数据(inbuf)解码成PCM格式的音频(outbuf)。inbuf是一个指向输入缓冲区的指针的指针,解码器会更新这个指针以指向未处理的输入数据。

qq_40773212的博客 3694

libmad helixMP3软解

利用libmad helix的MP3软解代码,里面还有一些相关的材料。

基于stm32 libmad MP3软解码库移植教程

目前,网络上绝大都数关于MP3播放器的例子,大都采用vs1003这颗硬件解码芯片或者使用AT89C51SND1C这颗含有内部音频解码电路的NB单片机,软件音频解码的例子少之又少。我花了些时间、精力,研究了目前linux领域很常用的一个开源音频解码库——libmad的解码流程,并将其成功移植到裸奔的stm32平台上。本着资源共享的奉献精神,我将移植过程整理成手册,发布于网络,希望对大家有用。

libmad使用一步步进阶

原文地址:http://my.oschina.net/mjRao/blog/57874 libmad是一个开源mp3解码库,其对mp3解码算法做了很多优化,性能较好,很多播放器如mplayer、xmms等都是使用这个开源库进行解码的;如果要设计mp3播放器而又不想研究mp3解码算法的话,libmad是个不错的选择,可是问题来了: libmad配套的相关文档太少,可以说几乎没有,只有一个示例程...

系统运维 778

HelixMP3Decoder及中文移植手册

Helix MP3 解码,全定点运算,可广泛移植多种嵌入式平台,包含中文移植手册,可快速掌握移植接口,可选择编译 ARM 平台汇编优化,仅支持MPEG-1 Audio Layer III。

探索嵌入式音频新境界:STM32 MP3软解移植工程

探索嵌入式音频新境界:STM32 MP3软解移植工程 【下载地址】STM32MP3软解移植工程 本仓库提供了一个STM32平台上MP3软解的移植工程,包含了两种常用的解码库:libmad 和 helix。通过本工程,您可以在STM32平台上实现MP3音频文件的软解码功能 ...

gitblog_09725的博客 674

MP3软件解码库

本文件为MP3软件解码,讲文件解压后全部复制到APP文件夹下,接口文件为mp3dec.c 具体内容自己查看!

stm32F103RET+WM8978+Helix软解播放MP3

使用Helix库软解播放MP3,效果还可以。 MP3文件支持标准的采用率(27000这种非标准采样率不支持),支持CBR与VBR 主芯片使用STM32F103RET,STM32F103VET,STM32F103ZET及更高RAM的芯片 SD卡仅支持FAT32文件格式(exFAT不支持) 不支持长文件名,只支持8.3文件名格式,不支持中文文件名 播放的音频文件需要放在\music目录下

libmad与mplayer的交叉编译过程

我用的交叉编译器是arm-linux-gcc 4.3.2   首先先编译libmad ./configure --enable-fpm=arm --host=arm-linux CC=arm-linux-gcc --disable-debugging   然后编译mplayer ./configure    --host-cc=gcc    --cc=arm-none-linu

helloworldprogram的专栏 754

从AP到ADSP:高通8650 AudioReach中GSL-Passthru-GPR的数据通路剖析

本文深入剖析了高通骁龙8650平台AudioReach架构中,音频数据从应用处理器(AP)到音频数字信号处理器(ADSP)的完整传输路径。重点解析了GSL(Graph Service Layer)如何封装命令,并通过Passthru驱动与GPR(Generic Packet Router)协同工作,实现跨处理器的高效、异步数据交换,揭示了现代手机复杂音频系统背后的核心通信机制。

cherry的博客 536

【亲测免费】 在STM32上实现MP3软解码:一个开源的移植工程

在STM32上实现MP3软解码:一个开源的移植工程 【下载地址】STM32MP3软解移植工程 本仓库提供了一个STM32平台上MP3软解的移植工程,包含了两种常用的解码库:libmad 和 helix。通过本工程,您可以在STM32平台上实现MP3音频文件的软解码功能 ...

gitblog_09714的博客 1098

无线自组织网络基础知识

参考书籍:《无线自组织网络路由协议及应用》 目录第一章 绪论1.1 无线自组织网络概述1.1.1 无线自组织网络的定义及分类1.1.2无线自组织网络的主要特点1.1.3无线自组织网络的应用与发展1.无线自组织网络的应用2.无线自组织网络的起源和发展1.2典型的无线自组织网络1.2.1移动Ad Hoc网络1、移动Ad Hoc网络的定义2.移动AdHoc网络的特点3.移动Ad Hoc网络的应用1.2....

逸凌Time 2万+

COMSOL报错调试总结(不定期更新)

COMSOL报错调试总结1. 可定位错误1.1 除零错误1.2 未定义变量值1.3 边界条件/材料属性等缺失2. 难定位错误2.1. 装配期间内存不足 官方给的案例总是非常完美,运行流畅,结果完美。但是自己做模型时候就总是报错,而且不像自己coding的程序那样可以明确定位哪里出了bug。这里把我碰到的一些报错问题以及调试方法记录下来~ 部分来源于以下参考来源: http://wap.sciencenet.cn/blog-1467490-1118453.html?mobile=1 1. 可定位错误 以下错误

jessica0307的博客 8万+

Libmad开源MP3解码库的使用_铽可喏_新浪博客

MAD(libmad)是一个开源的高精度MPEG音频解码库。libmad提供24-bit的PCM输出,完全定点计算。使用libmad提供的一系列API可以实现MP3文件的解码。 libmad通过回调函数机制来实现解码,当mad_decoder_init初始化完成后,程序执行 mad_decoder_run,这时候程序就会不断调...

tekenuo的专栏 2441

【屠龙之术】SAP 欧洲公司 高级合规性报表 FEC

所谓FEC ,其实是法国税务局要求法国的公司,每年要向税务局进行提交的税务报告,这个报告有特殊的格式,进行加密,法国公司要在收到税务局通知以后,及时进行报送,如果不报送,或者报送不合格文件,将面临5000欧的罚款。-----------------------------------------------进入正文----------------------------------------------------------------------有专门的T-code,PPT我就不贴了,我直接截图。

竹大的博客 1955

Helix MP3 解码器在cortex m4应用

Helix MP3 解码器在cortex m4应用 Helix MP3 解码器可浮点和定点实现。该算法可运行在任意 32 位定点处理器上,并完全使用 C 语言编码,可选择用优化的汇编指令替换某些代码段。 Helix MP3 解码器提供对 MPEG-1、 MPEG-2 和 MPEG-2.5的第 3 层 (Layer 3)支持。它支持可变位速率、恒定位速率,以及立体声和单声道音频格式。 下图是一...

Quard_D的博客 4996

STM32(H7)学习记录-14 XSPI连接DDR SDRAM(HyperBus)

主控芯片是STM32H7S7 ,HyperBusRAM芯片是W956D8MBYA5I。*DQS0(这个引脚是作为RWDS)使用的CubeMX版本是6.13.0。

m0_71918616的博客 1071

BugkuCTF-PWN题pwn2-overflow超详细讲解

解题思路 1)计算出get_shell_的地址偏移量 2)算出来之后就直接溢出到后门函数 知识点 x64函数调用规则 解题之前我们先学下linux x64的函数调用规则。 x64机器在调用某个函数前,比如int func(int a, int b, int c, int d, int e, int f, int g, int h),首先他会把前6个参数从左往右存入到寄存器rdi、rsi、rdx、rcx、r8、r9,其余参数存入到栈里,保存的顺序是从右往左入栈。比如abcdef会存入到寄存器里,然后一次入栈h

am_03的博客 3013

libmad的使用 mp3解码 实现套路

硬件环境: imx6ul 自制电路板 本次中使用到了cs4344和pt12913(这两个没啥说的一个i2s,一个i2c但是蛮好用的)。 软件: linux 3.14.10(好像是,记不清了) libmad 0.15.1b 最大的感觉是这玩意蛮方便,但是使用过程中还是被他坑了一波(其实说到底还是自己太水)。 在这里吐槽一下我司,项目经理和产品实在是比较无力,没啥说的。 最差的端午。2天...

spark550的博客 3014

从稀疏表示到低秩表示(一)

确定研究方向后一直在狂补理论,最近看了一些文章,有了些想法,顺便也总结了representation系列的文章,由于我刚接触,可能会有些不足,愿大家共同指正。 从稀疏表示到低秩表示系列文章包括如下内容: 一、 sparse representation 二、 一、 sparse representation 1  sparsity  一个线性表示解决的问题如下图所示:

彼岸花 3万+

platform_set_drvdata() platform_get_drvdata()

内核模块一般在probe()函数中动态申请内存来使用,这种情况下,这个指针就得有个位置存储防止丢失, 所以内核设计得在platform_device结构体中,保留了一个指针,就是为了这样的驱动编写方式。 所以我们一般在probe()函数中 动态申请设备结构体,并初始化它,然后使用platform_set_drvdata()将其保存到platform_device中, 在需要使用的时候再使用

烟台 嵌入式产品开发 1万+

拯救者Y9000P 2022双系统实战:Ubuntu22.04分区优化与驱动避坑指南

本文提供联想拯救者Y9000P 2022款安装Ubuntu 22.04双系统的详细实战指南。重点讲解针对该机型的磁盘分区优化方案、NVIDIA显卡驱动安装避坑技巧,以及安装后的网络、时间同步等必备配置,帮助用户高效完成双系统部署并提升使用体验。

weixin_29208327的博客 421

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

上一篇: x264 encode example code
下一篇: input core输入事件 矩阵键盘 映射 原理分析
Yantai666
博客等级 码龄15年 45粉丝 271原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值