1
+ /*
2
+ * Allegro5 MP3 reader.
3
+ * Requires MiniMP3 from https://github.com/lieff/minimp3
4
+ * author: Mark Watkin (pmprog) 2019
5
+ */
6
+
7
+
8
+ #include "allegro5/allegro.h"
9
+ #include "allegro5/allegro_acodec.h"
10
+ #include "allegro5/allegro_audio.h"
11
+ #include "allegro5/internal/aintern.h"
12
+ #include "allegro5/internal/aintern_audio.h"
13
+ #include "allegro5/internal/aintern_exitfunc.h"
14
+ #include "allegro5/internal/aintern_system.h"
15
+ #include "acodec.h"
16
+ #include "helper.h"
17
+
18
+ #define MINIMP3_IMPLEMENTATION
19
+ #include <minimp3.h>
20
+ #include <minimp3_ex.h>
21
+
22
+ ALLEGRO_DEBUG_CHANNEL ("acodec" )
23
+
24
+ static bool mp3_libinit = false;
25
+ static mp3dec_t mp3d ;
26
+
27
+ void mp3_initminimp3 ();
28
+
29
+ ALLEGRO_SAMPLE * _al_load_mp3 (const char * filename )
30
+ {
31
+ ALLEGRO_FILE * f ;
32
+ ALLEGRO_SAMPLE * spl ;
33
+ ASSERT (filename );
34
+
35
+ f = al_fopen (filename , "rb" );
36
+ if (!f )
37
+ return NULL ;
38
+
39
+ spl = _al_load_mp3_f (f );
40
+
41
+ al_fclose (f );
42
+
43
+ return spl ;
44
+ }
45
+
46
+ ALLEGRO_SAMPLE * _al_load_mp3_f (ALLEGRO_FILE * f )
47
+ {
48
+ mp3_initminimp3 (); // Make sure library is initialised
49
+
50
+ mp3dec_file_info_t info ;
51
+ ALLEGRO_SAMPLE * spl = NULL ;
52
+
53
+ // Read our file size
54
+ int64_t filesize = al_fsize (f );
55
+ if (filesize == -1 )
56
+ return NULL ;
57
+
58
+ // Allocate buffer and read all the file
59
+ size_t fsize = (size_t )al_fsize (f );
60
+ uint8_t * mp3data = (uint8_t * )al_malloc (fsize );
61
+ size_t readbytes = al_fread (f , mp3data , fsize );
62
+ if (readbytes != fsize )
63
+ {
64
+ al_free (mp3data );
65
+ return NULL ;
66
+ }
67
+
68
+ // Decode the file contents, and copy to a new buffer
69
+ mp3dec_load_buf (& mp3d , mp3data , filesize , & info , NULL , NULL );
70
+ uint8_t * pcmdata = (uint8_t * )al_malloc (info .samples * sizeof (int16_t ));
71
+ memcpy (pcmdata , info .buffer , info .samples * sizeof (int16_t ));
72
+
73
+ // Free file copy, and buffer (which is copied to pcmdata
74
+ al_free (mp3data );
75
+ al_free (info .buffer );
76
+
77
+ // Create sample from info variable
78
+ spl = al_create_sample (pcmdata , info .samples , info .hz , _al_word_size_to_depth_conf (2 ), _al_count_to_channel_conf (info .channels ), true);
79
+
80
+ return spl ;
81
+ }
82
+
83
+ ALLEGRO_AUDIO_STREAM * _al_load_mp3_audio_stream (const char * filename , size_t buffer_count , unsigned int samples )
84
+ {
85
+ ALLEGRO_FILE * f ;
86
+ ALLEGRO_AUDIO_STREAM * stream ;
87
+ ASSERT (filename );
88
+
89
+ f = al_fopen (filename , "rb" );
90
+ if (!f )
91
+ return NULL ;
92
+
93
+ stream = _al_load_mp3_audio_stream_f (f , buffer_count , samples );
94
+ if (!stream ) {
95
+ al_fclose (f );
96
+ }
97
+
98
+ return stream ;
99
+ }
100
+
101
+ ALLEGRO_AUDIO_STREAM * _al_load_mp3_audio_stream_f (ALLEGRO_FILE * f , size_t buffer_count , unsigned int samples )
102
+ {
103
+ mp3_initminimp3 (); // Make sure library is initialised
104
+ return NULL ;
105
+ }
106
+
107
+ void mp3_initminimp3 ()
108
+ {
109
+ if (!mp3_libinit )
110
+ {
111
+ mp3dec_init (& mp3d );
112
+ mp3_libinit = true;
113
+ }
114
+ }
0 commit comments