1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#include "cbrr.h"
#include <alsa/asoundlib.h>
#include <mpg123.h>
#include <stdio.h>
#include <stdlib.h>
#define PCM_DEVICE "default"
void brr_c(char *filename) {
// Initialize the MPG123 library
mpg123_init();
mpg123_handle *mh = mpg123_new(NULL, NULL);
if (mpg123_open(mh, filename) != MPG123_OK) {
fprintf(stderr, "Error opening %s: %s\n", filename, mpg123_strerror(mh));
return;
}
// Retrieve the format of the MP3 file
long rate;
int channels, encoding;
if (mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) {
fprintf(stderr, "Error getting format: %s\n", mpg123_strerror(mh));
return;
}
// Set the output format
snd_pcm_t *pcm_handle;
snd_pcm_hw_params_t *params;
int pcm, dir;
snd_pcm_uframes_t frames;
char *buffer;
int size;
// Open the PCM device
if (pcm = snd_pcm_open(&pcm_handle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0) <
0) {
fprintf(stderr, "Error opening PCM device %s: %s\n", PCM_DEVICE,
snd_strerror(pcm));
return;
}
// Allocate hardware parameters object
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(pcm_handle, params);
// Set the desired hardware parameters
snd_pcm_hw_params_set_access(pcm_handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(pcm_handle, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(pcm_handle, params, channels);
snd_pcm_hw_params_set_rate_near(pcm_handle, params, &rate, &dir);
// Write the parameters to the driver
if (pcm = snd_pcm_hw_params(pcm_handle, params) < 0) {
fprintf(stderr, "Error setting HW params: %s\n", snd_strerror(pcm));
return;
}
// Use a buffer large enough to hold one period
snd_pcm_hw_params_get_period_size(params, &frames, &dir);
size = frames * channels * 2; // 2 bytes/sample, 2 channels
buffer = (char *)malloc(size);
// Decode and play the MP3 file
size_t buffer_size = mpg123_outblock(mh);
unsigned char *mpg123_buffer =
(unsigned char *)malloc(buffer_size * sizeof(unsigned char));
size_t done;
int err;
while ((err = mpg123_read(mh, mpg123_buffer, buffer_size, &done)) ==
MPG123_OK) {
snd_pcm_writei(pcm_handle, mpg123_buffer, done / 4);
}
// Clean up
free(buffer);
free(mpg123_buffer);
snd_pcm_drain(pcm_handle);
snd_pcm_close(pcm_handle);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
return;
}
|