From 044303c98dc22972891be239e7341dc271baf605 Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Thu, 13 Sep 2007 00:33:25 +0000 Subject: [PATCH] *** empty log message *** --- doc/html/documentation_example_code.html | 81 +++++++ examples/c/encode/Makefile.am | 18 ++ examples/c/encode/file/Makefile.am | 28 +++ examples/c/encode/file/Makefile.lite | 39 ++++ .../c/encode/file/example_c_encode_file.dsp | 100 +++++++++ .../encode/file/example_c_encode_file.vcproj | 204 ++++++++++++++++++ examples/c/encode/file/main.c | 173 +++++++++++++++ examples/cpp/encode/Makefile.am | 18 ++ examples/cpp/encode/file/Makefile.am | 28 +++ examples/cpp/encode/file/Makefile.lite | 41 ++++ .../encode/file/example_cpp_encode_file.dsp | 100 +++++++++ .../file/example_cpp_encode_file.vcproj | 204 ++++++++++++++++++ examples/cpp/encode/file/main.cpp | 175 +++++++++++++++ 13 files changed, 1209 insertions(+) create mode 100644 doc/html/documentation_example_code.html create mode 100644 examples/c/encode/Makefile.am create mode 100644 examples/c/encode/file/Makefile.am create mode 100644 examples/c/encode/file/Makefile.lite create mode 100644 examples/c/encode/file/example_c_encode_file.dsp create mode 100644 examples/c/encode/file/example_c_encode_file.vcproj create mode 100644 examples/c/encode/file/main.c create mode 100644 examples/cpp/encode/Makefile.am create mode 100644 examples/cpp/encode/file/Makefile.am create mode 100644 examples/cpp/encode/file/Makefile.lite create mode 100644 examples/cpp/encode/file/example_cpp_encode_file.dsp create mode 100644 examples/cpp/encode/file/example_cpp_encode_file.vcproj create mode 100644 examples/cpp/encode/file/main.cpp diff --git a/doc/html/documentation_example_code.html b/doc/html/documentation_example_code.html new file mode 100644 index 00000000..041b7aea --- /dev/null +++ b/doc/html/documentation_example_code.html @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + FLAC - developers + + + + + + +
+ + + +
+  english  | +  russian  +
+ +
+ +
+
+ example code +
+
+
+ The FLAC source code has several small example programs that demonstrate how to use the libraries. The source is available on the download page, or can be checked out from CVS or browsed online. The examples complement the API documentation.
+
+ Currently the examples show how to encode WAV files to FLAC and vice-versa using both libFLAC and libFLAC++. Over time we'll be adding more examples. +
+ +
+ + + + + + diff --git a/examples/c/encode/Makefile.am b/examples/c/encode/Makefile.am new file mode 100644 index 00000000..35bb987b --- /dev/null +++ b/examples/c/encode/Makefile.am @@ -0,0 +1,18 @@ +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under difference licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +SUBDIRS = file diff --git a/examples/c/encode/file/Makefile.am b/examples/c/encode/file/Makefile.am new file mode 100644 index 00000000..80819b73 --- /dev/null +++ b/examples/c/encode/file/Makefile.am @@ -0,0 +1,28 @@ +# example_c_encode_file - Simple FLAC file encoder using libFLAC +# Copyright (C) 2007 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +EXTRA_DIST = \ + Makefile.lite \ + example_c_encode_file.dsp \ + example_c_encode_file.vcproj \ + +noinst_PROGRAMS = example_c_encode_file +example_c_encode_file_LDADD = \ + @OGG_LIBS@ \ + @MINGW_WINSOCK_LIBS@ \ + -lm +example_c_encode_file_SOURCES = main.c diff --git a/examples/c/encode/file/Makefile.lite b/examples/c/encode/file/Makefile.lite new file mode 100644 index 00000000..d8be3269 --- /dev/null +++ b/examples/c/encode/file/Makefile.lite @@ -0,0 +1,39 @@ +# example_c_encode_file - Simple FLAC file encoder using libFLAC +# Copyright (C) 2007 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# +# GNU makefile +# + +topdir = ../../../.. +libdir = $(topdir)/obj/$(BUILD)/lib + +PROGRAM_NAME = example_c_encode_file + +INCLUDES = -I$(topdir)/include + +ifeq ($(DARWIN_BUILD),yes) +EXPLICIT_LIBS = $(libdir)/libFLAC.a $(OGG_LIB_DIR)/libogg.a -lm +else +LIBS = -lFLAC -L$(OGG_LIB_DIR) -logg -lm +endif + +SRCS_C = main.c + +include $(topdir)/build/exe.mk + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/examples/c/encode/file/example_c_encode_file.dsp b/examples/c/encode/file/example_c_encode_file.dsp new file mode 100644 index 00000000..8b22bc4b --- /dev/null +++ b/examples/c/encode/file/example_c_encode_file.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="example_c_encode_file" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=example_c_encode_file - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example_c_encode_file.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example_c_encode_file.mak" CFG="example_c_encode_file - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example_c_encode_file - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example_c_encode_file - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example_c_encode_file - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\..\..\obj\release\bin" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\include" /D "NDEBUG" /D "FLAC__NO_DLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 ..\..\..\..\obj\release\lib\libFLAC_static.lib ..\..\..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example_c_encode_file - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\..\..\obj\debug\bin" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\include" /D "_DEBUG" /D "DEBUG" /D "FLAC__NO_DLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\..\..\..\obj\debug\lib\libFLAC_static.lib ..\..\..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "example_c_encode_file - Win32 Release" +# Name "example_c_encode_file - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# End Target +# End Project diff --git a/examples/c/encode/file/example_c_encode_file.vcproj b/examples/c/encode/file/example_c_encode_file.vcproj new file mode 100644 index 00000000..e4e7a309 --- /dev/null +++ b/examples/c/encode/file/example_c_encode_file.vcproj @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/c/encode/file/main.c b/examples/c/encode/file/main.c new file mode 100644 index 00000000..d1037e3e --- /dev/null +++ b/examples/c/encode/file/main.c @@ -0,0 +1,173 @@ +/* example_c_encode_file - Simple FLAC file encoder using libFLAC + * Copyright (C) 2007 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This example shows how to use libFLAC to encode a WAVE file to a FLAC + * file. It only supports 16-bit stereo files in canonical WAVE format. + * + * Complete API documentation can be found at: + * http://flac.sourceforge.net/api/ + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include "FLAC/metadata.h" +#include "FLAC/stream_encoder.h" + +static void progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); + +#define READSIZE 1024 + +static unsigned total_samples = 0; /* can use a 32-bit number due to WAVE size limitations */ +static FLAC__byte buffer[READSIZE/*samples*/ * 2/*bytes_per_sample*/ * 2/*channels*/]; /* we read the WAVE data into here */ +static FLAC__int32 pcm[READSIZE/*samples*/ * 2/*channels*/]; + +int main(int argc, char *argv[]) +{ + FLAC__bool ok = true; + FLAC__StreamEncoder *encoder = 0; + FLAC__StreamEncoderInitStatus init_status; + FLAC__StreamMetadata *metadata[2]; + FLAC__StreamMetadata_VorbisComment_Entry entry; + FILE *fin; + unsigned sample_rate = 0; + unsigned channels = 0; + unsigned bps = 0; + + if(argc != 3) { + fprintf(stderr, "usage: %s infile.wav outfile.flac\n", argv[0]); + return 1; + } + + if((fin = fopen(argv[1], "rb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[1]); + return 1; + } + + /* read wav header and validate it */ + if( + fread(buffer, 1, 44, fin) != 44 || + memcmp(buffer, "RIFF", 4) || + memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) || + memcmp(buffer+32, "\004\000\020\000data", 8) + ) { + fprintf(stderr, "ERROR: invalid/unsupported WAVE file, only 16bps stereo WAVE in canonical form allowed\n"); + fclose(fin); + return 1; + } + sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) | buffer[25]) << 8) | buffer[24]; + channels = 2; + bps = 16; + total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8) | buffer[41]) << 8) | buffer[40]) / 4; + + /* allocate the encoder */ + if((encoder = FLAC__stream_encoder_new()) == NULL) { + fprintf(stderr, "ERROR: allocating encoder\n"); + fclose(fin); + return 1; + } + + ok &= FLAC__stream_encoder_set_verify(encoder, true); + ok &= FLAC__stream_encoder_set_compression_level(encoder, 5); + ok &= FLAC__stream_encoder_set_channels(encoder, channels); + ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps); + ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate); + ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, total_samples); + + /* now add some metadata; we'll add some tags and a padding block */ + if(ok) { + if( + (metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL || + (metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL || + /* there are many tag (vorbiscomment) functions but these are convenient for this particular use: */ + !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ARTIST", "Some Artist") || + !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) || /* copy=false: let metadata object take control of entry's allocated string */ + !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "YEAR", "1984") || + !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) + ) { + fprintf(stderr, "ERROR: out of memory or tag error\n"); + ok = false; + } + + metadata[1]->length = 1234; /* set the padding length */ + + ok = FLAC__stream_encoder_set_metadata(encoder, metadata, 2); + } + + /* initialize encoder */ + if(ok) { + init_status = FLAC__stream_encoder_init_file(encoder, argv[2], progress_callback, /*client_data=*/NULL); + if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { + fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]); + ok = false; + } + } + + /* read blocks of samples from WAVE file and feed to encoder */ + if(ok) { + size_t left = (size_t)total_samples; + while(ok && left) { + size_t need = (left>READSIZE? (size_t)READSIZE : (size_t)left); + if(fread(buffer, channels*(bps/8), need, fin) != need) { + fprintf(stderr, "ERROR: reading from WAVE file\n"); + ok = false; + } + else { + /* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */ + size_t i; + for(i = 0; i < need*channels; i++) { + /* inefficient but simple and works on big- or little-endian machines */ + pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]); + } + /* feed samples to encoder */ + ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need); + } + left -= need; + } + } + + ok &= FLAC__stream_encoder_finish(encoder); + + fprintf(stderr, "encoding: %s\n", ok? "succeeded" : "FAILED"); + fprintf(stderr, " state: %s\n", FLAC__StreamEncoderStateString[FLAC__stream_encoder_get_state(encoder)]); + + /* now that encoding is finished, the metadata can be freed */ + FLAC__metadata_object_delete(metadata[0]); + FLAC__metadata_object_delete(metadata[1]); + + FLAC__stream_encoder_delete(encoder); + fclose(fin); + + return 0; +} + +void progress_callback(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data) +{ + (void)encoder, (void)client_data; + +#ifdef _MSC_VER + fprintf(stderr, "wrote %I64u bytes, %I64u/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate); +#else + fprintf(stderr, "wrote %llu bytes, %llu/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate); +#endif +} diff --git a/examples/cpp/encode/Makefile.am b/examples/cpp/encode/Makefile.am new file mode 100644 index 00000000..35bb987b --- /dev/null +++ b/examples/cpp/encode/Makefile.am @@ -0,0 +1,18 @@ +# FLAC - Free Lossless Audio Codec +# Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson +# +# This file is part the FLAC project. FLAC is comprised of several +# components distributed under difference licenses. The codec libraries +# are distributed under Xiph.Org's BSD-like license (see the file +# COPYING.Xiph in this distribution). All other programs, libraries, and +# plugins are distributed under the GPL (see COPYING.GPL). The documentation +# is distributed under the Gnu FDL (see COPYING.FDL). Each file in the +# FLAC distribution contains at the top the terms under which it may be +# distributed. +# +# Since this particular file is relevant to all components of FLAC, +# it may be distributed under the Xiph.Org license, which is the least +# restrictive of those mentioned above. See the file COPYING.Xiph in this +# distribution. + +SUBDIRS = file diff --git a/examples/cpp/encode/file/Makefile.am b/examples/cpp/encode/file/Makefile.am new file mode 100644 index 00000000..4539dd99 --- /dev/null +++ b/examples/cpp/encode/file/Makefile.am @@ -0,0 +1,28 @@ +# example_cpp_encode_file - Simple FLAC file encoder using libFLAC +# Copyright (C) 2007 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +EXTRA_DIST = \ + Makefile.lite \ + example_cpp_encode_file.dsp \ + example_cpp_encode_file.vcproj \ + +noinst_PROGRAMS = example_cpp_encode_file +example_cpp_encode_file_LDADD = \ + @OGG_LIBS@ \ + @MINGW_WINSOCK_LIBS@ \ + -lm +example_cpp_encode_file_SOURCES = main.c diff --git a/examples/cpp/encode/file/Makefile.lite b/examples/cpp/encode/file/Makefile.lite new file mode 100644 index 00000000..9ae1b129 --- /dev/null +++ b/examples/cpp/encode/file/Makefile.lite @@ -0,0 +1,41 @@ +# example_cpp_encode_file - Simple FLAC file encoder using libFLAC +# Copyright (C) 2007 Josh Coalson +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# +# GNU makefile +# + +topdir = ../../../.. +libdir = $(topdir)/obj/$(BUILD)/lib + +PROGRAM_NAME = example_cpp_encode_file + +INCLUDES = -I$(topdir)/include + +ifeq ($(DARWIN_BUILD),yes) +EXPLICIT_LIBS = $(libdir)/libFLAC++.a $(libdir)/libFLAC.a $(OGG_LIB_DIR)/libogg.a -lm +else +LIBS = -lFLAC++ -lFLAC -L$(OGG_LIB_DIR) -logg -lm +endif + +SRCS_CPP = main.cpp + +include $(topdir)/build/exe.mk + +LINK = $(CCC) $(LINKAGE) + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/examples/cpp/encode/file/example_cpp_encode_file.dsp b/examples/cpp/encode/file/example_cpp_encode_file.dsp new file mode 100644 index 00000000..cf150305 --- /dev/null +++ b/examples/cpp/encode/file/example_cpp_encode_file.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="example_cpp_encode_file" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=example_cpp_encode_file - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example_cpp_encode_file.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example_cpp_encode_file.mak" CFG="example_cpp_encode_file - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example_cpp_encode_file - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example_cpp_encode_file - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example_cpp_encode_file - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "..\..\..\..\obj\release\bin" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\include" /D "NDEBUG" /D "FLAC__NO_DLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 ..\..\..\..\obj\release\lib\libFLAC++_static.lib ..\..\..\..\obj\release\lib\libFLAC_static.lib ..\..\..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example_cpp_encode_file - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "..\..\..\..\obj\debug\bin" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\..\include" /D "_DEBUG" /D "DEBUG" /D "FLAC__NO_DLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 ..\..\..\..\obj\debug\lib\libFLAC++_static.lib ..\..\..\..\obj\debug\lib\libFLAC_static.lib ..\..\..\..\obj\release\lib\ogg_static.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "example_cpp_encode_file - Win32 Release" +# Name "example_cpp_encode_file - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# End Target +# End Project diff --git a/examples/cpp/encode/file/example_cpp_encode_file.vcproj b/examples/cpp/encode/file/example_cpp_encode_file.vcproj new file mode 100644 index 00000000..72117f15 --- /dev/null +++ b/examples/cpp/encode/file/example_cpp_encode_file.vcproj @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/cpp/encode/file/main.cpp b/examples/cpp/encode/file/main.cpp new file mode 100644 index 00000000..8471bedd --- /dev/null +++ b/examples/cpp/encode/file/main.cpp @@ -0,0 +1,175 @@ +/* example_cpp_encode_file - Simple FLAC file encoder using libFLAC + * Copyright (C) 2007 Josh Coalson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This example shows how to use libFLAC++ to encode a WAVE file to a FLAC + * file. It only supports 16-bit stereo files in canonical WAVE format. + * + * Complete API documentation can be found at: + * http://flac.sourceforge.net/api/ + */ + +#if HAVE_CONFIG_H +# include +#endif + +#include +#include +#include "FLAC++/metadata.h" +#include "FLAC++/encoder.h" + +class OurEncoder: public FLAC::Encoder::File { +public: + OurEncoder(): FLAC::Encoder::File() { } +protected: + virtual void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate); +}; + +#define READSIZE 1024 + +static unsigned total_samples = 0; /* can use a 32-bit number due to WAVE size limitations */ +static FLAC__byte buffer[READSIZE/*samples*/ * 2/*bytes_per_sample*/ * 2/*channels*/]; /* we read the WAVE data into here */ +static FLAC__int32 pcm[READSIZE/*samples*/ * 2/*channels*/]; +static FLAC__int32 *pcm_[2] = { pcm, pcm+READSIZE }; + +int main(int argc, char *argv[]) +{ + FLAC__bool ok = true; + OurEncoder encoder; + FLAC__StreamEncoderInitStatus init_status; + FLAC__StreamMetadata *metadata[2]; + FLAC__StreamMetadata_VorbisComment_Entry entry; + FILE *fin; + unsigned sample_rate = 0; + unsigned channels = 0; + unsigned bps = 0; + + if(argc != 3) { + fprintf(stderr, "usage: %s infile.wav outfile.flac\n", argv[0]); + return 1; + } + + if((fin = fopen(argv[1], "rb")) == NULL) { + fprintf(stderr, "ERROR: opening %s for output\n", argv[1]); + return 1; + } + + /* read wav header and validate it */ + if( + fread(buffer, 1, 44, fin) != 44 || + memcmp(buffer, "RIFF", 4) || + memcmp(buffer+8, "WAVEfmt \020\000\000\000\001\000\002\000", 16) || + memcmp(buffer+32, "\004\000\020\000data", 8) + ) { + fprintf(stderr, "ERROR: invalid/unsupported WAVE file, only 16bps stereo WAVE in canonical form allowed\n"); + fclose(fin); + return 1; + } + sample_rate = ((((((unsigned)buffer[27] << 8) | buffer[26]) << 8) | buffer[25]) << 8) | buffer[24]; + channels = 2; + bps = 16; + total_samples = (((((((unsigned)buffer[43] << 8) | buffer[42]) << 8) | buffer[41]) << 8) | buffer[40]) / 4; + + /* check the encoder */ + if(!encoder) { + fprintf(stderr, "ERROR: allocating encoder\n"); + fclose(fin); + return 1; + } + + ok &= encoder.set_verify(true); + ok &= encoder.set_compression_level(5); + ok &= encoder.set_channels(channels); + ok &= encoder.set_bits_per_sample(bps); + ok &= encoder.set_sample_rate(sample_rate); + ok &= encoder.set_total_samples_estimate(total_samples); + + /* now add some metadata; we'll add some tags and a padding block */ + if(ok) { + if( + (metadata[0] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL || + (metadata[1] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL || + /* there are many tag (vorbiscomment) functions but these are convenient for this particular use: */ + !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "ARTIST", "Some Artist") || + !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) || /* copy=false: let metadata object take control of entry's allocated string */ + !FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, "YEAR", "1984") || + !FLAC__metadata_object_vorbiscomment_append_comment(metadata[0], entry, /*copy=*/false) + ) { + fprintf(stderr, "ERROR: out of memory or tag error\n"); + ok = false; + } + + metadata[1]->length = 1234; /* set the padding length */ + + ok = encoder.set_metadata(metadata, 2); + } + + /* initialize encoder */ + if(ok) { + init_status = encoder.init(argv[2]); + if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) { + fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]); + ok = false; + } + } + + /* read blocks of samples from WAVE file and feed to encoder */ + if(ok) { + size_t left = (size_t)total_samples; + while(ok && left) { + size_t need = (left>READSIZE? (size_t)READSIZE : (size_t)left); + if(fread(buffer, channels*(bps/8), need, fin) != need) { + fprintf(stderr, "ERROR: reading from WAVE file\n"); + ok = false; + } + else { + /* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */ + size_t i; + for(i = 0; i < need*channels; i++) { + /* inefficient but simple and works on big- or little-endian machines */ + pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]); + } + /* feed samples to encoder */ + ok = encoder.process_interleaved(pcm, need); + } + left -= need; + } + } + + ok &= encoder.finish(); + + fprintf(stderr, "encoding: %s\n", ok? "succeeded" : "FAILED"); + fprintf(stderr, " state: %s\n", encoder.get_state().resolved_as_cstring(encoder)); + + /* now that encoding is finished, the metadata can be freed */ + FLAC__metadata_object_delete(metadata[0]); + FLAC__metadata_object_delete(metadata[1]); + + fclose(fin); + + return 0; +} + +void OurEncoder::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate) +{ +#ifdef _MSC_VER + fprintf(stderr, "wrote %I64u bytes, %I64u/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate); +#else + fprintf(stderr, "wrote %llu bytes, %llu/%u samples, %u/%u frames\n", bytes_written, samples_written, total_samples, frames_written, total_frames_estimate); +#endif +}