示例#1
0
/**
 * Play one step of the buffer
 */
int play_step_music_buffer(music_buffer_t *music_buf)
{
    size_t ret = 0;
    if (lock_music_buffer(music_buf)) return 1;
    MY_READ(music_buf->info.file, music_buf->buf, music_buf->buf_size);
    size_t bytes = ret;
    if (bytes == 0) {
        if (!feof(music_buf->info.file)) {
            unlock_music_buffer(music_buf);
            return 0;
        } else {
            fprintf(stderr, "An error occured while reading the file.\n");
            unlock_music_buffer(music_buf);
            return 1;
        }
    }
    unlock_music_buffer(music_buf);
    ret = write(music_buf->fd_dsp,  music_buf->buf, bytes);
    // An error may happen when stopping playback
    if (ret != bytes && music_buf->playing) {
        fprintf(stderr, "Writing to the sound device failed.\n");
        return 2;
    }
    return 0;
}
示例#2
0
/**
 * Open a music file in AU or WAVE format
 * Please call fclose(file_info->file) to free the file descriptor
 */
int open_music_file(const char *file_name, music_file_t *file_info)
{
    // Open file
    file_info->file = fopen (file_name, "rb");
    if (file_info->file == NULL) {
        fprintf(stderr, "Couldn't open the file!\n");
        return 2;
    }

    // Look for magic number to determine file type
    int ret;
    uint32_t magic_number;
    MY_READ(file_info->file, & magic_number, sizeof(magic_number));
    magic_number = ntohl (magic_number);

    if (magic_number == 0x52494646) {
        // Seems to be a RIFF file. Try to see if it's a WAVE one.
        ret = wave_opener(file_info);
    } else if (magic_number == 0x2e736e64) {
        // Decode file header
        ret = au_opener(file_info);
    } else {
        fprintf(stderr, "File format not recognized.\n");
        fclose(file_info->file);
        return 2;
    }

    if (ret) {
        fprintf(stderr, "Header parsing failed! File may have been corrupted.\n");
        fclose(file_info->file);
        return 2;
    }

    return 0;
}
static ssize_t
fullRead (int fd, char *buf, size_t count)
// Retry partial or EAGAIN writes until count is completely written.
{
    size_t bytesread = 0;
    while (bytesread < count) {
        ssize_t rv = MY_READ (fd, buf+bytesread, count-bytesread);
        if (rv < 0) {
            if ((errno == EAGAIN) || (errno == EINTR)) {
                continue;
            }

            return rv;
        }
        else if (rv == 0) {
            return bytesread;
        }

        bytesread += rv;
    }

    assert (bytesread == count);
    return bytesread;
}
示例#4
0
/**
 * Read info in WAV files.
 */
int wave_opener(music_file_t * file_info)
{
    // Apart from the magic numbers, the RIFF spec says that everything
    // is stored in little-endian.

    int ret = 0;
    FILE * file = file_info -> file;

    uint32_t file_size;
    MY_READ(file, & file_size, sizeof(file_size));
    file_size = U32_TO_LE(file_size);
    file_size += 8;
    printf("[WAV] File size: %u.\n", file_size);

    uint32_t magic_number;
    MY_READ(file, & magic_number, sizeof(magic_number));
    magic_number = ntohl (magic_number);
    if (magic_number != 0x57415645) {
        fprintf(stderr, "This RIFF file not a WAVE file.\n");
        return 1;
    }

    uint32_t magic_number_header;
    MY_READ(file, & magic_number_header, sizeof(magic_number_header));
    magic_number_header = ntohl (magic_number_header);
    if (magic_number_header != 0x666d7420) {
        fprintf(stderr, "WAVE file ERROR: no header!!\n");
        return 1;
    }

    uint32_t header_size;
    MY_READ(file, & header_size, sizeof(header_size));
    header_size = U32_TO_LE (header_size);
    printf("[WAV] Header size: %u.\n", header_size);

    uint16_t encoding;
    MY_READ(file, & encoding, sizeof(encoding));
    encoding = U16_TO_LE (encoding);
    printf("[WAV] WAVE encoding format: %u.\n", encoding);
    if (encoding != 1) {
        fprintf(stderr, "Encoding not supported. Sorry...\n");
        return 1;
    }

    uint16_t channels;
    MY_READ(file, & channels, sizeof(channels));
    channels = U16_TO_LE (channels);
    printf("[WAV] Nb of channels: %u.\n", channels);
    file_info -> channels = channels;

    uint32_t sample_rate;
    MY_READ(file, & sample_rate, sizeof(sample_rate));
    sample_rate = U32_TO_LE (sample_rate);
    printf("[WAV] Sample rate: %u.\n", sample_rate);
    file_info -> sample_rate = sample_rate;

    uint32_t byte_rate;
    MY_READ(file, & byte_rate, sizeof(byte_rate));
    byte_rate = U32_TO_LE (byte_rate);
    printf("[WAV] Byte rate: %u.\n", byte_rate);

    uint16_t block_align;
    MY_READ(file, & block_align, sizeof(block_align));
    block_align = U16_TO_LE (block_align);
    printf("[WAV] Block size: %u.\n", block_align);

    uint16_t bits_per_sample;
    MY_READ(file, & bits_per_sample, sizeof(bits_per_sample));
    bits_per_sample = U16_TO_LE (bits_per_sample);
    printf("[WAV] Bits per sample: %u.\n", bits_per_sample);
    file_info -> bits_per_sample = bits_per_sample;

    uint_fast32_t oss_format;
    switch (bits_per_sample) {
        case 8:
            oss_format = AFMT_U8;
            break;

        case 16:
            oss_format = AFMT_S16_LE;
            break;

        default:
            fprintf(stderr, "This value of bits per sample not supported. Sorry...\n");
            return 1;
    }
    file_info -> oss_format = oss_format;

    // Header sanity checks
    if (block_align != channels * bits_per_sample / 8 ||
        (uint_fast32_t) block_align * sample_rate != byte_rate) {
        fprintf(stderr, "WAVE file error: Internal inconsistency in the header.\n");
        return 1;
    }

    uint32_t magic_number_data;
    MY_READ(file, & magic_number_data, sizeof(magic_number_data));
    magic_number_data = ntohl (magic_number_data);
    if (magic_number_data != 0x64617461) {
        fprintf(stderr, "WAVE file ERROR: no data.\n");
        return 1;
    }

    uint32_t data_size;
    MY_READ(file, & data_size, sizeof(data_size));
    data_size = U32_TO_LE (data_size);
    printf("[WAV] Data size: %u.\n",data_size);
    file_info -> data_size = data_size;

    return 0;
}
示例#5
0
/**
 * Read informations in AU files
 */
int au_opener(music_file_t * file_info)
{
    int ret;
    FILE * file = file_info -> file;

    uint32_t header_size;
    MY_READ(file, & header_size, sizeof(header_size));
    header_size = ntohl (header_size);
    printf("[AU] Header size: %u.\n", header_size);

    uint32_t data_size;
    MY_READ(file, & data_size, sizeof(data_size));
    data_size = ntohl (data_size);
    printf("[AU] Data size: %u.\n",data_size);
    file_info -> data_size = data_size;

    uint32_t encoding;
    MY_READ(file, & encoding, sizeof(encoding));
    encoding = ntohl (encoding);

    unsigned oss_format;
    uint_fast32_t bits_per_sample;
    switch (encoding) {
        case 2:
            bits_per_sample = 8;
            oss_format = AFMT_S8;
            printf("[AU] Encoding format: Signed 8-bit.\n");
            break;

        case 3:
            bits_per_sample = 16;
            oss_format = AFMT_S16_BE;
            printf("[AU] Encoding format: Signed 16-bit.\n");
            break;

        default:
            printf("[AU] Encoding format: %u.\n", encoding);
            fprintf(stderr, "Encoding not supported. Sorry...\n");
            return 1;
    }
    file_info -> bits_per_sample = bits_per_sample;
    file_info -> oss_format = oss_format;

    uint32_t sample_rate;
    MY_READ(file, & sample_rate, sizeof(sample_rate));
    sample_rate = ntohl (sample_rate);
    printf("[AU] Sample rate: %u.\n", sample_rate);
    file_info -> sample_rate = sample_rate;

    uint32_t channels;
    MY_READ(file, & channels, sizeof(channels));
    channels = ntohl (channels);
    printf("[AU] Nb of channels: %u.\n", channels);
    file_info -> channels = channels;

    // Position the cursor to the beginning of the data section
    if (fseek(file, header_size, SEEK_SET) == -1) {
        perror("fseek");
        return 2;
    }

    return 0;
}