用力宝播放音频文件

弗罗茨

我试图使一个简单的C程序播放AIFF或WAV文件。根据我在http://www.xiph.org/ao/doc/上看到的内容,这应该可以工作,但是无论我输入什么文件,它都会发出嗡嗡声。这怎么了

/* compile with "gcc -o playme playme.c -lao -ldl -lm" */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>

ao_device *device;
ao_sample_format format;

int main(int argc, char *argv[])
{
    int default_driver;
    char *buffer;
    unsigned long count;

    FILE *fp;

    if (argc != 2) {
    printf("usage: %s <filename>\n", argv[0]);
    exit(1);
    }

    ao_initialize();
    default_driver = ao_default_driver_id();
    memset(&format, 0, sizeof(format));

    format.bits = 16;
    format.channels = 2;
    format.rate = 44100;
    format.byte_format = AO_FMT_LITTLE;

    device = ao_open_live(default_driver, &format, NULL /* no options */);
    if (device == NULL) {
        printf("Error opening sound device.\n");
        exit(1);
    }

    fp = fopen(argv[1], "rb");
    if (fp == NULL) {
    printf("Cannot open %s.\n", argv[1]);
    exit(2);
    }

    fseek(fp, 0, SEEK_END);
    count = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    fread(buffer, sizeof(char), count, fp);
    ao_play(device, buffer, count);
    ao_close(device);
    ao_shutdown();

    return 0;
}
弗罗茨

我没有意识到的一个关键问题是,libao绝对不解码。因此,程序员应在打开音频设备之前提取样本大小,速率,通道等,并将其馈送到libao。libsndfile可用于执行此操作,但是如果您只想快速又脏一些,请使用下面的代码来播放AIFF文件:

/* compile with "gcc -o playaiff playaiff.c -lao -ldl -lm" */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ao/ao.h>
#include <math.h>

#define MAXCHAN 8

ao_device *device;
ao_sample_format format;

#define gshort( b) (((int)((b)[0]) << 8) + (int)((b)[1]))
#define glong( b) (((int)((b)[0]) << 24) + ((int)((b)[1]) << 16) +\
        ((int)((b)[2]) << 8) + (int)((b)[3]))

typedef struct {
    short     channels;
    short     samplesize;
    int   samplerate;
    unsigned long samplecount;
    int       valid;
} aiffinfo;

aiffinfo getaiffinfo(FILE *);
static int IeeeExtendedToLong(unsigned char *);

int main(int argc, char *argv[])
{
    int default_driver;
    char *buffer;

    aiffinfo info;

    FILE *fp;

    if (argc != 2) {
    printf("usage: %s <filename>\n", argv[0]);
    exit(1);
    }

    ao_initialize();
    default_driver = ao_default_driver_id();
    memset(&format, 0, sizeof(format));

    fp = fopen(argv[1], "rb");
    if (fp == NULL) {
    printf("Cannot open %s.\n", argv[1]);
    exit(2);
    }

    info = getaiffinfo(fp);

    if (!info.valid) {
    printf("Invalid AIFF file.\n");
    exit(1);
    }

    format.bits = info.samplesize;
    format.channels = info.channels;
    format.rate = info.samplerate;
    format.byte_format = AO_FMT_LITTLE;

    device = ao_open_live(default_driver, &format, NULL /* no options */);
    if (device == NULL) {
        printf("Error opening sound device.\n");
        exit(1);
    }

    buffer = malloc(sizeof(char) * info.samplecount);

    fread(buffer, sizeof(char), info.samplecount, fp);
    ao_play(device, buffer, info.samplecount);
    ao_close(device);
    ao_shutdown();

    return 0;
}


aiffinfo getaiffinfo(FILE *fp)
{
    int size;
    int len;
    int offset;
    int blocksize;
    int found = 0;
    unsigned char chunk[18];
    unsigned char fid[4];
    aiffinfo info;

    info.samplesize = 0;
    info.valid = 0;

    if (fread(chunk, 1, 4, fp) < 4) return info;
    if (memcmp(chunk,"FORM",4)) return info;
    if (fread(chunk, 1, 4, fp) < 4)  return info;
    size = glong(chunk);
    if (size & 1) size++;
    if (size < 20) return info;
    if (fread(chunk, 1, 4, fp) < 4) return info;
    if (memcmp(chunk, "AIFF", 4)) return info;

    size -= 4;
    while (size > 8) {
    if (fread(fid, 1, 4, fp) < 4) return info;    // chunck id
    if (fread(chunk, 1, 4, fp) < 4) return info;    // and len
    size -= 8;
    len = glong(chunk);
    if (len < 0) return info;
    if (len & 1) len++;
    size -= len;
    if (size < 0) return info;
    if (memcmp(fid, "COMM", 4) == 0) {
        if (len != 18) return info;
        if (fread(chunk, 1, 18, fp) < 18) return info;
        info.channels = gshort(chunk);
        if (info.channels < 1) return info;
        if (info.channels > MAXCHAN) return info;
        info.samplecount = glong(chunk+2);
        if (info.samplecount < 1) return info;
        info.samplerate = IeeeExtendedToLong(chunk + 8);
        if (info.samplerate <= 0) return info;
        info.samplesize = gshort(chunk + 6);
        if (info.samplesize < 1 || info.samplesize > 16) return info;
    } else if (memcmp(fid,"SSND",4)==0){
        if (!info.channels) return info;
        if (fread(chunk, 1, 4, fp) < 4) return info;
        offset = glong(chunk);
        if (fread(chunk, 1, 4, fp) < 4) return info;
        blocksize = glong(chunk);
        if (blocksize) return info;
        if (offset) fseek(fp, offset,SEEK_CUR);
        found = 1;
        break;
    } else fseek (fp, len, SEEK_CUR);
    }

    if (!found) return info;
    if (!info.channels) return info;

//    printf("Looks good so far.\n");
    info.valid = 1;
    return info;
}


/****************************************************************
 * Extended precision IEEE floating-point conversion routine.
 ****************************************************************/

#ifndef Uint32
#define Uint32 unsigned int
#endif
#ifndef HUGE_INT32
#define HUGE_INT32 0x7fffffff
#endif                                          /* HUGE_VAL */

static int IeeeExtendedToLong( unsigned char *bytes)
{
    int f = 0;
    int expon;
    Uint32 hiMant;
    Uint32 loMant;

    expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
    hiMant = ((Uint32) (bytes[2] & 0xFF) << 24)
    | ((Uint32) (bytes[3] & 0xFF) << 16)
    | ((Uint32) (bytes[4] & 0xFF) << 8)
    | ((Uint32) (bytes[5] & 0xFF));
    loMant = ((Uint32) (bytes[6] & 0xFF) << 24)
    | ((Uint32) (bytes[7] & 0xFF) << 16)
    | ((Uint32) (bytes[8] & 0xFF) << 8)
    | ((Uint32) (bytes[9] & 0xFF));

    if (expon == 0 && hiMant == 0 && loMant == 0) f = 0;
    else if (expon == 0x7FFF) f = HUGE_INT32;
    else {
    expon -= 16382;
    expon = 32-expon;
    if (expon < 0) f = HUGE_INT32;
    else f = hiMant >> expon;
    }

    if (bytes[0] & 0x80)
    return -f;
    else
    return f;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

星号,如何播放音频文件

来自分类Dev

从目录快速播放音频文件

来自分类Dev

用golang播放音频文件

来自分类Dev

悬停播放音频文件

来自分类Dev

如何播放音频文件?

来自分类Dev

Android播放音频文件(.wav)

来自分类Dev

Smartface:如何播放音频文件?

来自分类Dev

如何播放音频文件?

来自分类Dev

显示和播放音频文件

来自分类Dev

如何获取播放音频文件的音频路径?

来自分类Dev

如何获取播放音频文件的音频路径?

来自分类Dev

播放音频文件数据-Spring MVC

来自分类Dev

在很短的时间后多次播放音频文件?

来自分类Dev

如何从跨平台的Haskell代码播放音频文件

来自分类Dev

在Django应用中播放音频文件?

来自分类Dev

计算播放音频文件时剩下的时间

来自分类Dev

使用AVAudioEngine反复播放音频文件

来自分类Dev

如何在键盘按键上播放音频文件?

来自分类Dev

在WatchKit OS2中播放音频文件

来自分类Dev

如何使用Matlab在特定间隔播放音频文件?

来自分类Dev

播放音频文件时找不到'PathForResource'的重载

来自分类Dev

无法在Vue Web应用中播放音频文件

来自分类Dev

轻按时如何创建播放音频文件的通知?

来自分类Dev

颤动的声音无法播放音频文件

来自分类Dev

Java通过命令行播放音频文件

来自分类Dev

如何填充ListView和播放音频文件

来自分类Dev

顺序播放音频文件不起作用

来自分类Dev

如何在键盘按键上播放音频文件?

来自分类Dev

在onclick事件中播放音频文件