mirror of
https://github.com/openharmony/third_party_lame.git
synced 2026-07-01 05:53:58 -04:00
283 lines
5.7 KiB
C++
283 lines
5.7 KiB
C++
// LAME test program
|
|
//
|
|
// Copyright (c) 2010 Robert Hegemann
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Library General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Library General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Library General Public
|
|
// License along with this library; if not, write to the
|
|
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
// Boston, MA 02111-1307, USA.
|
|
|
|
#include <lame.h>
|
|
#include <wchar.h>
|
|
#include <stdlib.h>
|
|
|
|
|
|
class PcmGenerator
|
|
{
|
|
float* m_buffer_ch0;
|
|
float* m_buffer_ch1;
|
|
int m_size;
|
|
float m_a;
|
|
float m_b;
|
|
|
|
static double random()
|
|
{
|
|
int const range_max = 32768;
|
|
int const range_min = -32767;
|
|
return (double)rand() / (RAND_MAX + 1) * (range_max - range_min) + range_min;
|
|
}
|
|
|
|
PcmGenerator( PcmGenerator const& );
|
|
PcmGenerator& operator = ( PcmGenerator const& );
|
|
|
|
public:
|
|
|
|
explicit PcmGenerator(int size)
|
|
{
|
|
m_size = size >= 0 ? size : 0;
|
|
m_buffer_ch0 = new float [m_size];
|
|
m_buffer_ch1 = new float [m_size];
|
|
m_a = 0;
|
|
m_b = 0;
|
|
advance(0);
|
|
}
|
|
|
|
~PcmGenerator()
|
|
{
|
|
delete[] m_buffer_ch0;
|
|
delete[] m_buffer_ch1;
|
|
}
|
|
|
|
float const* ch0() const { return m_buffer_ch0; }
|
|
float const* ch1() const { return m_buffer_ch1; }
|
|
|
|
void advance( int x ) {
|
|
float a = m_a;
|
|
float b = m_b;
|
|
for (int i = 0; i < m_size; ++i) {
|
|
a += 10;
|
|
if (a > 32768) a = random();
|
|
b -= 10;
|
|
if (b < -32767) b = random();
|
|
m_buffer_ch0[i] = a;
|
|
m_buffer_ch1[i] = b;
|
|
}
|
|
m_a = a;
|
|
m_b = b;
|
|
}
|
|
};
|
|
|
|
class OutFile
|
|
{
|
|
FILE* m_file_handle;
|
|
|
|
public:
|
|
OutFile()
|
|
: m_file_handle(0)
|
|
{}
|
|
|
|
explicit OutFile(wchar_t const* filename)
|
|
: m_file_handle(0)
|
|
{
|
|
m_file_handle = _wfopen(filename, L"wb");
|
|
}
|
|
|
|
~OutFile()
|
|
{
|
|
close();
|
|
}
|
|
|
|
bool isOpen() const {
|
|
return 0 != m_file_handle;
|
|
}
|
|
|
|
void close() {
|
|
if (isOpen()) {
|
|
fclose(m_file_handle);
|
|
m_file_handle = 0;
|
|
}
|
|
}
|
|
|
|
void write(unsigned char const* data, int n) {
|
|
fwrite(data, 1, n, m_file_handle);
|
|
}
|
|
};
|
|
|
|
class Lame
|
|
{
|
|
lame_t m_gf;
|
|
bool m_init_params_called;
|
|
|
|
void ensureInitialized() {
|
|
if (isOpen()) {
|
|
if (!m_init_params_called) {
|
|
m_init_params_called = true;
|
|
lame_init_params(m_gf);
|
|
}
|
|
}
|
|
}
|
|
|
|
public:
|
|
|
|
Lame()
|
|
: m_gf( lame_init() )
|
|
, m_init_params_called( false )
|
|
{}
|
|
|
|
~Lame()
|
|
{
|
|
close();
|
|
}
|
|
|
|
void close() {
|
|
if (isOpen()) {
|
|
lame_close(m_gf);
|
|
m_gf = 0;
|
|
}
|
|
}
|
|
|
|
bool isOpen() const {
|
|
return m_gf != 0;
|
|
}
|
|
|
|
operator lame_t () const {
|
|
return m_gf;
|
|
}
|
|
|
|
void setInSamplerate( int rate ) {
|
|
lame_set_in_samplerate(m_gf, rate);
|
|
}
|
|
|
|
void setOutSamplerate( int rate ) {
|
|
lame_set_out_samplerate(m_gf, rate);
|
|
}
|
|
|
|
void setNumChannels( int num_channel ) {
|
|
lame_set_num_channels(m_gf, num_channel);
|
|
}
|
|
|
|
int encode(float const* ch0, float const* ch1, int n_in, unsigned char* out_buffer, int m_out_free) {
|
|
ensureInitialized();
|
|
return lame_encode_buffer_float(m_gf, ch0, ch1, n_in, out_buffer, m_out_free);
|
|
}
|
|
|
|
int flush(unsigned char* out_buffer, int m_out_free) {
|
|
ensureInitialized();
|
|
return lame_encode_flush(m_gf, out_buffer, m_out_free);
|
|
}
|
|
|
|
int getLameTag(unsigned char* out_buffer, int m_out_free) {
|
|
ensureInitialized();
|
|
return lame_get_lametag_frame(m_gf, out_buffer, m_out_free);
|
|
}
|
|
|
|
};
|
|
|
|
class OutBuffer
|
|
{
|
|
unsigned char* m_data;
|
|
int m_size;
|
|
int m_used;
|
|
|
|
OutBuffer( OutBuffer const& );
|
|
OutBuffer& operator = ( OutBuffer const& );
|
|
|
|
public:
|
|
|
|
OutBuffer()
|
|
{
|
|
m_size = 1000 * 1000;
|
|
m_data = new unsigned char[ m_size ];
|
|
m_used = 0;
|
|
}
|
|
|
|
~OutBuffer()
|
|
{
|
|
delete[] m_data;
|
|
}
|
|
|
|
void advance( int i ) {
|
|
m_used += i;
|
|
}
|
|
|
|
int used() const {
|
|
return m_used;
|
|
}
|
|
|
|
int unused() const {
|
|
return m_size - m_used;
|
|
}
|
|
|
|
unsigned char* current() { return m_data + m_used; }
|
|
unsigned char* begin() { return m_data; }
|
|
};
|
|
|
|
void generateFile(wchar_t const* filename, size_t n)
|
|
{
|
|
int const chunk = 1152;
|
|
PcmGenerator src(chunk);
|
|
|
|
OutFile mp3_stream( filename );
|
|
if (!mp3_stream.isOpen()) return;
|
|
|
|
Lame lame;
|
|
if (!lame.isOpen()) return;
|
|
|
|
OutBuffer mp3_stream_buffer;
|
|
int rc = 0;
|
|
|
|
lame.setInSamplerate(44100);
|
|
lame.setOutSamplerate(44100);
|
|
lame.setNumChannels(2);
|
|
|
|
while (n > 0) {
|
|
int const m = n < chunk ? n : chunk;
|
|
if ( n < chunk ) n = 0; else n -= chunk;
|
|
rc = lame.encode(src.ch0(), src.ch1(), m, mp3_stream_buffer.current(), mp3_stream_buffer.unused());
|
|
wprintf(L"rc=%d %d %d\n",rc,mp3_stream_buffer.used(),mp3_stream_buffer.unused());
|
|
if (rc < 0) return;
|
|
mp3_stream_buffer.advance( rc );
|
|
src.advance(m);
|
|
}
|
|
|
|
rc = lame.flush(mp3_stream_buffer.current(), mp3_stream_buffer.unused());
|
|
wprintf(L"flush rc=%d\n",rc);
|
|
if (rc < 0) return;
|
|
|
|
mp3_stream_buffer.advance( rc );
|
|
|
|
int lametag_size = lame.getLameTag(0,0);
|
|
wprintf(L"lametag_size=%d\n",lametag_size);
|
|
|
|
rc = lame.getLameTag(mp3_stream_buffer.begin(), lametag_size);
|
|
wprintf(L"rc=%d\n",rc);
|
|
if (rc < 0) return;
|
|
|
|
mp3_stream.write(mp3_stream_buffer.begin(), mp3_stream_buffer.used());
|
|
|
|
lame.close();
|
|
}
|
|
|
|
int wmain(int argc, wchar_t** argv)
|
|
{
|
|
if (argc != 3) {
|
|
wprintf(L"usage: %ws <filename> <number pcm samples>\n", argv[0]);
|
|
return -1;
|
|
}
|
|
wprintf(L"open file %ws\n", argv[1]);
|
|
int n = _wtoi(argv[2]);
|
|
wprintf(L"synthesize %d samples long mp3 file\n",n);
|
|
generateFile(argv[1], n);
|
|
return 0;
|
|
}
|