pcm文件播放

/*
This example reads standard from input and writes
to the default PCM device for 5 seconds of data.
*/

/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <stdio.h>  
#include <stdlib.h> 
#include <string> 
#include "alsa/asoundlib.h"

int main()
{

    snd_pcm_uframes_t periodsize;  
    int rc;
    int size;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    unsigned int val;
    int dir;
    snd_pcm_uframes_t frames;
    char *buffer;


    //lhm add
    std::string filename = "3.pcm";
    FILE* fp = fopen(filename.c_str(), "rb");
     if(fp == NULL)  
         return 0;  
        fseek(fp, 100, SEEK_SET);  



    /* Open PCM device for playback. */
    rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
    if (rc < 0)
    {
        fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc));
        exit(1);
    }

    /* Allocate a hardware parameters object. */
//  rc = snd_pcm_hw_params_alloca(&params);
    rc = snd_pcm_hw_params_malloc(&params);
    if(rc < 0)
    {
        perror("snd_pcm_hw_params_malloc");  
            exit(1);    
    }
    /* Fill it in with default values. */
    rc = snd_pcm_hw_params_any(handle, params);
    if(rc < 0)
    {
        perror("snd_pcm_hw_params_any");  
            exit(1); 
    }
    /* Set the desired hardware parameters. */
    /* Interleaved mode */
    rc = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    if (rc < 0) {  
            perror("snd_pcm_hw_params_set_access");  
            exit(1);  
        } 

    /* Signed 16-bit little-endian format */
    rc = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
    if (rc < 0) {  
            perror("snd_pcm_hw_params_set_format");  
            exit(1);  
     }

    /* 8000 bits/second sampling rate (CD quality) */
    val = 8000;
    rc = snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);
    if (rc < 0) {  
            perror("snd_pcm_hw_params_set_rate_near");  
            exit(1);  
    }

    /* One channels (mono) */
    rc = snd_pcm_hw_params_set_channels(handle, params, 1);
    if (rc < 0) {  
            perror("snd_pcm_hw_params_set_channels");  
            exit(1);  
        }         


    /* Set period size to 32 frames. */
    frames = 480;
    periodsize = frames * 2;
    rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &periodsize); 
    if (rc < 0)   
        {  
            printf("Unable to set buffer size %li : %s\n", frames * 2, snd_strerror(rc));      
        }
    periodsize /= 2;
    rc = snd_pcm_hw_params_set_period_size_near(handle, params, &periodsize, 0);
    if(rc < 0)
    {
        printf("Unable to set period size %li : %s\n", periodsize,  snd_strerror(rc));  
    }
    /* Write the parameters to the driver */
    rc = snd_pcm_hw_params(handle, params);
    if (rc < 0) {
        fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));
        exit(1);
    }
    /* Use a buffer large enough to hold one period */
    snd_pcm_hw_params_get_period_size(params, &frames, &dir);


    size = frames * 2; /* 2 bytes/sample, 1 channels */
    buffer = (char *)malloc(size);
        fprintf(stderr,  
            "size = %d\n",  
            size);  


    /* We want to loop for 5 seconds */
    //snd_pcm_hw_params_get_period_time(params, &val, &dir);

    /* 5 seconds in microseconds divided by
    * period time */
    while (1) //Ñ­»·ÂŒÒô 5 s
    {

//      rc = read(0, buffer, size);
        rc = fread(buffer, 1, size, fp);
        if (rc == 0) 
        {
            fprintf(stderr, "end of file on input\n");
            break;
        }
        else if (rc != size)
        {
            fprintf(stderr, "short read: read %d bytes\n", rc);
        }

        rc = snd_pcm_writei(handle, buffer, frames);//
        if (rc == -EPIPE)
        {
            /* EPIPE means underrun */
    //      fprintf(stderr, "underrun occurred\n");
            snd_pcm_prepare(handle);
        }
        else if (rc < 0) {
            fprintf(stderr, "error from writei: %s\n", snd_strerror(rc));
        }
        else if (rc != (int)frames) {
            fprintf(stderr, "short write, write %d frames\n", rc);
        }
    }

    snd_pcm_drain(handle);
    snd_pcm_close(handle);

    free(buffer);

    return 0;

}
TARGET = new3

CROSS_COMPILE = /home/lhm/Desktop/new_board/gcc/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-

CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILR)ar

CXXFLAGS = -g -Wall -I /home/lhm/Desktop/new_board/rtfs/usr/include 
LDFLAGS = -g -Wall -L /home/lhm/Desktop/new_board/rtfs/usr/lib


ARCH = arm

$(TARGET) : new3.o
    $(CXX) -o $@ $(LDFLAGS) $^ -lasound

new3.o : new3.c
    $(CXX) $(CXXFLAGS) -c $^ -o $@ 


.PHONY:clean
clean:
    rm -f $(TARGET) *.o 

猜你喜欢

转载自blog.csdn.net/u012323667/article/details/79486838