merge Sakari's (sbergen) branch back into 3.0, removing libsndfile and adding taglib

git-svn-id: svn://localhost/ardour2/branches/3.0@3736 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2008-09-17 08:44:51 +00:00
parent 8e9a83dfdc
commit 1c299d5a5c
406 changed files with 177056 additions and 64756 deletions

View File

@@ -261,16 +261,16 @@ def create_stored_revision (target = None, source = None, env = None):
if os.path.exists('.svn'):
rev = fetch_svn_revision ('.');
try:
text = "#ifndef __ardour_svn_revision_h__\n"
text += "#define __ardour_svn_revision_h__\n"
text += "static const char* ardour_svn_revision = \"" + rev + "\";\n";
text += "#endif\n"
print '============> writing svn revision info to svn_revision.h\n'
o = file ('svn_revision.h', 'w')
text = "#include <ardour/svn_revision.h>\n"
text += "namespace ARDOUR {\n";
text += "extern const char* svn_revision = \"" + rev + "\";\n";
text += "}\n";
print '============> writing svn revision info to libs/ardour/svn_revision.cc\n'
o = file ('libs/ardour/svn_revision.cc', 'w')
o.write (text)
o.close ()
except IOError:
print "Could not open svn_revision.h for writing\n"
print "Could not open libs/ardour/svn_revision.cc for writing\n"
sys.exit (-1)
else:
print "You cannot use \"scons revision\" on without using a checked out"
@@ -1163,6 +1163,9 @@ else:
libraries['sndfile-ardour'] = LibraryInfo(LIBS='libsndfile-ardour',
LIBPATH='#libs/libsndfile',
CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
libraries['taglib'] = LibraryInfo(LIBS='libtaglib',
LIBPATH='#libs/taglib',
CPPPATH=['#libs/taglib/headers','#libs/taglib/headers/taglib'])
# libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
# LIBPATH='#libs/libglademm',
# CPPPATH='#libs/libglademm')
@@ -1178,6 +1181,7 @@ else:
subdirs = [
'libs/sigc++2',
'libs/libsndfile',
'libs/taglib',
'libs/pbd',
'libs/midi++2',
'libs/ardour',
@@ -1399,6 +1403,12 @@ env.Alias ('srctar', srcdist)
env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
#
# Update revision info before going into subdirs
#
create_stored_revision()
#
# the subdirs
#

View File

@@ -53,6 +53,7 @@ gtkardour.Merge ([
libraries['samplerate'],
libraries['sigc2'],
libraries['sndfile-ardour'],
libraries['taglib'],
libraries['sysmidi'],
libraries['vamp'],
libraries['vamphost'],
@@ -170,10 +171,12 @@ editor_tempodisplay.cc
editor_timefx.cc
engine_dialog.cc
enums.cc
export_dialog.cc
export_range_markers_dialog.cc
export_region_dialog.cc
export_session_dialog.cc
export_format_dialog.cc
export_main_dialog.cc
export_channel_selector.cc
export_filename_selector.cc
export_format_selector.cc
export_timespan_selector.cc
gain_meter.cc
generic_pluginui.cc
ghostregion.cc
@@ -220,6 +223,7 @@ route_time_axis.cc
route_ui.cc
selection.cc
send_ui.cc
session_metadata_dialog.cc
sfdb_ui.cc
simpleline.cc
simplerect.cc

View File

@@ -27,6 +27,7 @@
#include <pbd/file_utils.h>
#include <ardour/svn_revision.h>
#include <ardour/ardour.h>
#include <ardour/version.h>
#include <ardour/filesystem_paths.h>
@@ -34,7 +35,6 @@
#include "utils.h"
#include "version.h"
#include "svn_revision.h"
#include "about.h"
#include "rgb_macros.h"
#include "ardour_ui.h"
@@ -215,7 +215,7 @@ About::About ()
set_website_label (_("visit http://www.ardour.org/"));
set_version ((string_compose(_("%1\n(built from revision %2)"),
VERSIONSTRING,
ardour_svn_revision)));
svn_revision)));
#ifdef WITH_PAYMENT_OPTIONS

View File

@@ -10,15 +10,17 @@
<menuitem action='Save'/>
<menuitem action='Snapshot'/>
<menuitem action='SaveTemplate'/>
<menu name='Metadata' action='Metadata'>
<menuitem action='EditMetadata'/>
<menuitem action='ImportMetadata'/>
</menu>
<separator/>
<menuitem action='AddTrackBus'/>
<separator/>
<menuitem action='addExistingAudioFiles'/>
<separator/>
<menu name='Export' action='Export'>
<menuitem action='ExportSession'/>
<menuitem action='ExportSelection'/>
<menuitem action='ExportRangeMarkers'/>
<menuitem action='ExportAudio'/>
</menu>
<separator/>
<menu name='Cleanup' action='Cleanup'>

View File

@@ -29,17 +29,13 @@
ArdourDialog::ArdourDialog (string title, bool modal, bool use_seperator)
: Dialog (title, modal, use_seperator)
{
session = 0;
set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
init ();
}
ArdourDialog::ArdourDialog (Gtk::Window& parent, string title, bool modal, bool use_seperator)
: Dialog (title, parent, modal, use_seperator)
{
session = 0;
set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
init ();
set_position (Gtk::WIN_POS_CENTER_ON_PARENT);
}
@@ -80,3 +76,10 @@ ArdourDialog::on_show ()
Dialog::on_show ();
}
void ArdourDialog::init ()
{
session = 0;
set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
set_border_width (10);
}

View File

@@ -54,6 +54,9 @@ class ArdourDialog : public Gtk::Dialog
virtual void session_gone () {
set_session (0);
}
private:
void init ();
};
#endif // __ardour_dialog_h__

View File

@@ -91,6 +91,7 @@ typedef uint64_t microseconds_t;
#include "gui_thread.h"
#include "theme_manager.h"
#include "bundle_manager.h"
#include "session_metadata_dialog.h"
#include "gain_meter.h"
#include "route_time_axis.h"
@@ -2008,6 +2009,24 @@ ARDOUR_UI::save_template ()
}
}
void
ARDOUR_UI::edit_metadata ()
{
SessionMetadataEditor dialog;
dialog.set_session (session);
editor->ensure_float (dialog);
dialog.run ();
}
void
ARDOUR_UI::import_metadata ()
{
SessionMetadataImporter dialog;
dialog.set_session (session);
editor->ensure_float (dialog);
dialog.run ();
}
void
ARDOUR_UI::fontconfig_dialog ()
{

View File

@@ -570,6 +570,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void open_session ();
void open_recent_session ();
void save_template ();
void edit_metadata ();
void import_metadata ();
void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many);
void session_add_midi_route (bool disk, uint32_t how_many);

View File

@@ -136,16 +136,17 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_action (main_actions, X_("SaveTemplate"), _("Save Template..."), mem_fun(*this, &ARDOUR_UI::save_template));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("ExportSession"), _("Export session to audiofile..."), mem_fun (*editor, &PublicEditor::export_session));
act = ActionManager::register_action (main_actions, X_("Metadata"), _("Metadata"));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("ExportSelection"), _("Export selection to audiofile..."), mem_fun (*editor, &PublicEditor::export_selection));
act = ActionManager::register_action (main_actions, X_("EditMetadata"), _("Edit Metadata"), mem_fun(*this, &ARDOUR_UI::edit_metadata));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::time_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("ExportRangeMarkers"), _("Export range markers to audiofile..."), mem_fun (*editor, &PublicEditor::export_range_markers));
act = ActionManager::register_action (main_actions, X_("ImportMetadata"), _("Import Metadata"), mem_fun(*this, &ARDOUR_UI::import_metadata));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("ExportAudio"), _("Export to audiofile(s)..."), mem_fun (*editor, &PublicEditor::export_audio));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::range_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("Export"), _("Export"));
ActionManager::session_sensitive_actions.push_back (act);

View File

@@ -295,8 +295,6 @@ Editor::Editor ()
_show_waveforms = true;
_show_waveforms_recording = true;
first_action_message = 0;
export_dialog = 0;
export_range_markers_dialog = 0;
show_gain_after_trim = false;
ignore_route_list_reorder = false;
no_route_list_redisplay = false;
@@ -2117,7 +2115,7 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true)));
items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false)));
items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection)));
items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_range)));
}

View File

@@ -98,8 +98,6 @@ class PlaylistSelector;
class Marker;
class GroupedButtons;
class AutomationLine;
class UIExportSpecification;
class ExportDialog;
class Selection;
class TimeSelection;
class TrackSelection;
@@ -272,12 +270,11 @@ class Editor : public PublicEditor
#endif
/* export */
/* these initiate export ... */
void export_session();
void export_selection();
void export_audio ();
void export_selection ();
void export_range ();
void export_region ();
void add_toplevel_controls (Gtk::Container&);
Gtk::HBox& get_status_bar_packer() { return status_bar_hpacker; }
@@ -1566,7 +1563,6 @@ public:
void marker_menu_set_from_playhead ();
void marker_menu_set_from_selection ();
void marker_menu_range_to_next ();
void marker_menu_export_range ();
void new_transport_marker_menu_set_loop ();
void new_transport_marker_menu_set_punch ();
void update_loop_range_view (bool visibility=false);
@@ -1994,15 +1990,8 @@ public:
/* audio export */
ExportDialog *export_dialog;
ExportDialog *export_range_markers_dialog;
void export_range (nframes64_t start, nframes64_t end);
void export_range_markers ();
int write_region_selection(RegionSelection&);
bool write_region (string path, boost::shared_ptr<ARDOUR::AudioRegion>);
void export_region ();
void bounce_region_selection ();
void bounce_range_selection (bool replace);
void external_edit_region ();

View File

@@ -492,9 +492,9 @@ Editor::register_actions ()
redo_action = act = ActionManager::register_action (editor_actions, "redo", _("Redo"), bind (mem_fun(*this, &Editor::redo), 1U));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "export-session", _("Export Session"), mem_fun(*this, &Editor::export_session));
act = ActionManager::register_action (editor_actions, "export-audio", _("Export Audio"), mem_fun(*this, &Editor::export_audio));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), mem_fun(*this, &Editor::export_selection));
act = ActionManager::register_action (editor_actions, "export-range", _("Export Range"), mem_fun(*this, &Editor::export_range));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "editor-separate", _("Separate"), mem_fun(*this, &Editor::separate_region_from_selection));

View File

@@ -24,9 +24,7 @@
#include <gtkmm/messagedialog.h>
#include "export_session_dialog.h"
#include "export_region_dialog.h"
#include "export_range_markers_dialog.h"
#include "export_main_dialog.h"
#include "editor.h"
#include "public_editor.h"
#include "selection.h"
@@ -36,7 +34,6 @@
#include <pbd/pthread_utils.h>
#include <ardour/types.h>
#include <ardour/export.h>
#include <ardour/audio_track.h>
#include <ardour/audiofilesource.h>
#include <ardour/audio_diskstream.h>
@@ -55,79 +52,60 @@ using namespace PBD;
using namespace Gtk;
void
Editor::export_session()
Editor::export_audio ()
{
if (session) {
export_range (session->current_start_frame(), session->current_end_frame());
}
ExportMainDialog dialog (*this);
dialog.set_session (session);
dialog.run();
}
void
Editor::export_selection ()
{
if (session) {
if (selection->time.empty()) {
MessageDialog message (*this, _("There is no selection to export.\n\nSelect a selection using the range mouse mode"));
message.run ();
return;
}
export_range (selection->time.front().start, selection->time.front().end);
}
ExportMainDialog dialog (*this);
dialog.set_session (session);
dialog.select_timespan (X_("selection"));
dialog.run();
}
void
Editor::export_range (nframes64_t start, nframes64_t end)
Editor::export_range ()
{
if (session) {
if (export_dialog == 0) {
export_dialog = new ExportSessionDialog (*this);
export_dialog->connect_to_session (session);
}
export_dialog->set_range (start, end);
export_dialog->start_export();
Marker* marker;
if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
/*NOTREACHED*/
}
}
Location* l;
bool is_start;
if (((l = find_location_from_marker (marker, is_start)) != 0) && (l->end() > l->start())) {
ExportMainDialog dialog (*this);
dialog.set_session (session);
dialog.select_timespan (l->id().to_s());
dialog.run();
}
}
/** Export the first selected region */
void
Editor::export_region ()
{
if (selection->regions.empty()) {
return;
}
boost::shared_ptr<Region> r = selection->regions.front()->region();
ExportDialog* dialog = new ExportRegionDialog (*this, r);
dialog->connect_to_session (session);
dialog->set_range (clicked_regionview->region()->first_frame(), clicked_regionview->region()->last_frame());
dialog->start_export();
// if (selection->regions.empty()) {
// return;
// }
//
// boost::shared_ptr<Region> r = selection->regions.front()->region();
//
// ExportDialog* dialog = new ExportRegionDialog (*this, r);
//
// dialog->connect_to_session (session);
// dialog->set_range (clicked_regionview->region()->first_frame(), clicked_regionview->region()->last_frame());
// dialog->start_export();
}
void
Editor::export_range_markers ()
{
if (session) {
if (session->locations()->num_range_markers() == 0) {
MessageDialog message (*this, _("There are no ranges to export.\n\nCreate 1 or more ranges by dragging the mouse in the range bar"));
message.run ();
return;
}
if (export_range_markers_dialog == 0) {
export_range_markers_dialog = new ExportRangeMarkersDialog(*this);
export_range_markers_dialog->connect_to_session (session);
}
export_range_markers_dialog->start_export();
}
}
int
Editor::write_region_selection (RegionSelection& regions)
{

View File

@@ -636,7 +636,7 @@ Editor::build_range_marker_menu (bool loop_or_punch)
}
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::marker_menu_export_range)));
items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::export_range)));
items.push_back (SeparatorElem());
if (!loop_or_punch) {
@@ -814,26 +814,6 @@ Editor::marker_menu_set_playhead ()
}
}
void
Editor::marker_menu_export_range ()
{
Marker* marker;
if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
/*NOTREACHED*/
}
Location* l;
bool is_start;
if ((l = find_location_from_marker (marker, is_start)) != 0) {
if (l->is_range_marker()) {
export_range (l->start(), l->end());
}
}
}
void
Editor::marker_menu_range_to_next ()
{

View File

@@ -636,7 +636,6 @@ LocationUI::LocationUI ()
get_vbox()->pack_start (location_hpacker);
location_vpacker.set_border_width (10);
location_vpacker.set_spacing (5);
location_vpacker.pack_start (loop_edit_row, false, false);

View File

@@ -31,6 +31,7 @@
#include <jack/jack.h>
#include <ardour/svn_revision.h>
#include <ardour/version.h>
#include <ardour/ardour.h>
#include <ardour/audioengine.h>
@@ -41,7 +42,6 @@
#include <gtkmm2ext/popup.h>
#include <gtkmm2ext/utils.h>
#include "../svn_revision.h"
#include "version.h"
#include "utils.h"
#include "ardour_ui.h"
@@ -324,7 +324,7 @@ int main (int argc, char *argv[])
cout << _("Ardour/GTK ")
<< VERSIONSTRING
<< _("\n (built using ")
<< ardour_svn_revision
<< svn_revision
#ifdef __GNUC__
<< _(" and GCC version ") << __VERSION__
#endif

View File

@@ -38,7 +38,6 @@
namespace ARDOUR {
class Session;
class ExportSpecification;
class Region;
class Playlist;
class RouteGroup;
@@ -206,16 +205,15 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual bool show_measures () const = 0;
virtual bool redraw_measures () = 0;
/** Open an export dialogue for the whole session */
virtual void export_session () = 0;
/** Open an export dialogue for currently selected time range, if there
* is one; if not an error is displayed to the user.
*/
/** Open main export dialog */
virtual void export_audio () = 0;
/** Open export dialog with current selection pre-selected */
virtual void export_selection () = 0;
/** Open export dialog with current range pre-selected */
virtual void export_range () = 0;
/** Open an export dialogue for marked ranges */
virtual void export_range_markers () = 0;
virtual void register_actions () = 0;
virtual void add_toplevel_controls (Gtk::Container&) = 0;
virtual void set_zoom_focus (Editing::ZoomFocus) = 0;

View File

@@ -37,6 +37,7 @@ audio_buffer.cc
audio_diskstream.cc
audioengine.cc
audiofilesource.cc
audiofile_tagger.cc
audio_library.cc
audio_playlist.cc
audio_port.cc
@@ -51,6 +52,7 @@ automation_control.cc
automation_event.cc
base_audio_port.cc
base_midi_port.cc
broadcast_info.cc
buffer.cc
buffer_set.cc
chan_count.cc
@@ -64,6 +66,19 @@ default_click.cc
directory_names.cc
diskstream.cc
enums.cc
export_channel_configuration.cc
export_file_io.cc
export_filename.cc
export_format_base.cc
export_format_manager.cc
export_formats.cc
export_format_specification.cc
export_handler.cc
export_processor.cc
export_profile_manager.cc
export_status.cc
export_timespan.cc
export_utilities.cc
filename_extensions.cc
filesystem_paths.cc
filter.cc
@@ -124,6 +139,7 @@ session_command.cc
session_directory.cc
session_events.cc
session_export.cc
session_metadata.cc
session_midi.cc
session_process.cc
session_state.cc
@@ -139,6 +155,7 @@ sndfilesource.cc
sndfileimportable.cc
source.cc
source_factory.cc
svn_revision.cc
tape_file_matcher.cc
template_utils.cc
tempo.cc
@@ -318,6 +335,7 @@ ardour.Merge ([
libraries['samplerate'],
libraries['sigc2'],
libraries['sndfile-ardour'],
libraries['taglib'],
libraries['vamp'],
libraries['vamphost'],
libraries['xml']

View File

@@ -30,12 +30,13 @@
#include <ardour/region.h>
#include <ardour/gain.h>
#include <ardour/logcurve.h>
#include <ardour/export.h>
class XMLNode;
namespace ARDOUR {
using std::vector;
class Route;
class Playlist;
class Session;

View File

@@ -30,11 +30,12 @@
#include <ardour/region.h>
#include <ardour/gain.h>
#include <ardour/logcurve.h>
#include <ardour/export.h>
#include <ardour/midi_source.h>
class XMLNode;
using std::vector;
namespace ARDOUR {
class Route;

View File

@@ -51,6 +51,7 @@
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/export_status.h>
#include <ardour/location.h>
#include <ardour/gain.h>
#include <ardour/io.h>
@@ -108,8 +109,9 @@ class MidiRegion;
class SMFSource;
class SessionDirectory;
class SessionMetadata;
class ExportHandler;
struct ExportSpecification;
struct RouteGroup;
using std::vector;
@@ -457,7 +459,7 @@ class Session : public PBD::StatefulDestructible
XMLNode& get_template();
/// The instant xml file is written to the session directory
void add_instant_xml (XMLNode&);
void add_instant_xml (XMLNode&, bool write_to_config = true);
XMLNode * instant_xml (const std::string& str);
enum StateOfTheState {
@@ -554,7 +556,7 @@ class Session : public PBD::StatefulDestructible
void set_smpte_offset_negative (bool);
bool smpte_offset_negative () const { return _smpte_offset_negative; }
nframes_t convert_to_frames_at (nframes_t position, AnyTime&);
nframes_t convert_to_frames_at (nframes_t position, AnyTime const &);
static sigc::signal<void> StartTimeChanged;
static sigc::signal<void> EndTimeChanged;
@@ -616,14 +618,27 @@ class Session : public PBD::StatefulDestructible
bool sample_rate_convert (import_status&, string infile, string& outfile);
string build_tmp_convert_name (string file);
/* Export stuff */
SlaveSource post_export_slave;
nframes_t post_export_position;
ExportStatus export_status;
boost::shared_ptr<ExportHandler> get_export_handler ();
void release_export_handler ();
int pre_export ();
int start_export (ARDOUR::ExportSpecification&);
int stop_export (ARDOUR::ExportSpecification&);
void finalize_export ();
int start_audio_export (nframes_t position, bool realtime);
int stop_audio_export ();
void finalize_audio_export ();
void abort_audio_export ();
sigc::signal<int, nframes_t> ProcessExport;
sigc::signal<void> ExportFinished;
static sigc::signal<void, std::string, std::string> Exported;
sigc::connection export_freewheel_connection;
sigc::connection export_abort_connection;
void add_source (boost::shared_ptr<Source>);
void remove_source (boost::weak_ptr<Source>);
@@ -1051,7 +1066,8 @@ class Session : public PBD::StatefulDestructible
void process_without_events (nframes_t);
void process_with_events (nframes_t);
void process_audition (nframes_t);
int process_export (nframes_t, ARDOUR::ExportSpecification*);
void process_export (nframes_t);
int process_export_fw (nframes_t);
/* slave tracking */
@@ -1076,8 +1092,8 @@ class Session : public PBD::StatefulDestructible
void set_slave_source (SlaveSource);
bool _exporting;
int prepare_to_export (ARDOUR::ExportSpecification&);
bool _exporting_realtime;
boost::shared_ptr<ExportHandler> export_handler;
void prepare_diskstreams ();
void commit_diskstreams (nframes_t, bool& session_requires_butler);
@@ -1724,6 +1740,12 @@ class Session : public PBD::StatefulDestructible
void sync_order_keys ();
static bool _disable_all_loaded_plugins;
/* Metadata */
SessionMetadata * _metadata;
public:
SessionMetadata & metadata () { return *_metadata; }
};
} // namespace ARDOUR

View File

@@ -342,6 +342,11 @@ namespace ARDOUR {
FormatInt16
};
enum CDMarkerFormat {
CDMarkerNone,
CDMarkerCUE,
CDMarkerTOC
};
enum HeaderFormat {
BWF,

View File

@@ -1024,65 +1024,67 @@ AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const
int
AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec)
{
const nframes_t blocksize = 4096;
nframes_t to_read;
int status = -1;
spec.channels = _sources.size();
if (spec.prepare (blocksize, session.frame_rate())) {
goto out;
}
spec.pos = 0;
spec.total_frames = _length;
while (spec.pos < _length && !spec.stop) {
/* step 1: interleave */
to_read = min (_length - spec.pos, blocksize);
if (spec.channels == 1) {
if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
goto out;
}
} else {
Sample buf[blocksize];
for (uint32_t chan = 0; chan < spec.channels; ++chan) {
if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
goto out;
}
for (nframes_t x = 0; x < to_read; ++x) {
spec.dataF[chan+(x*spec.channels)] = buf[x];
}
}
}
if (spec.process (to_read)) {
goto out;
}
spec.pos += to_read;
spec.progress = (double) spec.pos /_length;
}
status = 0;
out:
spec.running = false;
spec.status = status;
spec.clear();
return status;
// TODO EXPORT
// const nframes_t blocksize = 4096;
// nframes_t to_read;
// int status = -1;
//
// spec.channels = _sources.size();
//
// if (spec.prepare (blocksize, session.frame_rate())) {
// goto out;
// }
//
// spec.pos = 0;
// spec.total_frames = _length;
//
// while (spec.pos < _length && !spec.stop) {
//
//
// /* step 1: interleave */
//
// to_read = min (_length - spec.pos, blocksize);
//
// if (spec.channels == 1) {
//
// if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) {
// goto out;
// }
//
// } else {
//
// Sample buf[blocksize];
//
// for (uint32_t chan = 0; chan < spec.channels; ++chan) {
//
// if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
// goto out;
// }
//
// for (nframes_t x = 0; x < to_read; ++x) {
// spec.dataF[chan+(x*spec.channels)] = buf[x];
// }
// }
// }
//
// if (spec.process (to_read)) {
// goto out;
// }
//
// spec.pos += to_read;
// spec.progress = (double) spec.pos /_length;
//
// }
//
// status = 0;
//
// out:
// spec.running = false;
// spec.status = status;
// spec.clear();
//
// return status;
return 0;
}
void

View File

@@ -29,6 +29,9 @@
#include <ardour/panner.h>
#include <ardour/track.h>
#include <ardour/midi_track.h>
#include <ardour/export_filename.h>
#include <ardour/export_format_base.h>
#include <ardour/export_profile_manager.h>
using namespace std;
using namespace PBD;
@@ -59,6 +62,7 @@ setup_enum_writer ()
LayerModel _LayerModel;
SoloModel _SoloModel;
SampleFormat _SampleFormat;
CDMarkerFormat _CDMarkerFormat;
HeaderFormat _HeaderFormat;
PluginType _PluginType;
SlaveSource _SlaveSource;
@@ -86,6 +90,18 @@ setup_enum_writer ()
Region::PositionLockStyle _Region_PositionLockStyle;
Track::FreezeState _Track_FreezeState;
AutomationList::InterpolationStyle _AutomationList_InterpolationStyle;
AnyTime::Type _AnyTime_Type;
ExportFilename::TimeFormat _ExportFilename_TimeFormat;
ExportFilename::DateFormat _ExportFilename_DateFormat;
ExportFormatBase::Type _ExportFormatBase_Type;
ExportFormatBase::FormatId _ExportFormatBase_FormatId;
ExportFormatBase::Endianness _ExportFormatBase_Endianness;
ExportFormatBase::SampleFormat _ExportFormatBase_SampleFormat;
ExportFormatBase::DitherType _ExportFormatBase_DitherType;
ExportFormatBase::Quality _ExportFormatBase_Quality;
ExportFormatBase::SampleRate _ExportFormatBase_SampleRate;
ExportFormatBase::SRCQuality _ExportFormatBase_SRCQuality;
ExportProfileManager::TimeFormat _ExportProfileManager_TimeFormat;
#define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@@ -213,6 +229,11 @@ setup_enum_writer ()
REGISTER_ENUM (FormatInt16);
REGISTER (_SampleFormat);
REGISTER_ENUM (CDMarkerNone);
REGISTER_ENUM (CDMarkerCUE);
REGISTER_ENUM (CDMarkerTOC);
REGISTER (_CDMarkerFormat);
REGISTER_ENUM (BWF);
REGISTER_ENUM (WAVE);
REGISTER_ENUM (WAVE64);
@@ -386,4 +407,89 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (AutomationList, Curved);
REGISTER (_AutomationList_InterpolationStyle);
REGISTER_CLASS_ENUM (AnyTime, SMPTE);
REGISTER_CLASS_ENUM (AnyTime, BBT);
REGISTER_CLASS_ENUM (AnyTime, Frames);
REGISTER_CLASS_ENUM (AnyTime, Seconds);
REGISTER (_AnyTime_Type);
REGISTER_CLASS_ENUM (ExportFilename, D_None);
REGISTER_CLASS_ENUM (ExportFilename, D_ISO);
REGISTER_CLASS_ENUM (ExportFilename, D_ISOShortY);
REGISTER_CLASS_ENUM (ExportFilename, D_BE);
REGISTER_CLASS_ENUM (ExportFilename, D_BEShortY);
REGISTER (_ExportFilename_DateFormat);
REGISTER_CLASS_ENUM (ExportFilename, T_None);
REGISTER_CLASS_ENUM (ExportFilename, T_NoDelim);
REGISTER_CLASS_ENUM (ExportFilename, T_Delim);
REGISTER (_ExportFilename_TimeFormat);
REGISTER_CLASS_ENUM (ExportFormatBase, T_None);
REGISTER_CLASS_ENUM (ExportFormatBase, T_Sndfile);
REGISTER (_ExportFormatBase_Type);
REGISTER_CLASS_ENUM (ExportFormatBase, F_None);
REGISTER_CLASS_ENUM (ExportFormatBase, F_WAV);
REGISTER_CLASS_ENUM (ExportFormatBase, F_W64);
REGISTER_CLASS_ENUM (ExportFormatBase, F_AIFF);
REGISTER_CLASS_ENUM (ExportFormatBase, F_AU);
REGISTER_CLASS_ENUM (ExportFormatBase, F_IRCAM);
REGISTER_CLASS_ENUM (ExportFormatBase, F_RAW);
REGISTER_CLASS_ENUM (ExportFormatBase, F_FLAC);
REGISTER_CLASS_ENUM (ExportFormatBase, F_Ogg);
REGISTER (_ExportFormatBase_FormatId);
REGISTER_CLASS_ENUM (ExportFormatBase, E_FileDefault);
REGISTER_CLASS_ENUM (ExportFormatBase, E_Little);
REGISTER_CLASS_ENUM (ExportFormatBase, E_Big);
REGISTER_CLASS_ENUM (ExportFormatBase, E_Cpu);
REGISTER (_ExportFormatBase_Endianness);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_None);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_8);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_16);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_24);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_32);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_U8);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_Float);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_Double);
REGISTER_CLASS_ENUM (ExportFormatBase, SF_Vorbis);
REGISTER (_ExportFormatBase_SampleFormat);
REGISTER_CLASS_ENUM (ExportFormatBase, D_None);
REGISTER_CLASS_ENUM (ExportFormatBase, D_Rect);
REGISTER_CLASS_ENUM (ExportFormatBase, D_Tri);
REGISTER_CLASS_ENUM (ExportFormatBase, D_Shaped);
REGISTER (_ExportFormatBase_DitherType);
REGISTER_CLASS_ENUM (ExportFormatBase, Q_None);
REGISTER_CLASS_ENUM (ExportFormatBase, Q_Any);
REGISTER_CLASS_ENUM (ExportFormatBase, Q_LosslessLinear);
REGISTER_CLASS_ENUM (ExportFormatBase, Q_LosslessCompression);
REGISTER_CLASS_ENUM (ExportFormatBase, Q_LossyCompression);
REGISTER (_ExportFormatBase_Quality);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_None);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_22_05);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_44_1);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_48);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_88_2);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_96);
REGISTER_CLASS_ENUM (ExportFormatBase, SR_192);
REGISTER (_ExportFormatBase_SampleRate);
REGISTER_CLASS_ENUM (ExportFormatBase, SRC_SincBest);
REGISTER_CLASS_ENUM (ExportFormatBase, SRC_SincMedium);
REGISTER_CLASS_ENUM (ExportFormatBase, SRC_SincFast);
REGISTER_CLASS_ENUM (ExportFormatBase, SRC_ZeroOrderHold);
REGISTER_CLASS_ENUM (ExportFormatBase, SRC_Linear);
REGISTER (_ExportFormatBase_SRCQuality);
REGISTER_CLASS_ENUM (ExportProfileManager, SMPTE);
REGISTER_CLASS_ENUM (ExportProfileManager, BBT);
REGISTER_CLASS_ENUM (ExportProfileManager, MinSec);
REGISTER_CLASS_ENUM (ExportProfileManager, Frames);
REGISTER_CLASS_ENUM (ExportProfileManager, Off);
REGISTER (_ExportProfileManager_TimeFormat);
}

View File

@@ -47,6 +47,7 @@
#include <ardour/configuration.h>
#include <ardour/session.h>
#include <ardour/session_directory.h>
#include <ardour/session_metadata.h>
#include <ardour/utils.h>
#include <ardour/audio_diskstream.h>
#include <ardour/audioplaylist.h>
@@ -143,7 +144,8 @@ Session::Session (AudioEngine &eng,
_total_free_4k_blocks (0),
_bundle_xml_node (0),
_click_io ((IO*) 0),
main_outs (0)
main_outs (0),
_metadata (new SessionMetadata())
{
bool new_session;

View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 1999-2002 Paul Davis
Copyright (C) 1999-2008 Paul Davis
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
@@ -17,35 +17,18 @@
*/
/* see gdither.cc for why we have to do this */
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#include <cmath>
#undef _ISOC99_SOURCE
#undef _ISOC9X_SOURCE
#undef __USE_SVID
#define __USE_SVID 1
#include <cstdlib>
#undef __USE_SVID
#include <unistd.h>
#include <inttypes.h>
#include <float.h>
#include <sigc++/bind.h>
#include <pbd/error.h>
#include <glibmm/thread.h>
#include <ardour/gdither.h>
#include <ardour/export_failed.h>
#include <ardour/export_file_io.h>
#include <ardour/export_utilities.h>
#include <ardour/export_handler.h>
#include <ardour/timestamps.h>
#include <ardour/ardour.h>
#include <ardour/session.h>
#include <ardour/export.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/port.h>
#include <ardour/audio_port.h>
#include <ardour/audioengine.h>
#include <ardour/audio_diskstream.h>
#include <ardour/panner.h>
@@ -56,415 +39,28 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
static int
convert_spec_to_info (ExportSpecification& spec, SF_INFO& sfinfo)
boost::shared_ptr<ExportHandler>
Session::get_export_handler ()
{
if (spec.path.length() == 0) {
error << _("Export: no output file specified") << endmsg;
return -1;
if (!export_handler) {
export_handler.reset (new ExportHandler (*this));
}
/* XXX add checks that the directory path exists, and also
check if we are overwriting an existing file...
*/
sfinfo.format = spec.format;
sfinfo.samplerate = spec.sample_rate;
sfinfo.frames = spec.end_frame - spec.start_frame + 1;
sfinfo.channels = min (spec.channels, 2U);
return 0;
}
ExportSpecification::ExportSpecification ()
{
init ();
}
ExportSpecification::~ExportSpecification ()
{
clear ();
return export_handler;
}
void
ExportSpecification::init ()
Session::release_export_handler ()
{
src_state = 0;
pos = 0;
total_frames = 0;
out = 0;
channels = 0;
running = false;
stop = false;
progress = 0.0;
status = 0;
dither = 0;
start_frame = 0;
end_frame = 0;
dataF = 0;
dataF2 = 0;
leftoverF = 0;
max_leftover_frames = 0;
leftover_frames = 0;
output_data = 0;
out_samples_max = 0;
data_width = 0;
do_freewheel = false;
}
void
ExportSpecification::clear ()
{
if (out) {
sf_close (out);
out = 0;
if (!_exporting) {
export_handler.reset();
}
if (src_state) {
src_delete (src_state);
src_state = 0;
}
if (dither) {
gdither_free (dither);
dither = 0;
}
if (output_data) {
free (output_data);
output_data = 0;
}
if (dataF) {
delete [] dataF;
dataF = 0;
}
if (dataF2) {
delete [] dataF2;
dataF2 = 0;
}
if (leftoverF) {
delete [] leftoverF;
leftoverF = 0;
}
freewheel_connection.disconnect ();
init ();
}
int
ExportSpecification::prepare (nframes_t blocksize, nframes_t frate)
{
char errbuf[256];
GDitherSize dither_size;
frame_rate = frate;
if (channels == 0) {
error << _("illegal channel count in export specification") << endmsg;
return -1;
}
if (start_frame >= end_frame) {
error << _("illegal frame range in export specification") << endmsg;
return -1;
}
if ((data_width = sndfile_data_width(format)) == 0) {
error << _("Bad data width size. Report me!") << endmsg;
return -1;
}
switch (data_width) {
case 8:
dither_size = GDither8bit;
break;
case 16:
dither_size = GDither16bit;
break;
case 24:
dither_size = GDither32bit;
break;
default:
dither_size = GDitherFloat;
break;
}
if (convert_spec_to_info (*this, sfinfo)) {
return -1;
}
/* XXX make sure we have enough disk space for the output */
if ((out = sf_open (path.c_str(), SFM_WRITE, &sfinfo)) == 0) {
sf_error_str (0, errbuf, sizeof (errbuf) - 1);
error << string_compose(_("Export: cannot open output file \"%1\" (%2)"), path, errbuf) << endmsg;
return -1;
}
dataF = new float[blocksize * channels];
if (sample_rate != frame_rate) {
int err;
if ((src_state = src_new (src_quality, channels, &err)) == 0) {
error << string_compose (_("cannot initialize sample rate conversion: %1"), src_strerror (err)) << endmsg;
return -1;
}
src_data.src_ratio = sample_rate / (double) frame_rate;
out_samples_max = (nframes_t) ceil (blocksize * src_data.src_ratio * channels);
dataF2 = new float[out_samples_max];
max_leftover_frames = 4 * blocksize;
leftoverF = new float[max_leftover_frames * channels];
leftover_frames = 0;
} else {
out_samples_max = blocksize * channels;
}
dither = gdither_new (dither_type, channels, dither_size, data_width);
/* allocate buffers where dithering and output will occur */
switch (data_width) {
case 8:
sample_bytes = 1;
break;
case 16:
sample_bytes = 2;
break;
case 24:
case 32:
sample_bytes = 4;
break;
default:
sample_bytes = 0; // float format
break;
}
if (sample_bytes) {
output_data = (void*) malloc (sample_bytes * out_samples_max);
}
pos = start_frame;
end_frame = end_frame;
total_frames = end_frame - start_frame;
running = true;
do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */
return 0;
}
int
ExportSpecification::process (nframes_t nframes)
{
float* float_buffer = 0;
uint32_t chn;
uint32_t x;
uint32_t i;
sf_count_t written;
char errbuf[256];
nframes_t to_write = 0;
int cnt = 0;
do {
/* now do sample rate conversion */
if (sample_rate != frame_rate) {
int err;
src_data.output_frames = out_samples_max / channels;
src_data.end_of_input = ((pos + nframes) >= end_frame);
src_data.data_out = dataF2;
if (leftover_frames > 0) {
/* input data will be in leftoverF rather than dataF */
src_data.data_in = leftoverF;
if (cnt == 0) {
/* first time, append new data from dataF into the leftoverF buffer */
memcpy (leftoverF + (leftover_frames * channels), dataF, nframes * channels * sizeof(float));
src_data.input_frames = nframes + leftover_frames;
} else {
/* otherwise, just use whatever is still left in leftoverF; the contents
were adjusted using memmove() right after the last SRC call (see
below)
*/
src_data.input_frames = leftover_frames;
}
} else {
src_data.data_in = dataF;
src_data.input_frames = nframes;
}
++cnt;
if ((err = src_process (src_state, &src_data)) != 0) {
error << string_compose (_("an error occured during sample rate conversion: %1"),
src_strerror (err))
<< endmsg;
return -1;
}
to_write = src_data.output_frames_gen;
leftover_frames = src_data.input_frames - src_data.input_frames_used;
if (leftover_frames > 0) {
if (leftover_frames > max_leftover_frames) {
error << _("warning, leftover frames overflowed, glitches might occur in output") << endmsg;
leftover_frames = max_leftover_frames;
}
memmove (leftoverF, (char *) (src_data.data_in + (src_data.input_frames_used * channels)),
leftover_frames * channels * sizeof(float));
}
float_buffer = dataF2;
} else {
/* no SRC, keep it simple */
to_write = nframes;
leftover_frames = 0;
float_buffer = dataF;
}
if (output_data) {
memset (output_data, 0, sample_bytes * to_write * channels);
}
switch (data_width) {
case 8:
case 16:
case 24:
for (chn = 0; chn < channels; ++chn) {
gdither_runf (dither, chn, to_write, float_buffer, output_data);
}
break;
case 32:
for (chn = 0; chn < channels; ++chn) {
int *ob = (int *) output_data;
const double int_max = (float) INT_MAX;
const double int_min = (float) INT_MIN;
for (x = 0; x < to_write; ++x) {
i = chn + (x * channels);
if (float_buffer[i] > 1.0f) {
ob[i] = INT_MAX;
} else if (float_buffer[i] < -1.0f) {
ob[i] = INT_MIN;
} else {
if (float_buffer[i] >= 0.0f) {
ob[i] = lrintf (int_max * float_buffer[i]);
} else {
ob[i] = - lrintf (int_min * float_buffer[i]);
}
}
}
}
break;
default:
for (x = 0; x < to_write * channels; ++x) {
if (float_buffer[x] > 1.0f) {
float_buffer[x] = 1.0f;
} else if (float_buffer[x] < -1.0f) {
float_buffer[x] = -1.0f;
}
}
break;
}
/* and export to disk */
switch (data_width) {
case 8:
/* XXXX no way to deliver 8 bit audio to libsndfile */
written = to_write;
break;
case 16:
written = sf_writef_short (out, (short*) output_data, to_write);
break;
case 24:
case 32:
written = sf_writef_int (out, (int*) output_data, to_write);
break;
default:
written = sf_writef_float (out, float_buffer, to_write);
break;
}
if ((nframes_t) written != to_write) {
sf_error_str (out, errbuf, sizeof (errbuf) - 1);
error << string_compose(_("Export: could not write data to output file (%1)"), errbuf) << endmsg;
return -1;
}
} while (leftover_frames >= nframes);
return 0;
}
int
Session::start_export (ExportSpecification& spec)
{
if (!_engine.connected()) {
return -1;
}
if (spec.prepare (current_block_size, frame_rate())) {
return -1;
}
spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec));
cerr << "Start export at pos = " << spec.pos << endl;
return _engine.freewheel (true);
}
int
Session::stop_export (ExportSpecification& spec)
{
/* don't stop freewheeling but do stop paying attention to it for now */
spec.freewheel_connection.disconnect ();
spec.clear (); /* resets running/stop etc */
Exported (spec.path, name());
return 0;
}
int
Session::pre_export ()
{
wait_till_butler_finished ();
/* take everyone out of awrite to avoid disasters */
@@ -489,39 +85,41 @@ Session::pre_export ()
post_export_position = _transport_frame;
Config->set_slave_source (None);
_exporting = true;
export_status.running = true;
export_abort_connection = export_status.Aborting.connect (sigc::mem_fun (*this, &Session::abort_audio_export));
return 0;
}
int
Session::prepare_to_export (ExportSpecification& spec)
int
Session::start_audio_export (nframes_t position, bool realtime)
{
int ret = -1;
/* get everyone to the right position */
{
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
if ((*i)-> seek (spec.start_frame, true)) {
if ((*i)-> seek (position, true)) {
error << string_compose (_("%1: cannot seek to %2 for export"),
(*i)->name(), spec.start_frame)
(*i)->name(), position)
<< endmsg;
goto out;
return -1;
}
}
}
cerr << "Everybdy is at " << spec.start_frame << endl;
/* we just did the core part of a locate() call above, but
for the sake of any GUI, put the _transport_frame in
the right place too.
*/
_transport_frame = spec.start_frame;
_exporting = true;
_transport_frame = position;
_exporting_realtime = realtime;
export_status.stop = false;
/* get transport ready. note how this is calling butler functions
from a non-butler thread. we waited for the butler to stop
@@ -535,136 +133,72 @@ Session::prepare_to_export (ExportSpecification& spec)
post_transport ();
/* we are ready to go ... */
ret = 0;
out:
return ret;
}
int
Session::process_export (nframes_t nframes, ExportSpecification* spec)
{
uint32_t chn;
uint32_t x;
int ret = -1;
nframes_t this_nframes;
cerr << "Export process at pos = " << spec->pos << " _exporting = "
<< _exporting << " running = " << spec->running << " stop = "
<< spec->stop << endl;
/* This is not required to be RT-safe because we are running while freewheeling */
if (spec->do_freewheel == false) {
/* first time in export function: get set up */
if (prepare_to_export (*spec)) {
spec->running = false;
spec->status = -1;
return -1;
}
spec->do_freewheel = true;
}
if (!_exporting) {
/* finished, but still freewheeling */
cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <<endl;
no_roll (nframes, 0);
return 0;
}
if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
cerr << "\tExport ... not running or at end, no_roll() for " << nframes <<endl;
no_roll (nframes, 0);
return stop_export (*spec);
if (!_engine.connected()) {
return -1;
}
/* make sure we've caught up with disk i/o, since
we're running faster than realtime c/o JACK.
*/
wait_till_butler_finished ();
/* do the usual stuff */
process_without_events (nframes);
/* and now export the results */
nframes = this_nframes;
memset (spec->dataF, 0, sizeof (spec->dataF[0]) * nframes * spec->channels);
/* foreach output channel ... */
for (chn = 0; chn < spec->channels; ++chn) {
ExportPortMap::iterator mi = spec->port_map.find (chn);
if (mi == spec->port_map.end()) {
/* no ports exported to this channel */
continue;
}
vector<PortChannelPair>& mapped_ports ((*mi).second);
for (vector<PortChannelPair>::iterator t = mapped_ports.begin(); t != mapped_ports.end(); ++t) {
/* OK, this port's output is supposed to appear on this channel
*/
AudioPort* const aport = dynamic_cast<AudioPort*>((*t).first);
MidiPort* const mport = dynamic_cast<MidiPort*>((*t).first);
if (aport != 0) {
Sample* port_buffer = aport->get_audio_buffer().data();
/* now interleave the data from the channel into the float buffer */
for (x = 0; x < nframes; ++x) {
spec->dataF[chn+(x*spec->channels)] += (float) port_buffer[x];
}
} else if (mport != 0) {
cerr << "EXPORT MIDI PORT" << endl;
}
}
if (realtime) {
last_process_function = process_function;
process_function = &Session::process_export;
} else {
export_freewheel_connection = _engine.Freewheel.connect (sigc::mem_fun (*this, &Session::process_export_fw));
return _engine.freewheel (true);
}
cerr << "\tprocess " << nframes << endl;
if (spec->process (nframes)) {
goto out;
}
spec->pos += nframes;
spec->progress = 1.0 - (((float) spec->end_frame - spec->pos) / spec->total_frames);
cerr << "\t@ " << spec->pos << " prog = " << spec->progress << endl;
/* and we're good to go */
ret = 0;
out:
if (ret) {
sf_close (spec->out);
spec->out = 0;
unlink (spec->path.c_str());
spec->running = false;
spec->status = ret;
_exporting = false;
}
return ret;
return 0;
}
void
Session::finalize_export ()
Session::process_export (nframes_t nframes)
{
_engine.freewheel (false);
_exporting = false;
try {
if (export_status.stop) {
stop_audio_export ();
return;
}
if (!_exporting_realtime) {
/* make sure we've caught up with disk i/o, since
we're running faster than realtime c/o JACK.
*/
wait_till_butler_finished ();
}
/* do the usual stuff */
process_without_events (nframes);
/* handle export */
ProcessExport (nframes);
} catch (ExportFailed e) {
std::cerr << e.what() << std::endl;
stop_audio_export();
finalize_audio_export();
}
}
int
Session::process_export_fw (nframes_t nframes)
{
process_export (nframes);
return 0;
}
int
Session::stop_audio_export ()
{
if (_exporting_realtime) {
process_function = last_process_function;
} else {
export_freewheel_connection.disconnect();
}
/* can't use stop_transport() here because we need
an immediate halt and don't require all the declick
@@ -674,6 +208,33 @@ Session::finalize_export ()
realtime_stop (true);
schedule_butler_transport_work ();
if (!export_status.aborted()) {
ExportFinished ();
}
return 0;
}
void
Session::finalize_audio_export ()
{
_exporting = false;
export_status.running = false;
if (!_exporting_realtime) {
_engine.freewheel (false);
_exporting_realtime = false;
}
/* Clean up */
ProcessExport.clear();
ExportFinished.clear();
export_freewheel_connection.disconnect();
export_abort_connection.disconnect();
export_handler.reset();
/* restart slaving */
if (post_export_slave != None) {
@@ -682,3 +243,10 @@ Session::finalize_export ()
locate (post_export_position, false, false, false);
}
}
void
Session::abort_audio_export ()
{
stop_audio_export ();
finalize_audio_export ();
}

View File

@@ -64,6 +64,7 @@
#include <ardour/session_directory.h>
#include <ardour/session_utils.h>
#include <ardour/session_state_utils.h>
#include <ardour/session_metadata.h>
#include <ardour/buffer.h>
#include <ardour/audio_diskstream.h>
#include <ardour/midi_diskstream.h>
@@ -77,7 +78,6 @@
#include <ardour/midi_source.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/auditioner.h>
#include <ardour/export.h>
#include <ardour/io_processor.h>
#include <ardour/send.h>
#include <ardour/processor.h>
@@ -200,6 +200,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_play_range = false;
waiting_to_start = false;
_exporting = false;
_exporting_realtime = false;
_gain_automation_buffer = 0;
_pan_automation_buffer = 0;
_npan_buffers = 0;
@@ -537,6 +538,10 @@ Session::create (bool& new_session, const string& mix_template, nframes_t initia
}
}
/* Instantiate metadata */
_metadata = new SessionMetadata ();
/* set initial start + end point */
@@ -977,6 +982,8 @@ Session::state(bool full_state)
node->add_child_nocopy (get_options());
node->add_child_nocopy (_metadata->get_state());
child = node->add_child ("Sources");
if (full_state) {
@@ -1202,6 +1209,7 @@ Session::set_state (const XMLNode& node)
Path
extra
Options/Config
Metadata
Locations
Sources
AudioRegions
@@ -1229,6 +1237,12 @@ Session::set_state (const XMLNode& node)
error << _("Session: XML state has no options section") << endmsg;
}
if ((child = find_named_node (node, "Metadata")) == 0) {
warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
} else if (_metadata->set_state (*child)) {
goto out;
}
if ((child = find_named_node (node, "Locations")) == 0) {
error << _("Session: XML state has no locations section") << endmsg;
goto out;
@@ -2895,10 +2909,12 @@ Session::controllable_by_id (const PBD::ID& id)
}
void
Session::add_instant_xml (XMLNode& node)
Session::add_instant_xml (XMLNode& node, bool write_to_config)
{
Stateful::add_instant_xml (node, _path);
Config->add_instant_xml (node);
if (write_to_config) {
Config->add_instant_xml (node);
}
}
XMLNode*

View File

@@ -568,7 +568,7 @@ Session::jack_timebase_callback (jack_transport_state_t state,
}
ARDOUR::nframes_t
Session::convert_to_frames_at (nframes_t position, AnyTime& any)
Session::convert_to_frames_at (nframes_t position, AnyTime const & any)
{
double secs;

View File

@@ -1,14 +0,0 @@
The main author of libsndfile is Erik de Castro Lopo <erikd@mega-nerd.com>.
The code in the src/GSM610 directory was written by Jutta Degener
<jutta@cs.tu-berlin.de> and Carsten Bormann <cabo@cs.tu-berlin.de>.
They should not be contacted in relation to libsndfile or the GSM 6.10 code
that is part of libsndfile. Their original code can be found at:
http://kbs.cs.tu-berlin.de/~jutta/toast.html
Code in the src/G72x directory was released by Sun Microsystems, Inc. to the
public domain. Minor modifications were required to integrate these files
into libsndfile. The changes are listed in src/G72x/ChangeLog.

File diff suppressed because it is too large Load Diff

View File

@@ -1,113 +0,0 @@
#!/bin/sh
# Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the author nor the names of any contributors may be used
# to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
echo "Usage : Mingw-make-dist.sh <source tarball>."
exit 1
fi
TARGZ=$1
if [ ! -f $TARGZ ]; then
echo "Can't find source tarball."
fi
TARGZ=$1
if [ ! -f $TARGZ.asc ]; then
echo "Can't find source tarball signature."
fi
UNAME=`uname -s`
if [ x$UNAME != "xMINGW32_NT-5.1" ]; then
echo "Not able to build Win32 binaries on this platform."
fi
echo "Building MinGW binary/source zip file."
VERSION=`pwd | sed -e "s#.*/##" | sed -e s/libsndfile-//`
BUILD=`echo $VERSION | sed -e "s/\./_/g"`
INSTALL="libsndfile-$BUILD"
ZIPNAME="$INSTALL.zip"
if [ -z "$BUILD" ]; then
echo "Bad BUILD variable : '$BUILD'"
exit 1
fi
if [ ! -d $INSTALL/ ]; then
mkdir $INSTALL
fi
if [ ! -f config.status ]; then
./configure --prefix=`pwd`/$INSTALL/
else
teststr=`grep "with options" config.status | grep -- --prefix=`
if [ -z "$teststr" ]; then
# --disable-static doesn't work.
./configure --prefix=`pwd`/$INSTALL/
fi
fi
if [ ! -f src/.libs/libsndfile-1.dll ]; then
make all check
fi
if [ ! -f $INSTALL/bin/libsndfile-1.dll ]; then
make install
rm -f $INSTALL/bin/sndfile-regtest.exe
strip $INSTALL/bin/*.*
mv $INSTALL/bin/*.* $INSTALL/include/*.* $INSTALL/
rmdir $INSTALL/bin
rm -rf $INSTALL/lib
rmdir $INSTALL/include
cp src/libsndfile.def $INSTALL/
cp Win32/README-precompiled-dll.txt $INSTALL/
fi
if [ ! -f $INSTALL/libsndfile-$VERSION.tar.gz ]; then
cp $TARGZ $INSTALL/
if [ -f $TARGZ.asc ]; then
cp $TARGZ.asc $INSTALL/
fi
fi
if [ ! -f $ZIPNAME ]; then
zip -r $ZIPNAME $INSTALL/
fi
# Do not edit or modify anything in this comment block.
# The following line is a file identity tag for the GNU Arch
# revision control system.
#
# arch-tag: 3f82cd8a-f800-48d7-9646-2cdcf03c81a0

View File

@@ -1,126 +0,0 @@
Version 1.0.16 (2006-04-30)
* Add support for Broadcast (BEXT) chunks in WAV files.
* Implement new commands SFC_GET_SIGNAL_MAX and SFC_GET_MAX_ALL_CHANNELS.
* Add support for RIFX (big endian WAV variant).
* Fix configure script bugs.
* Fix bug in INST and MARK chunk writing for AIFF files.
Version 1.0.15 (2006-03-16)
* Fix some ia64 issues.
* Fix precompiled DLL.
* Minor bug fixes.
Version 1.0.14 (2006-02-19)
* Really fix MinGW compile problems.
* Minor bug fixes.
Version 1.0.13 (2006-01-21)
* Fix for MinGW compiler problems.
* Allow readin/write of instrument chunks from WAV and AIFF files.
* Compile problem fix for Solaris compiler.
* Minor cleanups and bug fixes.
Version 1.0.12 (2005-09-30)
* Add support for FLAC and Apple's Core Audio Format (CAF).
* Add virtual I/O interface (still needs docs).
* Cygwin and other Win32 fixes.
* Minor bug fixes and cleanups.
Version 1.0.11 (2004-11-15)
* Add support for SD2 files.
* Add read support for loop info in WAV and AIFF files.
* Add more tests.
* Improve type safety.
* Minor optimisations and bug fixes.
Version 1.0.10 (2004-06-15)
* Fix AIFF read/write mode bugs.
* Add support for compiling Win32 DLLS using MinGW.
* Fix problems resulting in failed compiles with gcc-2.95.
* Improve test suite.
* Minor bug fixes.
Version 1.0.9 (2004-03-30)
* Add handling of AVR (Audio Visual Research) files.
* Improve handling of WAVEFORMATEXTENSIBLE WAV files.
* Fix for using pipes on Win32.
Version 1.0.8 (2004-03-14)
* Correct peak chunk handing for files with > 16 tracks.
* Fix for WAV files with huge number of CUE chunks.
Version 1.0.7 (2004-02-25)
* Fix clip mode detection on ia64, MIPS and other CPUs.
* Fix two MacOSX build problems.
Version 1.0.6 (2004-02-08)
* Added support for native Win32 file access API (Ross Bencina).
* New mode to add clippling then a converting from float/double to integer
would otherwise wrap around.
* Fixed a bug in reading/writing files > 2Gig on Linux, Solaris and others.
* Many minor bug fixes.
* Other random fixes for Win32.
Version 1.0.5 (2003-05-03)
* Added support for HTK files.
* Added new function sf_open_fd() to allow for secure opening of temporary
files as well as reading/writing sound files embedded within larger
container files.
* Added string support for AIFF files.
* Minor bug fixes and code cleanups.
Version 1.0.4 (2003-02-02)
* Added suport of PVF and XI files.
* Added functionality for setting and retreiving strings from sound files.
* Minor code cleanups and bug fixes.
Version 1.0.3 (2002-12-09)
* Minor bug fixes.
Version 1.0.2 (2002-11-24)
* Added support for VOX ADPCM.
* Improved error reporting.
* Added version scripting on Linux and Solaris.
* Minor bug fixes.
Version 1.0.1 (2002-09-14)
* Added MAT and MAT5 file formats.
* Minor bug fixes.
Version 1.0.0 (2002-08-16)
* Final release for 1.0.0.
Version 1.0.0rc6 (2002-08-14)
* Release candidate 6 for the 1.0.0 series.
* MacOS9 fixes.
Version 1.0.0rc5 (2002-08-10)
* Release candidate 5 for the 1.0.0 series.
* Changed the definition of sf_count_t which was causing problems when
libsndfile was compiled with other libraries (ie WxWindows).
* Minor bug fixes.
* Documentation cleanup.
Version 1.0.0rc4 (2002-08-03)
* Release candidate 4 for the 1.0.0 series.
* Minor bug fixes.
* Fix broken Win32 "make check".
Version 1.0.0rc3 (2002-08-02)
* Release candidate 3 for the 1.0.0 series.
* Fix bug where libsndfile was reading beyond the end of the data chunk.
* Added on-the-fly header updates on write.
* Fix a couple of documentation issues.
Version 1.0.0rc2 (2002-06-24)
* Release candidate 2 for the 1.0.0 series.
* Fix compile problem for Win32.
Version 1.0.0rc1 (2002-06-24)
* Release candidate 1 for the 1.0.0 series.
Version 0.0.28 (2002-04-27)
* Last offical release of 0.0.X series of the library.
Version 0.0.8 (1999-02-16)
* First offical release.

View File

@@ -1,71 +0,0 @@
This is libsndfile, 1.0.16
libsndfile is a library of C routines for reading and writing
files containing sampled audio data.
The src/ directory contains the source code for library itself.
The doc/ directory contains the libsndfile documentation.
The examples/ directory contains examples of how to write code using
libsndfile. 'wav32_aiff24' converts a WAV file containing 32 bit floating
point data into a 24 bit PCM AIFF file. 'sndfile2oct' dumps the audio
data of a file in a human readable format. 'sfconvert' is the beginnings
of a audio file format conversion utility. 'make_sine' generates a WAV
file containing one cycle of a sine wave with 4096 sample points in
32 bit floating point format. 'sfinfo' opens a sound file and prints
out information about that file.
The tests/ directory contains programs which link against libsndfile
and test its functionality.
The Win32/ directory contains files and documentation to allow libsndfile
to compile under Win32 with the Microsoft Visual C++ compiler.
The src/GSM610 directory contains code written by Jutta Degener and Carsten
Bormann. Their original code can be found at :
http://kbs.cs.tu-berlin.de/~jutta/toast.html
The src/G72x directory contains code written and released by Sun Microsystems
under a suitably free license.
Win32
-----
There are detailed instructions for building libsndfile on Win32 in the file
doc/win32.html
MacOSX
------
Building on MacOSX should be the same as building it on any other Unix.
OTHER PLATFORMS
---------------
To compile libsndfile on platforms which have a Bourne Shell compatible
shell, an ANSI C compiler and a make utility should require no more that
the following three commands :
./configure
make
make install
For platforms without the required shell, it is usually sufficient to
create an approriate config.h file in the src/ directory with correct
values for the following #defines (this would work for AmigaOS) :
#define HAVE_ENDIAN_H 0
#define GUESS_BIG_ENDIAN 1
#define GUESS_LITTLE_ENDIAN 0
#define FORCE_BROKEN_FLOAT 0
CONTACTS
--------
libsndfile was written by Erik de Castro Lopo (erikd AT mega-nerd DOT com).
The libsndfile home page is at :
http://www.mega-nerd.com/libsndfile/

View File

@@ -1,56 +0,0 @@
# -*- python -*-
import os
import os.path
import glob
sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
Import('env install_prefix libraries use_flac')
sndfile = env.Clone()
if use_flac:
sndfile.Merge([libraries['flac'] ])
domain = 'libsndfile'
sndfile.Append(CCFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"")
sndfile.Append(CCFLAGS = "-DVERSION=\\\"ardour-special\\\"")
# mingw may need this
#sndfile.Append(CCFLAGS="-no-undefined")
sndfile.Append(PACKAGE = domain)
sndfile.Append(POTFILE = domain + '.pot')
conf = Configure(sndfile)
if conf.CheckCHeader('/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h'):
sndfile.Append(LINKFLAGS = "-framework CoreServices")
sndfile = conf.Finish()
libsndfile = sndfile.SharedLibrary('sndfile-ardour', sndfile_files)
if use_flac:
sndfile_h = sndfile.Command('src/sndfile.h', ['src/sndfile.h.in'], 'cd libs/libsndfile && ./configure && cd -', ENV=os.environ)
else:
sndfile_h = sndfile.Command('src/sndfile.h', ['src/sndfile.h.in'], 'cd libs/libsndfile && ./configure --disable-flac && cd -', ENV=os.environ)
Default([sndfile_h,libsndfile])
env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour3'), libsndfile))
env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
'configure', 'SConscript',
'install-sh',
'libsndfile.spec.in',
'sndfile.pc.in',
'config.sub',
'config.guess'
] +
sndfile_files +
glob.glob('src/*.h') +
glob.glob('src/GSM610/*.h') +
glob.glob('src/G72x/*.h') +
[ 'src/sndfile.h.in', 'src/config.h.in', 'src/Symbols.linux', 'src/Symbols.darwin', 'src/libsndfile.def', 'src/cygsndfile.def' ]
))

View File

@@ -1,579 +0,0 @@
dnl By default, many hosts won't let programs access large files;
dnl one must use special compiler options to get large-file access to work.
dnl For more details about this brain damage please see:
dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
dnl Written by Paul Eggert <eggert@twinsun.com>.
dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME)
AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS],
[AC_CACHE_CHECK([for $1 value to request large file support],
ac_cv_sys_largefile_$1,
[ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || {
ac_cv_sys_largefile_$1=no
ifelse($1, CFLAGS,
[case "$host_os" in
# IRIX 6.2 and later require cc -n32.
changequote(, )dnl
irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
changequote([, ])dnl
if test "$GCC" != yes; then
ac_cv_sys_largefile_CFLAGS=-n32
fi
ac_save_CC="$CC"
CC="$CC $ac_cv_sys_largefile_CFLAGS"
AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no)
CC="$ac_save_CC"
esac])
}])])
dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL)
AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND],
[case $2 in
no) ;;
?*)
case "[$]$1" in
'') $1=$2 ;;
*) $1=[$]$1' '$2 ;;
esac ;;
esac])
dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT)
AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE],
[AC_CACHE_CHECK([for $1], $2,
[$2=no
changequote(, )dnl
$4
for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
case "$ac_flag" in
-D$1)
$2=1 ;;
-D$1=*)
$2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
esac
done
changequote([, ])dnl
])
if test "[$]$2" != no; then
AC_DEFINE_UNQUOTED([$1], [$]$2, [$3])
fi])
AC_DEFUN([AC_SYS_EXTRA_LARGEFILE],
[AC_REQUIRE([AC_CANONICAL_HOST])
AC_ARG_ENABLE(largefile,
[ --disable-largefile omit support for large files])
if test "$enable_largefile" != no; then
AC_CHECK_TOOL(GETCONF, getconf)
AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS)
AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS)
AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS)
for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
case "$ac_flag" in
no) ;;
-D_FILE_OFFSET_BITS=*) ;;
-D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
-D_LARGE_FILES | -D_LARGE_FILES=*) ;;
-D?* | -I?*)
AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;;
*)
AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;;
esac
done
AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS")
AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS")
AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS,
ac_cv_sys_file_offset_bits,
[Number of bits in a file offset, on hosts where this is settable.])
[case "$host_os" in
# HP-UX 10.20 and later
hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
ac_cv_sys_file_offset_bits=64 ;;
esac]
AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE,
ac_cv_sys_largefile_source,
[Define to make fseeko etc. visible, on some hosts.],
[case "$host_os" in
# HP-UX 10.20 and later
hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
ac_cv_sys_largefile_source=1 ;;
esac])
AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES,
ac_cv_sys_large_files,
[Define for large files, on AIX-style hosts.],
[case "$host_os" in
# AIX 4.2 and later
aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*)
ac_cv_sys_large_files=1 ;;
esac])
fi
])
dnl @synopsis AC_C_FIND_ENDIAN
dnl
dnl Determine endian-ness of target processor.
dnl @version 1.1 Mar 03 2002
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Majority written from scratch to replace the standard autoconf macro
dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation
dnl of the AC_TRY_RUN macro.
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl Find endian-ness in the following way:
dnl 1) Look in <endian.h>.
dnl 2) If 1) fails, look in <sys/types.h> and <sys/param.h>.
dnl 3) If 1) and 2) fails and not cross compiling run a test program.
dnl 4) If 1) and 2) fails and cross compiling then guess based on target.
AC_DEFUN([AC_C_FIND_ENDIAN],
[AC_CACHE_CHECK(processor byte ordering,
ac_cv_c_byte_order,
# Initialize to unknown
ac_cv_c_byte_order=unknown
if test x$ac_cv_header_endian_h = xyes ; then
# First try <endian.h> which should set BYTE_ORDER.
[AC_TRY_LINK([
#include <endian.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <endian.h>
#if BYTE_ORDER != BIG_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=big
)]
fi
if test $ac_cv_c_byte_order = unknown ; then
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
bogus endian macros
#endif
], return 0 ;,
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
[AC_TRY_LINK([
#include <sys/types.h>
#include <sys/param.h>
#if BYTE_ORDER != LITTLE_ENDIAN
not big endian
#endif
], return 0 ;,
ac_cv_c_byte_order=little
)]
)]
fi
if test $ac_cv_c_byte_order = unknown ; then
if test $cross_compiling = yes ; then
# This is the last resort. Try to guess the target processor endian-ness
# by looking at the target CPU type.
[
case "$target_cpu" in
alpha* | i?86* | mipsel* | ia64*)
ac_cv_c_big_endian=0
ac_cv_c_little_endian=1
;;
m68* | mips* | powerpc* | hppa* | sparc*)
ac_cv_c_big_endian=1
ac_cv_c_little_endian=0
;;
esac
]
else
AC_TRY_RUN(
[[
int main (void)
{ /* Are we little or big endian? From Harbison&Steele. */
union
{ long l ;
char c [sizeof (long)] ;
} u ;
u.l = 1 ;
return (u.c [sizeof (long) - 1] == 1);
}
]], , ac_cv_c_byte_order=big,
ac_cv_c_byte_order=unknown
)
AC_TRY_RUN(
[[int main (void)
{ /* Are we little or big endian? From Harbison&Steele. */
union
{ long l ;
char c [sizeof (long)] ;
} u ;
u.l = 1 ;
return (u.c [0] == 1);
}]], , ac_cv_c_byte_order=little,
ac_cv_c_byte_order=unknown
)
fi
fi
)
]
if test $ac_cv_c_byte_order = big ; then
ac_cv_c_big_endian=1
ac_cv_c_little_endian=0
elif test $ac_cv_c_byte_order = little ; then
ac_cv_c_big_endian=0
ac_cv_c_little_endian=1
else
ac_cv_c_big_endian=0
ac_cv_c_little_endian=0
AC_MSG_WARN([[*****************************************************************]])
AC_MSG_WARN([[*** Not able to determine endian-ness of target processor. ]])
AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in ]])
AC_MSG_WARN([[*** src/config.h may need to be hand editied. ]])
AC_MSG_WARN([[*****************************************************************]])
fi
)# AC_C_FIND_ENDIAN
dnl @synopsis AC_C99_FLEXIBLE_ARRAY
dnl
dnl Dose the compiler support the 1999 ISO C Standard "stuct hack".
dnl @version 1.1 Mar 15 2004
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
AC_DEFUN([AC_C99_FLEXIBLE_ARRAY],
[AC_CACHE_CHECK(C99 struct flexible array support,
ac_cv_c99_flexible_array,
# Initialize to unknown
ac_cv_c99_flexible_array=no
AC_TRY_LINK([[
#include <stdlib.h>
typedef struct {
int k;
char buffer [] ;
} MY_STRUCT ;
]],
[ MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ],
ac_cv_c99_flexible_array=yes,
ac_cv_c99_flexible_array=no
))]
) # AC_C99_FLEXIBLE_ARRAY
dnl @synopsis AC_C99_FUNC_LRINT
dnl
dnl Check whether C99's lrint function is available.
dnl @version 1.3 Feb 12 2002
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl
AC_DEFUN([AC_C99_FUNC_LRINT],
[AC_CACHE_CHECK(for lrint,
ac_cv_c99_lrint,
[
lrint_save_CFLAGS=$CFLAGS
CFLAGS="-O2 -lm"
AC_TRY_LINK([
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)
CFLAGS=$lrint_save_CFLAGS
])
if test "$ac_cv_c99_lrint" = yes; then
AC_DEFINE(HAVE_LRINT, 1,
[Define if you have C99's lrint function.])
fi
])# AC_C99_FUNC_LRINT
dnl @synopsis AC_C99_FUNC_LRINTF
dnl
dnl Check whether C99's lrintf function is available.
dnl @version 1.3 Feb 12 2002
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl
AC_DEFUN([AC_C99_FUNC_LRINTF],
[AC_CACHE_CHECK(for lrintf,
ac_cv_c99_lrintf,
[
lrintf_save_CFLAGS=$CFLAGS
CFLAGS="-O2 -lm"
AC_TRY_LINK([
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)
CFLAGS=$lrintf_save_CFLAGS
])
if test "$ac_cv_c99_lrintf" = yes; then
AC_DEFINE(HAVE_LRINTF, 1,
[Define if you have C99's lrintf function.])
fi
])# AC_C99_FUNC_LRINTF
dnl @synopsis AC_C99_FUNC_LLRINT
dnl
dnl Check whether C99's llrint function is available.
dnl @version 1.1 Sep 30 2002
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl
AC_DEFUN([AC_C99_FUNC_LLRINT],
[AC_CACHE_CHECK(for llrint,
ac_cv_c99_llrint,
[
llrint_save_CFLAGS=$CFLAGS
CFLAGS="-O2 -lm"
AC_TRY_LINK([
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
#include <stdint.h>
], int64_t x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no)
CFLAGS=$llrint_save_CFLAGS
])
if test "$ac_cv_c99_llrint" = yes; then
AC_DEFINE(HAVE_LLRINT, 1,
[Define if you have C99's llrint function.])
fi
])# AC_C99_FUNC_LLRINT
dnl @synopsis AC_C_CLIP_MODE
dnl
dnl Determine the clipping mode when converting float to int.
dnl @version 1.0 May 17 2003
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl Find the clipping mode in the following way:
dnl 1) If we are not cross compiling test it.
dnl 2) IF we are cross compiling, assume that clipping isn't done correctly.
AC_DEFUN([AC_C_CLIP_MODE],
[AC_CACHE_CHECK(processor clipping capabilities,
ac_cv_c_clip_type,
# Initialize to unknown
ac_cv_c_clip_positive=unknown
ac_cv_c_clip_negative=unknown
if test $ac_cv_c_clip_positive = unknown ; then
AC_TRY_RUN(
[[
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = 1.0 * 0x7FFFFFFF ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != 127)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
]],
ac_cv_c_clip_positive=yes,
ac_cv_c_clip_positive=no,
ac_cv_c_clip_positive=unknown
)
AC_TRY_RUN(
[[
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = -8.0 * 0x10000000 ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != -128)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
]],
ac_cv_c_clip_negative=yes,
ac_cv_c_clip_negative=no,
ac_cv_c_clip_negative=unknown
)
fi
if test $ac_cv_c_clip_positive = yes ; then
ac_cv_c_clip_positive=1
else
ac_cv_c_clip_positive=0
fi
if test $ac_cv_c_clip_negative = yes ; then
ac_cv_c_clip_negative=1
else
ac_cv_c_clip_negative=0
fi
[[
case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
"00")
ac_cv_c_clip_type="none"
;;
"10")
ac_cv_c_clip_type="positive"
;;
"01")
ac_cv_c_clip_type="negative"
;;
"11")
ac_cv_c_clip_type="both"
;;
esac
]]
)
]
)# AC_C_CLIP_MODE
dnl @synopsis AC_ADD_CFLAGS
dnl
dnl Add the given option to CFLAGS, if it doesn't break the compiler
AC_DEFUN([AC_ADD_CFLAGS],
[AC_MSG_CHECKING([if $CC accepts $1])
ac_add_cflags__old_cflags="$CFLAGS"
CFLAGS="$CFLAGS $1"
AC_TRY_LINK([#include <stdio.h>],
[printf("Hello, World!\n"); return 0;],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
CFLAGS="$ac_add_cflags__old_cflags")
])
ifelse(dnl
Do not edit or modify anything in this comment block.
The arch-tag line is a file identity tag for the GNU Arch
revision control system.
arch-tag: bc38294d-bb5c-42ad-90b9-779def5eaab7
)dnl

View File

@@ -1,107 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
# Copyright 1999, 2000 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Usage:
# compile PROGRAM [ARGS]...
# `-o FOO.o' is removed from the args passed to the actual compile.
# Usage statement added by Billy Biggs <vektor@dumbterm.net>.
if [ -z $1 ]; then
echo "Wrapper for compilers which do not understand '-c -o'."
echo "usage: compile PROGRAM [ARGS]..."
echo "'-o FOO.o' is removed from the args passed to the actual compile."
exit 1
fi
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status

13933
libs/libsndfile/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,541 +0,0 @@
# Copyright (C) 1999-2006 Erik de Castro Lopo (erikd AT mega-nerd DOT com).
dnl Require autoconf version
AC_PREREQ(2.59)
AC_INIT([libsndfile],[ardour-special],[ardour@ardour.org])
AC_CONFIG_SRCDIR([src/sndfile.c])
AC_CANONICAL_TARGET([])
AC_CONFIG_HEADERS(src/config.h)
AC_LANG([C])
#------------------------------------------------------------------------------------
# Rules for library version information:
#
# 1. Start with version information of `0:0:0' for each libtool library.
# 2. Update the version information only immediately before a public release of
# your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
# 3. If the library source code has changed at all since the last update, then
# increment revision (`c:r:a' becomes `c:r+1:a').
# 4. If any interfaces have been added, removed, or changed since the last update,
# increment current, and set revision to 0.
# 5. If any interfaces have been added since the last public release, then increment
# age.
# 6. If any interfaces have been removed since the last public release, then set age
# to 0.
SHARED_VERSION_INFO="1:16:0"
AC_PROG_CC
#AM_PROG_LIBTOOL
AC_CHECK_PROG(autogen, autogen, yes, no)
AC_PROG_INSTALL
AC_PROG_LN_S
AC_HEADER_STDC
AC_CHECK_HEADERS(endian.h)
AC_CHECK_HEADERS(byteswap.h)
AC_CHECK_HEADERS(locale.h)
AC_CHECK_HEADERS(inttypes.h)
AC_HEADER_SYS_WAIT
AC_CHECK_DECLS(S_IRGRP)
AC_DEFINE_UNQUOTED([HAVE_DECL_S_IRGRP],${HAVE_DECL_S_IRGRP},
[Set to 1 if S_IRGRP is defined.])
#====================================================================================
# Check for support of the struct hack.
AC_C99_FLEXIBLE_ARRAY
if test x$ac_cv_c99_flexible_array = xyes ; then
AC_DEFINE([HAVE_FLEXIBLE_ARRAY],1, [Set to 1 if the compile supports the struct hack.])
else
AC_MSG_WARN([[*** This compiler does not support the 1999 ISO C Standard ***]])
AC_MSG_WARN([[*** feature known as the flexible array struct member. ***]])
AC_DEFINE([HAVE_FLEXIBLE_ARRAY],0)
fi
#====================================================================================
# Couple of initializations here. Fill in real values later.
SHLIB_VERSION_ARG=""
#====================================================================================
# Finished checking, handle options.
AC_ARG_ENABLE(experimental,
AC_HELP_STRING([--enable-experimental], [enable experimental code]))
EXPERIMENTAL_CODE=0
if test x$enable_experimental = xyes ; then
EXPERIMENTAL_CODE=1
fi
AC_DEFINE_UNQUOTED([ENABLE_EXPERIMENTAL_CODE],${EXPERIMENTAL_CODE}, [Set to 1 to enable experimental code.])
AC_ARG_ENABLE(gcc-werror,
AC_HELP_STRING([--enable-gcc-werror], [enable -Werror in all Makefiles]))
AC_ARG_ENABLE(gcc-pipe,
AC_HELP_STRING([--disable-gcc-pipe], [disable gcc -pipe option]))
AC_ARG_ENABLE(gcc-opt,
AC_HELP_STRING([--disable-gcc-opt], [disable gcc optimisations]))
AC_ARG_ENABLE(cpu-clip,
AC_HELP_STRING([--disable-cpu-clip], [disable tricky cpu specific clipper]))
AC_ARG_ENABLE(bow-docs,
AC_HELP_STRING([--enable-bow-docs], [enable black-on-white html docs]))
AC_ARG_ENABLE(sqlite,
AC_HELP_STRING([--disable-sqlite], [disable use of sqlite]))
AC_ARG_ENABLE(flac,
AC_HELP_STRING([--disable-flac], [disable use of FLAC]))
AC_ARG_ENABLE(alsa,
AC_HELP_STRING([--disable-alsa], [disable use of ALSA]))
#====================================================================================
# Check types and their sizes.
AC_CHECK_SIZEOF(short,2)
AC_CHECK_SIZEOF(int,4)
AC_CHECK_SIZEOF(long,4)
AC_CHECK_SIZEOF(float,4)
AC_CHECK_SIZEOF(double,4)
AC_CHECK_SIZEOF(void*,8)
AC_CHECK_SIZEOF(size_t,4)
AC_CHECK_SIZEOF(int64_t,8)
AC_CHECK_SIZEOF(long long,8)
#====================================================================================
# Find an appropriate type for sf_count_t.
# On systems supporting files larger than 2 Gig, sf_count_t must be a 64 bit value.
# Unfortunately there is more than one way of ensuring this so need to do some
# pretty rigourous testing here.
unset ac_cv_sizeof_off_t
AC_CHECK_SIZEOF(off_t,1) # Fake default value.
case "$host_os" in
mingw*)
TYPEOF_SF_COUNT_T="__int64"
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
SIZEOF_SF_COUNT_T=8
;;
*)
if test "x$ac_cv_sizeof_off_t" = "x8" ; then
# If sizeof (off_t) is 8, no further checking is needed.
TYPEOF_SF_COUNT_T="off_t"
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
SIZEOF_SF_COUNT_T=8
else
# Check for common 64 bit file offset types.
AC_CHECK_SIZEOF(loff_t,1) # Fake default value.
AC_CHECK_SIZEOF(off64_t,1) # Fake default value.
TYPEOF_SF_COUNT_T="unknown"
if test "x$ac_cv_sizeof_loff_t" = "x8" ; then
TYPEOF_SF_COUNT_T="loff_t"
SIZEOF_SF_COUNT_T=8
elif test "x$ac_cv_sizeof_off64_t" = "x8" ; then
TYPEOF_SF_COUNT_T="off64_t"
SIZEOF_SF_COUNT_T=8
fi
# Save the old sizeof (off_t) value and then unset it to see if it
# changes when Large File Support is enabled.
pre_largefile_sizeof_off_t=$ac_cv_sizeof_off_t
unset ac_cv_sizeof_off_t
AC_SYS_EXTRA_LARGEFILE
if test "x$ac_cv_sys_largefile_CFLAGS" = "xno" ; then
ac_cv_sys_largefile_CFLAGS=""
fi
if test "x$ac_cv_sys_largefile_LDFLAGS" = "xno" ; then
ac_cv_sys_largefile_LDFLAGS=""
fi
if test "x$ac_cv_sys_largefile_LIBS" = "xno" ; then
ac_cv_sys_largefile_LIBS=""
fi
AC_CHECK_SIZEOF(off_t,1) # Fake default value.
if test "x$ac_cv_sizeof_off_t" = "x8" ; then
SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
elif test "x$ac_cv_sizeof_off_t" = "x$pre_largefile_sizeof_off_t" ; then
AC_MSG_WARN([[This machine does not seem to support 64 bit file offsets.]])
TYPEOF_SF_COUNT_T="off_t"
SIZEOF_SF_COUNT_T=$ac_cv_sizeof_off_t
elif test "x$TYPEOF_SF_COUNT_T" = "xunknown" ; then
echo
echo "*** The configure process has determined that this system is capable"
echo "*** of Large File Support but has not been able to find a type which"
echo "*** is an unambiguous 64 bit file offset."
echo "*** Please contact the author to help resolve this problem."
echo
AC_MSG_ERROR([[Bad file offset type.]])
fi
fi
;;
esac
if test $SIZEOF_SF_COUNT_T = 4 ; then
SF_COUNT_MAX="0x7FFFFFFF"
fi
AC_DEFINE_UNQUOTED([TYPEOF_SF_COUNT_T],${TYPEOF_SF_COUNT_T}, [Set to long if unknown.])
AC_SUBST(TYPEOF_SF_COUNT_T)
AC_DEFINE_UNQUOTED([SIZEOF_SF_COUNT_T],${SIZEOF_SF_COUNT_T}, [Set to sizeof (long) if unknown.])
AC_SUBST(SIZEOF_SF_COUNT_T)
AC_DEFINE_UNQUOTED([SF_COUNT_MAX],${SF_COUNT_MAX}, [Set to maximum allowed value of sf_count_t type.])
AC_SUBST(SF_COUNT_MAX)
AC_CHECK_TYPES(ssize_t)
AC_CHECK_SIZEOF(ssize_t,4)
#====================================================================================
# Determine endian-ness of target processor.
AC_C_FIND_ENDIAN
AC_DEFINE_UNQUOTED(CPU_IS_BIG_ENDIAN, ${ac_cv_c_big_endian},
[Target processor is big endian.])
AC_DEFINE_UNQUOTED(CPU_IS_LITTLE_ENDIAN, ${ac_cv_c_little_endian},
[Target processor is little endian.])
#====================================================================================
# Check for functions.
AC_CHECK_FUNCS(malloc calloc realloc free)
AC_CHECK_FUNCS(open read write lseek pread pwrite)
AC_CHECK_FUNCS(fstat ftruncate fsync fdatasync)
AC_CHECK_FUNCS(snprintf vsnprintf)
AC_CHECK_FUNCS(gmtime gmtime_r)
AC_CHECK_FUNCS(mmap getpagesize)
AC_CHECK_FUNCS(setlocale)
AC_CHECK_LIB([m],floor)
AC_CHECK_FUNCS(floor ceil fmod)
case "$host_os" in
cygwin*)
AC_MSG_WARN([[Not using built-in lrint() and lrintf() because they are broken on Cygwin.]])
;;
*)
AC_C99_FUNC_LRINT
AC_C99_FUNC_LRINTF
if test "x$ac_cv_c99_lrint" = "xno" ; then
if test "x$ac_cv_c99_lrintf" = "xno" ; then
AC_MSG_WARN([[*** Missing C99 standard functions lrint() and lrintf().]])
AC_MSG_WARN([[*** This may cause benign compiler warnings on some systems (ie Solaris).]])
fi
fi
;;
esac
#====================================================================================
# Check for libsqlite3 (only used in regtest).
ac_cv_sqlite3=no
if test x$enable_sqlite != xno ; then
PKG_CHECK_MODULES(SQLITE3, sqlite3 >= 3.2, ac_cv_sqlite3=yes, ac_cv_sqlite3=no)
fi
if test x$ac_cv_sqlite3 = "xyes" ; then
HAVE_SQLITE3=1
else
HAVE_SQLITE3=0
fi
AC_DEFINE_UNQUOTED([HAVE_SQLITE3],$HAVE_SQLITE3,[Set to 1 if you have libsqlite3.])
#====================================================================================
# Determine if the processor can do clipping on float to int conversions.
if test x$enable_cpu_clip != "xno" ; then
AC_C_CLIP_MODE
else
echo "checking processor clipping capabilities... disabled"
ac_cv_c_clip_positive=0
ac_cv_c_clip_negative=0
fi
AC_DEFINE_UNQUOTED(CPU_CLIPS_POSITIVE, ${ac_cv_c_clip_positive},
[Target processor clips on positive float to int conversion.])
AC_DEFINE_UNQUOTED(CPU_CLIPS_NEGATIVE, ${ac_cv_c_clip_negative},
[Target processor clips on negative float to int conversion.])
#====================================================================================
# Target OS specific stuff.
OS_SPECIFIC_CFLAGS=""
OS_SPECIFIC_LINKS=""
os_is_win32=0
os_is_macosx=0
use_windows_api=0
case "$host_os" in
darwin* | rhapsody*)
os_is_macosx=1
OS_SPECIFIC_CFLAGS="-fpascal-strings -I/Developer/Headers/FlatCarbon"
OS_SPECIFIC_LINKS="-framework CoreAudio"
;;
mingw*)
os_is_win32=1
use_windows_api=1
OS_SPECIFIC_LINKS="-lwinmm"
;;
cygwin*)
os_is_win32=1
OS_SPECIFIC_LINKS="-lwinmm"
;;
esac
AC_DEFINE_UNQUOTED(OS_IS_WIN32, ${os_is_win32}, [Set to 1 if compiling for Win32])
AC_DEFINE_UNQUOTED(OS_IS_MACOSX, ${os_is_macosx}, [Set to 1 if compiling for MacOSX])
AC_DEFINE_UNQUOTED(USE_WINDOWS_API, ${use_windows_api}, [Set to 1 to use the native windows API])
#====================================================================================
# Check for ALSA.
ALSA_LIBS=""
if test x$enable_alsa != xno ; then
AC_CHECK_HEADERS(alsa/asoundlib.h)
if test x$ac_cv_header_alsa_asoundlib_h = xyes ; then
ALSA_LIBS="-lasound"
fi
fi
#====================================================================================
# Check for FLAC
FLAC_LIBS=""
if test x$enable_flac != xno ; then
AC_CHECK_HEADERS(FLAC/all.h)
if test x$ac_cv_header_FLAC_all_h = xyes ; then
AC_CHECK_LIB(FLAC, FLAC__seekable_stream_encoder_set_tell_callback, HAVE_FLAC_1_1_1="yes")
if test "x$HAVE_FLAC_1_1_1" = xyes ; then
AC_DEFINE(HAVE_FLAC_1_1_1, [1], [Define to 1 if you have libflac 1.1.1])
fi
FLAC_LIBS="-lFLAC"
fi
fi
#====================================================================================
# Test for sanity when cross-compiling.
if test x$cross_compiling = xyes ; then
AC_MSG_WARN([[******************************************************************]])
AC_MSG_WARN([[*** We are cross-compiling, so have to assume sizeof (short) == 2 ]])
AC_MSG_WARN([[*** and sizeof (int) == 4. If this is not the case there is no ]])
AC_MSG_WARN([[*** chance of this working. Please contact the mantainer. ]])
AC_MSG_WARN([[******************************************************************]])
fi
if test $ac_cv_sizeof_short != 2 ; then
AC_MSG_WARN([[******************************************************************]])
AC_MSG_WARN([[*** sizeof (short) != 2. ]])
AC_MSG_WARN([[******************************************************************]])
fi
if test $ac_cv_sizeof_int != 4 ; then
AC_MSG_WARN([[******************************************************************]])
AC_MSG_WARN([[*** sizeof (int) != 4 ]])
AC_MSG_WARN([[******************************************************************]])
fi
if test $ac_cv_sizeof_float != 4 ; then
AC_MSG_WARN([[******************************************************************]])
AC_MSG_WARN([[*** sizeof (float) != 4. ]])
AC_MSG_WARN([[******************************************************************]])
fi
if test $ac_cv_sizeof_double != 8 ; then
AC_MSG_WARN([[******************************************************************]])
AC_MSG_WARN([[*** sizeof (double) != 8. ]])
AC_MSG_WARN([[******************************************************************]])
fi
if test x"$ac_cv_prog_autogen" = "xno" ; then
AC_MSG_WARN([[Touching files in directory tests/.]])
touch tests/*.c tests/*.h
fi
#====================================================================================
# Settings for the HTML documentation.
htmldocdir=$prefix/share/doc/libsndfile1-dev/html
if test $prefix = "NONE" ; then
htmldocdir=/usr/local/share/doc/libsndfile1-dev/html
else
htmldocdir=$prefix/share/doc/libsndfile1-dev/html
fi
if test x$enable_bow_docs = "xyes" ; then
HTML_BGCOLOUR="white"
HTML_FGCOLOUR="black"
else
HTML_BGCOLOUR="black"
HTML_FGCOLOUR="white"
fi
#====================================================================================
# Now use the information from the checking stage.
if test x$ac_cv_c_compiler_gnu = xyes ; then
AC_ADD_CFLAGS(-std=gnu99)
CFLAGS="$CFLAGS -W -Wall"
AC_ADD_CFLAGS(-Wdeclaration-after-statement)
if test x$enable_gcc_werror = "xyes" ; then
CFLAGS="-Werror $CFLAGS"
fi
CFLAGS="$CFLAGS -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings"
# -Wpointer-arith -Wundef -Wmissing-declarations -Winline -Wconversion"
if test "x$enable_gcc_opt" = "xno" ; then
temp_CFLAGS=`echo $CFLAGS | sed "s/O2/O0/"`
CFLAGS=$temp_CFLAGS
AC_MSG_WARN([[*** Compiler optimisations switched off. ***]])
fi
# OS specific tweaks.
case "$host_os" in
darwin* | rhapsody*)
# Disable -Wall, -pedantic and -Wshadow for Apple Darwin/Rhapsody.
# System headers on these systems are broken.
temp_CFLAGS=`echo $CFLAGS | sed "s/-Wall -pedantic//" | sed "s/-Wshadow//" | sed "s/-Waggregate-return//"`
CFLAGS=$temp_CFLAGS
SHLIB_VERSION_ARG="-Wl,-exported_symbols_list -Wl,\$(srcdir)/Symbols.darwin"
;;
linux*)
SHLIB_VERSION_ARG="-Wl,--version-script=\$(srcdir)/Symbols.linux"
;;
mingw*)
SHLIB_VERSION_ARG="-Wl,\$(srcdir)/libsndfile.def"
;;
cygwin*)
SHLIB_VERSION_ARG="-Wl,\$(srcdir)/cygsndfile.def"
;;
*)
;;
esac
if test x$enable_gcc_pipe != "xno" ; then
CFLAGS="$CFLAGS -pipe"
fi
AC_DEFINE([COMPILER_IS_GCC],1, [Set to 1 if the compile is GNU GCC.])
GCC_MAJOR_VERSION=`$CC -dumpversion | sed "s/\..*//"`
AC_DEFINE_UNQUOTED([GCC_MAJOR_VERSION],${GCC_MAJOR_VERSION}, [Major version of GCC or 3 otherwise.])
fi
CFLAGS="$CFLAGS $OS_SPECIFIC_CFLAGS"
if test x"$CFLAGS" = x ; then
echo "Error in configure script. CFLAGS has been screwed up."
exit
fi
AC_SUBST(htmldocdir)
AC_SUBST(HTML_BGCOLOUR)
AC_SUBST(HTML_FGCOLOUR)
AC_SUBST(SHLIB_VERSION_ARG)
AC_SUBST(SHARED_VERSION_INFO)
AC_SUBST(OS_SPECIFIC_CFLAGS)
AC_SUBST(OS_SPECIFIC_LINKS)
AC_SUBST(ALSA_LIBS)
AC_SUBST(FLAC_LIBS)
AC_SUBST(ENABLE_EXPERIMENTAL_CODE)
AC_SUBST(COMPILER_IS_GCC)
AC_SUBST(GCC_MAJOR_VERSION)
dnl The following line causes the libtool distributed with the source
dnl to be replaced if the build system has a more recent version.
AC_SUBST(LIBTOOL_DEPS)
AC_CONFIG_FILES([ \
src/sndfile.h
sndfile.pc \
])
AC_OUTPUT
#====================================================================================
AC_MSG_RESULT([
-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-
Configuration summary :
Version : ..................... ${VERSION}
Experimental code : ........... ${enable_experimental:-no}
])
if test x$ac_cv_c_compiler_gnu = xyes ; then
echo -e " Tools :\n"
echo " Compiler is GCC : ............. ${ac_cv_c_compiler_gnu}"
echo " GCC major version : ........... ${GCC_MAJOR_VERSION}"
if test $GCC_MAJOR_VERSION -lt 3 ; then
echo -e "\n ** This compiler version allows applications to write"
echo " ** to static strings within the library."
echo " ** Compile with GCC version 3.X to avoid this problem."
fi
fi
if test $libdir = "\${exec_prefix}/lib" ; then
libdir="$prefix/lib"
fi
if test $bindir = "\${exec_prefix}/bin" ; then
bindir="$prefix/bin"
fi
AC_MSG_RESULT([[
Installation directories :
Library directory : ........... $libdir
Program directory : ........... $bindir
Pkgconfig directory : ......... $libdir/pkgconfig
HTML docs directory : ......... $htmldocdir
]])
if test x$prefix != "x/usr" ; then
echo "Compiling some other packages against libsndfile may require"
echo -e "the addition of \"$libdir/pkgconfig\" to the"
echo -e "PKG_CONFIG_PATH environment variable.\n"
fi
#====================================================================================
ifelse(dnl
Do not edit or modify anything in this comment block.
The arch-tag line is a file identity tag for the GNU Arch
revision control system.
arch-tag: 6391b316-6cfc-43c2-a18a-8defdc4ee359
)dnl

View File

@@ -1,294 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
#
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "$0: no input file specified" >&2
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d "$dst" ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "$0: $src does not exist" >&2
exit 1
fi
if [ x"$dst" = x ]
then
echo "$0: no destination specified" >&2
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d "$dst" ]
then
dst=$dst/`basename "$src"`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1
shift
if [ ! -d "$pathcomp" ] ;
then
$mkdirprog "$pathcomp"
else
:
fi
pathcomp=$pathcomp/
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd "$dst" &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename "$dst"`
else
:
fi
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
# Now remove or move aside any old file at destination location. We try this
# two ways since rm can't unlink itself on some systems and the destination
# file might be busy for other reasons. In this case, the final cleanup
# might fail but the new file should still install successfully.
{
if [ -f "$dstdir/$dstfile" ]
then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
{
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}

View File

@@ -1,69 +0,0 @@
%define name @PACKAGE@
%define version @VERSION@
%define release 1
Summary: A library to handle various audio file formats.
Name: %{name}
Version: %{version}
Release: %{release}
Copyright: LGPL
Group: Libraries/Sound
Source: http://www.mega-nerd.com/libsndfile/libsndfile-%{version}.tar.gz
URL: http://www.mega-nerd.com/libsndfile/
BuildRoot: /var/tmp/%{name}-%{version}
%description
libsndfile is a C library for reading and writing sound files such as
AIFF, AU and WAV files through one standard interface. It can currently
read/write 8, 16, 24 and 32-bit PCM files as well as 32-bit floating
point WAV files and a number of compressed formats.
%package devel
Summary: Libraries, includes, etc to develop libsndfile applications
Group: Libraries
%description devel
Libraries, include files, etc you can use to develop libsndfile applications.
%prep
%setup
%build
%configure
make
%install
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
mkdir -p $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT install
%clean
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
%files
%defattr(-,root,root)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO doc
%{_libdir}/libsndfile.so.*
%{_bindir}/*
%{_mandir}/man1/*
%{_datadir}/octave/site/m/*
%{_defaultdocdir}/libsndfile1-dev/html/*
%files devel
%defattr(-,root,root)
%{_libdir}/libsndfile.a
%{_libdir}/libsndfile.la
%{_libdir}/libsndfile.so
%{_includedir}/sndfile.h
%{_libdir}/pkgconfig/sndfile.pc
%changelog
* Sun May 15 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
- Add html files to the files section.
* Tue Sep 16 2003 Erik de Castro Lopo <erikd@mega-nerd.com>
- Apply corrections from Andrew Schultz.
* Mon Oct 21 2002 Erik de Castro Lopo <erikd@mega-nerd.com>
- Force installation of sndfile.pc file.
* Thu Jul 6 2000 Josh Green <jgreen@users.sourceforge.net>
- Created libsndfile.spec.in

View File

@@ -1,111 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# End:
# mkinstalldirs ends here

View File

@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: sndfile
Description: A library for reading and writing audio files
Requires:
Version: @VERSION@
Libs: -L${libdir} -lsndfile
Cflags: -I${includedir}

View File

@@ -1,50 +0,0 @@
2001-06-05 Erik de Castro Lopo <erikd@mega-nerd.com>
* g72x.c
Added {} in function update () to prevent 'ambiguous else' warning messages.
2000-07-14 Erik de Castro Lopo <erikd@mega-nerd.com>
* g72x.c
Modified g72x_init_state () to fit in with the new structure of the code.
Implemented g72x_encode_block () and g72x_decode_block ().
2000-07-12 Erik de Castro Lopo <erikd@mega-nerd.com>
* g72x.h
Moved nearly all definitions and function prototypes from this file have been
moved to private.h.
Added an enum defining the 4 different G72x ADPCM codecs.
Added new function prototypes to define a cleaner interface to the encoder
and decoder. This new interface also allows samples to be processed in blocks
rather than on a sample by sample basis like the original code.
* private.h
Added prototypes moved from g72x.h.
Changed struct g72x_state to a typedef struct { .. } G72x_PRIVATE.
Added fields to G72x_PRIVATE required for working on blocks of samples.
2000-06-07 Erik de Castro Lopo <erikd@mega-nerd.com>
* g72x.c
Fixed all compiler warnings.
Removed functions tandem_adjust() which is not required by libsndfile.
* g721.c
Fixed all compiler warnings.
Removed functions tandem_adjust_alaw() and tandem_adjust_ulaw () which are not
required by libsndfile.
Removed second parameter to g721_encoder () which is not required.
* g72x.h
Removed in_coding and out_coding parameters from all functions. These allowed
g72x encoding/decoding to/from A-law or u-law and are not required by libsndfile.
Removed unneeded defines for A-law, u-law and linear encoding.
* g723_16.c
Removed second parameter (in_coding) for g723_16_encoder().
Removed second parameter (out_coding) for g723_16_decoder().
* private.h
New file containing prototypes and tyepdefs private to G72x code.

View File

@@ -1,94 +0,0 @@
The files in this directory comprise ANSI-C language reference implementations
of the CCITT (International Telegraph and Telephone Consultative Committee)
G.711, G.721 and G.723 voice compressions. They have been tested on Sun
SPARCstations and passed 82 out of 84 test vectors published by CCITT
(Dec. 20, 1988) for G.721 and G.723. [The two remaining test vectors,
which the G.721 decoder implementation for u-law samples did not pass,
may be in error because they are identical to two other vectors for G.723_40.]
This source code is released by Sun Microsystems, Inc. to the public domain.
Please give your acknowledgement in product literature if this code is used
in your product implementation.
Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system
software. However, Sun's implementations have been optimized for higher
performance on SPARCstations.
The source files for CCITT conversion routines in this directory are:
g72x.h header file for g721.c, g723_24.c and g723_40.c
g711.c CCITT G.711 u-law and A-law compression
g72x.c common denominator of G.721 and G.723 ADPCM codes
g721.c CCITT G.721 32Kbps ADPCM coder (with g72x.c)
g723_24.c CCITT G.723 24Kbps ADPCM coder (with g72x.c)
g723_40.c CCITT G.723 40Kbps ADPCM coder (with g72x.c)
Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked
as follows:
unsigned char ucode, acode;
short pcm_val;
ucode = linear2ulaw(pcm_val);
ucode = alaw2ulaw(acode);
acode = linear2alaw(pcm_val);
acode = ulaw2alaw(ucode);
pcm_val = ulaw2linear(ucode);
pcm_val = alaw2linear(acode);
The other CCITT compression routines are invoked as follows:
#include "g72x.h"
struct g72x_state state;
int sample, code;
g72x_init_state(&state);
code = {g721,g723_24,g723_40}_encoder(sample, coding, &state);
sample = {g721,g723_24,g723_40}_decoder(code, coding, &state);
where
coding = AUDIO_ENCODING_ULAW for 8-bit u-law samples
AUDIO_ENCODING_ALAW for 8-bit A-law samples
AUDIO_ENCODING_LINEAR for 16-bit linear PCM samples
This directory also includes the following sample programs:
encode.c CCITT ADPCM encoder
decode.c CCITT ADPCM decoder
Makefile makefile for the sample programs
The sample programs contain examples of how to call the various compression
routines and pack/unpack the bits. The sample programs read byte streams from
stdin and write to stdout. The input/output data is raw data (no file header
or other identifying information is embedded). The sample programs are
invoked as follows:
encode [-3|4|5] [-a|u|l] <infile >outfile
decode [-3|4|5] [-a|u|l] <infile >outfile
where:
-3 encode to (decode from) G.723 24kbps (3-bit) data
-4 encode to (decode from) G.721 32kbps (4-bit) data [the default]
-5 encode to (decode from) G.723 40kbps (5-bit) data
-a encode from (decode to) A-law data
-u encode from (decode to) u-law data [the default]
-l encode from (decode to) 16-bit linear data
Examples:
# Read 16-bit linear and output G.721
encode -4 -l <pcmfile >g721file
# Read 40Kbps G.723 and output A-law
decode -5 -a <g723file >alawfile
# Compress and then decompress u-law data using 24Kbps G.723
encode -3 <ulawin | deoced -3 >ulawout

View File

@@ -1,162 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g721.c
*
* Description:
*
* g721_encoder(), g721_decoder()
*
* These routines comprise an implementation of the CCITT G.721 ADPCM
* coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which
* take advantage of work station attributes, such as hardware 2's
* complement arithmetic and large memory. Specifically, certain time
* consuming operations such as multiplications are replaced
* with lookup tables and software 2's complement operations are
* replaced with hardware 2's complement.
*
* The deviation from the bit level specification (lookup tables)
* preserves the bit level performance specifications.
*
* As outlined in the G.721 Recommendation, the algorithm is broken
* down into modules. Each section of code below is preceded by
* the name of the module which it is implementing.
*
*/
#include "g72x.h"
#include "g72x_priv.h"
static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
/*
* Maps G.721 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
425, 373, 323, 273, 213, 135, 4, -2048};
/* Maps G.721 code word to log of scale factor multiplier. */
static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
1122, 355, 198, 112, 64, 41, 18, -12};
/*
* Maps G.721 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
/*
* g721_encoder()
*
* Encodes the input vale of linear PCM, A-law or u-law data sl and returns
* the resulting code. -1 is returned for unknown input coding value.
*/
int
g721_encoder(
int sl,
G72x_STATE *state_ptr)
{
short sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short sr; /* ADDB */
short y; /* MIX */
short dqsez; /* ADDC */
short dq, i;
/* linearize input sample to 14-bit PCM */
sl >>= 2; /* 14-bit dynamic range */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */
d = sl - se; /* estimation difference */
/* quantize the prediction difference */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */
dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g721_decoder()
*
* Description:
*
* Decodes a 4-bit code of G.721 encoded data of i and
* returns the resulting linear PCM, A-law or u-law value.
* return -1 for unknown out_coding value.
*/
int
g721_decoder(
int i,
G72x_STATE *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x0f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* dynamic quantizer step size */
dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
/* sr was 14-bit dynamic range */
return (sr << 2);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 101b6e25-457d-490a-99ae-e2e74a26ea24
*/

View File

@@ -1,169 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/* 16kbps version created, used 24kbps code and changing as little as possible.
* G.726 specs are available from ITU's gopher or WWW site (http://www.itu.ch)
* If any errors are found, please contact me at mrand@tamu.edu
* -Marc Randolph
*/
/*
* g723_16.c
*
* Description:
*
* g723_16_encoder(), g723_16_decoder()
*
* These routines comprise an implementation of the CCITT G.726 16 Kbps
* ADPCM coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which take advantage
* of workstation attributes, such as hardware 2's complement arithmetic.
*
*/
#include "g72x.h"
#include "g72x_priv.h"
/*
* Maps G.723_16 code word to reconstructed scale factor normalized log
* magnitude values. Comes from Table 11/G.726
*/
static short _dqlntab[4] = { 116, 365, 365, 116};
/* Maps G.723_16 code word to log of scale factor multiplier.
*
* _witab[4] is actually {-22 , 439, 439, -22}, but FILTD wants it
* as WI << 5 (multiplied by 32), so we'll do that here
*/
static short _witab[4] = {-704, 14048, 14048, -704};
/*
* Maps G.723_16 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
/* Comes from FUNCTF */
static short _fitab[4] = {0, 0xE00, 0xE00, 0};
/* Comes from quantizer decision level tables (Table 7/G.726)
*/
static short qtab_723_16[1] = {261};
/*
* g723_16_encoder()
*
* Encodes a linear PCM, A-law or u-law input sample and returns its 2-bit code.
* Returns -1 if invalid input coding value.
*/
int
g723_16_encoder(
int sl,
G72x_STATE *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
/* linearize input sample to 14-bit PCM */
sl >>= 2; /* sl of 14-bit dynamic range */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation diff. */
/* quantize prediction difference d */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_723_16, 1); /* i = ADPCM code */
/* Since quantize() only produces a three level output
* (1, 2, or 3), we must create the fourth one on our own
*/
if (i == 3) /* i code for the zero region */
if ((d & 0x8000) == 0) /* If d > 0, i=3 isn't right... */
i = 0;
dq = reconstruct(i & 2, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_16_decoder()
*
* Decodes a 2-bit CCITT G.723_16 ADPCM code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_16_decoder(
int i,
G72x_STATE *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x03; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x02, _dqlntab[i], y); /* unquantize pred diff */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
/* sr was of 14-bit dynamic range */
return (sr << 2);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: ae265466-c3fc-4f83-bb32-edae488a5ca5
*/

View File

@@ -1,146 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g723_24.c
*
* Description:
*
* g723_24_encoder(), g723_24_decoder()
*
* These routines comprise an implementation of the CCITT G.723 24 Kbps
* ADPCM coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which take advantage
* of workstation attributes, such as hardware 2's complement arithmetic.
*
*/
#include "g72x.h"
#include "g72x_priv.h"
/*
* Maps G.723_24 code word to reconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
/* Maps G.723_24 code word to log of scale factor multiplier. */
static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
/*
* Maps G.723_24 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
static short qtab_723_24[3] = {8, 218, 331};
/*
* g723_24_encoder()
*
* Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
* Returns -1 if invalid input coding value.
*/
int
g723_24_encoder(
int sl,
G72x_STATE *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
/* linearize input sample to 14-bit PCM */
sl >>= 2; /* sl of 14-bit dynamic range */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation diff. */
/* quantize prediction difference d */
y = step_size(state_ptr); /* quantizer step size */
i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */
dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_24_decoder()
*
* Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int
g723_24_decoder(
int i,
G72x_STATE *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x07; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (sr << 2); /* sr was of 14-bit dynamic range */
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 75389236-650b-4427-98f3-0df6e8fb24bc
*/

View File

@@ -1,160 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g723_40.c
*
* Description:
*
* g723_40_encoder(), g723_40_decoder()
*
* These routines comprise an implementation of the CCITT G.723 40Kbps
* ADPCM coding algorithm. Essentially, this implementation is identical to
* the bit level description except for a few deviations which
* take advantage of workstation attributes, such as hardware 2's
* complement arithmetic.
*
* The deviation from the bit level specification (lookup tables),
* preserves the bit level performance specifications.
*
* As outlined in the G.723 Recommendation, the algorithm is broken
* down into modules. Each section of code below is preceded by
* the name of the module which it is implementing.
*
*/
#include "g72x.h"
#include "g72x_priv.h"
/*
* Maps G.723_40 code word to ructeconstructed scale factor normalized log
* magnitude values.
*/
static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
358, 395, 429, 459, 488, 514, 539, 566,
566, 539, 514, 488, 459, 429, 395, 358,
318, 274, 224, 169, 104, 28, -66, -2048};
/* Maps G.723_40 code word to log of scale factor multiplier. */
static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
3200, 1856, 1312, 1280, 1248, 768, 448, 448};
/*
* Maps G.723_40 code words to a set of values whose long and short
* term averages are computed and then compared to give an indication
* how stationary (steady state) the signal is.
*/
static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
378, 413, 445, 475, 502, 528, 553};
/*
* g723_40_encoder()
*
* Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
* the resulting 5-bit CCITT G.723 40Kbps code.
* Returns -1 if the input coding value is invalid.
*/
int g723_40_encoder (int sl, G72x_STATE *state_ptr)
{
short sei, sezi, se, sez; /* ACCUM */
short d; /* SUBTA */
short y; /* MIX */
short sr; /* ADDB */
short dqsez; /* ADDC */
short dq, i;
/* linearize input sample to 14-bit PCM */
sl >>= 2; /* sl of 14-bit dynamic range */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
d = sl - se; /* d = estimation difference */
/* quantize prediction difference */
y = step_size(state_ptr); /* adaptive quantizer step size */
i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */
sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
dqsez = sr + sez - se; /* dqsez = pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (i);
}
/*
* g723_40_decoder()
*
* Decodes a 5-bit CCITT G.723 40Kbps code and returns
* the resulting 16-bit linear PCM, A-law or u-law sample value.
* -1 is returned if the output coding is unknown.
*/
int g723_40_decoder (int i, G72x_STATE *state_ptr)
{
short sezi, sei, sez, se; /* ACCUM */
short y ; /* MIX */
short sr; /* ADDB */
short dq;
short dqsez;
i &= 0x1f; /* mask to get proper bits */
sezi = predictor_zero(state_ptr);
sez = sezi >> 1;
sei = sezi + predictor_pole(state_ptr);
se = sei >> 1; /* se = estimated signal */
y = step_size(state_ptr); /* adaptive quantizer step size */
dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */
sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
dqsez = sr - se + sez; /* pole prediction diff. */
update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
return (sr << 2); /* sr was of 14-bit dynamic range */
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: eb8d9a00-32bf-4dd2-b287-01b0336d72bf
*/

View File

@@ -1,652 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* g72x.c
*
* Common routines for G.721 and G.723 conversions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g72x.h"
#include "g72x_priv.h"
static G72x_STATE * g72x_state_new (void) ;
static int unpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples) ;
static int pack_bytes (int bits, const short * samples, unsigned char * block) ;
static
short power2 [15] =
{ 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000
} ;
/*
* quan()
*
* quantizes the input val against the table of size short integers.
* It returns i if table[i - 1] <= val < table[i].
*
* Using linear search for simple coding.
*/
static
int quan (int val, short *table, int size)
{
int i;
for (i = 0; i < size; i++)
if (val < *table++)
break;
return (i);
}
/*
* fmult()
*
* returns the integer product of the 14-bit integer "an" and
* "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
*/
static
int fmult (int an, int srn)
{
short anmag, anexp, anmant;
short wanexp, wanmant;
short retval;
anmag = (an > 0) ? an : ((-an) & 0x1FFF);
anexp = quan(anmag, power2, 15) - 6;
anmant = (anmag == 0) ? 32 :
(anexp >= 0) ? anmag >> anexp : anmag << -anexp;
wanexp = anexp + ((srn >> 6) & 0xF) - 13;
/*
** The original was :
** wanmant = (anmant * (srn & 0x37) + 0x30) >> 4 ;
** but could see no valid reason for the + 0x30.
** Removed it and it improved the SNR of the codec.
*/
wanmant = (anmant * (srn & 0x37)) >> 4 ;
retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
(wanmant >> -wanexp);
return (((an ^ srn) < 0) ? -retval : retval);
}
static G72x_STATE * g72x_state_new (void)
{ return calloc (1, sizeof (G72x_STATE)) ;
}
/*
* private_init_state()
*
* This routine initializes and/or resets the G72x_PRIVATE structure
* pointed to by 'state_ptr'.
* All the initial state values are specified in the CCITT G.721 document.
*/
void private_init_state (G72x_STATE *state_ptr)
{
int cnta;
state_ptr->yl = 34816;
state_ptr->yu = 544;
state_ptr->dms = 0;
state_ptr->dml = 0;
state_ptr->ap = 0;
for (cnta = 0; cnta < 2; cnta++) {
state_ptr->a[cnta] = 0;
state_ptr->pk[cnta] = 0;
state_ptr->sr[cnta] = 32;
}
for (cnta = 0; cnta < 6; cnta++) {
state_ptr->b[cnta] = 0;
state_ptr->dq[cnta] = 32;
}
state_ptr->td = 0;
} /* private_init_state */
struct g72x_state * g72x_reader_init (int codec, int *blocksize, int *samplesperblock)
{ G72x_STATE *pstate ;
if ((pstate = g72x_state_new ()) == NULL)
return NULL ;
private_init_state (pstate) ;
pstate->encoder = NULL ;
switch (codec)
{ case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */
pstate->decoder = g723_16_decoder ;
*blocksize = G723_16_BYTES_PER_BLOCK ;
*samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 2 ;
pstate->blocksize = G723_16_BYTES_PER_BLOCK ;
pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
break ;
case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */
pstate->decoder = g723_24_decoder ;
*blocksize = G723_24_BYTES_PER_BLOCK ;
*samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 3 ;
pstate->blocksize = G723_24_BYTES_PER_BLOCK ;
pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
break ;
case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */
pstate->decoder = g721_decoder ;
*blocksize = G721_32_BYTES_PER_BLOCK ;
*samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 4 ;
pstate->blocksize = G721_32_BYTES_PER_BLOCK ;
pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
break ;
case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */
pstate->decoder = g723_40_decoder ;
*blocksize = G721_40_BYTES_PER_BLOCK ;
*samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 5 ;
pstate->blocksize = G721_40_BYTES_PER_BLOCK ;
pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
break ;
default :
free (pstate) ;
return NULL ;
} ;
return pstate ;
} /* g72x_reader_init */
struct g72x_state * g72x_writer_init (int codec, int *blocksize, int *samplesperblock)
{ G72x_STATE *pstate ;
if ((pstate = g72x_state_new ()) == NULL)
return NULL ;
private_init_state (pstate) ;
pstate->decoder = NULL ;
switch (codec)
{ case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */
pstate->encoder = g723_16_encoder ;
*blocksize = G723_16_BYTES_PER_BLOCK ;
*samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 2 ;
pstate->blocksize = G723_16_BYTES_PER_BLOCK ;
pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
break ;
case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */
pstate->encoder = g723_24_encoder ;
*blocksize = G723_24_BYTES_PER_BLOCK ;
*samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 3 ;
pstate->blocksize = G723_24_BYTES_PER_BLOCK ;
pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
break ;
case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */
pstate->encoder = g721_encoder ;
*blocksize = G721_32_BYTES_PER_BLOCK ;
*samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 4 ;
pstate->blocksize = G721_32_BYTES_PER_BLOCK ;
pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
break ;
case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */
pstate->encoder = g723_40_encoder ;
*blocksize = G721_40_BYTES_PER_BLOCK ;
*samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
pstate->codec_bits = 5 ;
pstate->blocksize = G721_40_BYTES_PER_BLOCK ;
pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
break ;
default :
free (pstate) ;
return NULL ;
} ;
return pstate ;
} /* g72x_writer_init */
int g72x_decode_block (G72x_STATE *pstate, const unsigned char *block, short *samples)
{ int k, count ;
count = unpack_bytes (pstate->codec_bits, pstate->blocksize, block, samples) ;
for (k = 0 ; k < count ; k++)
samples [k] = pstate->decoder (samples [k], pstate) ;
return 0 ;
} /* g72x_decode_block */
int g72x_encode_block (G72x_STATE *pstate, short *samples, unsigned char *block)
{ int k, count ;
for (k = 0 ; k < pstate->samplesperblock ; k++)
samples [k] = pstate->encoder (samples [k], pstate) ;
count = pack_bytes (pstate->codec_bits, samples, block) ;
return count ;
} /* g72x_encode_block */
/*
* predictor_zero()
*
* computes the estimated signal from 6-zero predictor.
*
*/
int predictor_zero (G72x_STATE *state_ptr)
{
int i;
int sezi;
sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
for (i = 1; i < 6; i++) /* ACCUM */
sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
return (sezi);
}
/*
* predictor_pole()
*
* computes the estimated signal from 2-pole predictor.
*
*/
int predictor_pole(G72x_STATE *state_ptr)
{
return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
}
/*
* step_size()
*
* computes the quantization step size of the adaptive quantizer.
*
*/
int step_size (G72x_STATE *state_ptr)
{
int y;
int dif;
int al;
if (state_ptr->ap >= 256)
return (state_ptr->yu);
else {
y = state_ptr->yl >> 6;
dif = state_ptr->yu - y;
al = state_ptr->ap >> 2;
if (dif > 0)
y += (dif * al) >> 6;
else if (dif < 0)
y += (dif * al + 0x3F) >> 6;
return (y);
}
}
/*
* quantize()
*
* Given a raw sample, 'd', of the difference signal and a
* quantization step size scale factor, 'y', this routine returns the
* ADPCM codeword to which that sample gets quantized. The step
* size scale factor division operation is done in the log base 2 domain
* as a subtraction.
*/
int quantize(
int d, /* Raw difference signal sample */
int y, /* Step size multiplier */
short *table, /* quantization table */
int size) /* table size of short integers */
{
short dqm; /* Magnitude of 'd' */
short expon; /* Integer part of base 2 log of 'd' */
short mant; /* Fractional part of base 2 log */
short dl; /* Log of magnitude of 'd' */
short dln; /* Step size scale factor normalized log */
int i;
/*
* LOG
*
* Compute base 2 log of 'd', and store in 'dl'.
*/
dqm = abs(d);
expon = quan(dqm >> 1, power2, 15);
mant = ((dqm << 7) >> expon) & 0x7F; /* Fractional portion. */
dl = (expon << 7) + mant;
/*
* SUBTB
*
* "Divide" by step size multiplier.
*/
dln = dl - (y >> 2);
/*
* QUAN
*
* Obtain codword i for 'd'.
*/
i = quan(dln, table, size);
if (d < 0) /* take 1's complement of i */
return ((size << 1) + 1 - i);
else if (i == 0) /* take 1's complement of 0 */
return ((size << 1) + 1); /* new in 1988 */
else
return (i);
}
/*
* reconstruct()
*
* Returns reconstructed difference signal 'dq' obtained from
* codeword 'i' and quantization step size scale factor 'y'.
* Multiplication is performed in log base 2 domain as addition.
*/
int
reconstruct(
int sign, /* 0 for non-negative value */
int dqln, /* G.72x codeword */
int y) /* Step size multiplier */
{
short dql; /* Log of 'dq' magnitude */
short dex; /* Integer part of log */
short dqt;
short dq; /* Reconstructed difference signal sample */
dql = dqln + (y >> 2); /* ADDA */
if (dql < 0) {
return ((sign) ? -0x8000 : 0);
} else { /* ANTILOG */
dex = (dql >> 7) & 15;
dqt = 128 + (dql & 127);
dq = (dqt << 7) >> (14 - dex);
return ((sign) ? (dq - 0x8000) : dq);
}
}
/*
* update()
*
* updates the state variables for each output code
*/
void
update(
int code_size, /* distinguish 723_40 with others */
int y, /* quantizer step size */
int wi, /* scale factor multiplier */
int fi, /* for long/short term energies */
int dq, /* quantized prediction difference */
int sr, /* reconstructed signal */
int dqsez, /* difference from 2-pole predictor */
G72x_STATE *state_ptr) /* coder state pointer */
{
int cnt;
short mag, expon; /* Adaptive predictor, FLOAT A */
short a2p = 0; /* LIMC */
short a1ul; /* UPA1 */
short pks1; /* UPA2 */
short fa1;
char tr; /* tone/transition detector */
short ylint, thr2, dqthr;
short ylfrac, thr1;
short pk0;
pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */
mag = dq & 0x7FFF; /* prediction difference magnitude */
/* TRANS */
ylint = state_ptr->yl >> 15; /* exponent part of yl */
ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */
thr1 = (32 + ylfrac) << ylint; /* threshold */
thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */
dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */
if (state_ptr->td == 0) /* signal supposed voice */
tr = 0;
else if (mag <= dqthr) /* supposed data, but small mag */
tr = 0; /* treated as voice */
else /* signal is data (modem) */
tr = 1;
/*
* Quantizer scale factor adaptation.
*/
/* FUNCTW & FILTD & DELAY */
/* update non-steady state step size multiplier */
state_ptr->yu = y + ((wi - y) >> 5);
/* LIMB */
if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */
state_ptr->yu = 544;
else if (state_ptr->yu > 5120)
state_ptr->yu = 5120;
/* FILTE & DELAY */
/* update steady state step size multiplier */
state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
/*
* Adaptive predictor coefficients.
*/
if (tr == 1) { /* reset a's and b's for modem signal */
state_ptr->a[0] = 0;
state_ptr->a[1] = 0;
state_ptr->b[0] = 0;
state_ptr->b[1] = 0;
state_ptr->b[2] = 0;
state_ptr->b[3] = 0;
state_ptr->b[4] = 0;
state_ptr->b[5] = 0;
} else { /* update a's and b's */
pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */
/* update predictor pole a[1] */
a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
if (dqsez != 0) {
fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
if (fa1 < -8191) /* a2p = function of fa1 */
a2p -= 0x100;
else if (fa1 > 8191)
a2p += 0xFF;
else
a2p += fa1 >> 5;
if (pk0 ^ state_ptr->pk[1])
{ /* LIMC */
if (a2p <= -12160)
a2p = -12288;
else if (a2p >= 12416)
a2p = 12288;
else
a2p -= 0x80;
}
else if (a2p <= -12416)
a2p = -12288;
else if (a2p >= 12160)
a2p = 12288;
else
a2p += 0x80;
}
/* TRIGB & DELAY */
state_ptr->a[1] = a2p;
/* UPA1 */
/* update predictor pole a[0] */
state_ptr->a[0] -= state_ptr->a[0] >> 8;
if (dqsez != 0)
{ if (pks1 == 0)
state_ptr->a[0] += 192;
else
state_ptr->a[0] -= 192;
} ;
/* LIMD */
a1ul = 15360 - a2p;
if (state_ptr->a[0] < -a1ul)
state_ptr->a[0] = -a1ul;
else if (state_ptr->a[0] > a1ul)
state_ptr->a[0] = a1ul;
/* UPB : update predictor zeros b[6] */
for (cnt = 0; cnt < 6; cnt++) {
if (code_size == 5) /* for 40Kbps G.723 */
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
else /* for G.721 and 24Kbps G.723 */
state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
if (dq & 0x7FFF) { /* XOR */
if ((dq ^ state_ptr->dq[cnt]) >= 0)
state_ptr->b[cnt] += 128;
else
state_ptr->b[cnt] -= 128;
}
}
}
for (cnt = 5; cnt > 0; cnt--)
state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
/* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
if (mag == 0) {
state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
} else {
expon = quan(mag, power2, 15);
state_ptr->dq[0] = (dq >= 0) ?
(expon << 6) + ((mag << 6) >> expon) :
(expon << 6) + ((mag << 6) >> expon) - 0x400;
}
state_ptr->sr[1] = state_ptr->sr[0];
/* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
if (sr == 0) {
state_ptr->sr[0] = 0x20;
} else if (sr > 0) {
expon = quan(sr, power2, 15);
state_ptr->sr[0] = (expon << 6) + ((sr << 6) >> expon);
} else if (sr > -32768) {
mag = -sr;
expon = quan(mag, power2, 15);
state_ptr->sr[0] = (expon << 6) + ((mag << 6) >> expon) - 0x400;
} else
state_ptr->sr[0] = (short) 0xFC20;
/* DELAY A */
state_ptr->pk[1] = state_ptr->pk[0];
state_ptr->pk[0] = pk0;
/* TONE */
if (tr == 1) /* this sample has been treated as data */
state_ptr->td = 0; /* next one will be treated as voice */
else if (a2p < -11776) /* small sample-to-sample correlation */
state_ptr->td = 1; /* signal may be data */
else /* signal is voice */
state_ptr->td = 0;
/*
* Adaptation speed control.
*/
state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */
state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */
if (tr == 1)
state_ptr->ap = 256;
else if (y < 1536) /* SUBTC */
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (state_ptr->td == 1)
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
(state_ptr->dml >> 3))
state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
else
state_ptr->ap += (-state_ptr->ap) >> 4;
return ;
} /* update */
/*------------------------------------------------------------------------------
*/
static int
unpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples)
{ unsigned int in_buffer = 0 ;
unsigned char in_byte ;
int k, in_bits = 0, bindex = 0 ;
for (k = 0 ; bindex <= blocksize && k < G72x_BLOCK_SIZE ; k++)
{ if (in_bits < bits)
{ in_byte = block [bindex++] ;
in_buffer |= (in_byte << in_bits);
in_bits += 8;
}
samples [k] = in_buffer & ((1 << bits) - 1);
in_buffer >>= bits;
in_bits -= bits;
} ;
return k ;
} /* unpack_bytes */
static int
pack_bytes (int bits, const short * samples, unsigned char * block)
{
unsigned int out_buffer = 0 ;
int k, bindex = 0, out_bits = 0 ;
unsigned char out_byte ;
for (k = 0 ; k < G72x_BLOCK_SIZE ; k++)
{ out_buffer |= (samples [k] << out_bits) ;
out_bits += bits ;
if (out_bits >= 8)
{ out_byte = out_buffer & 0xFF ;
out_bits -= 8 ;
out_buffer >>= 8 ;
block [bindex++] = out_byte ;
}
} ;
return bindex ;
} /* pack_bytes */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 6298dc75-fd0f-4062-9b90-f73ed69f22d4
*/

View File

@@ -1,99 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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 file is not the same as the original file from Sun Microsystems. Nearly
** all the original definitions and function prototypes that were in the file
** of this name have been moved to g72x_priv.h.
*/
#ifndef G72X_HEADER_FILE
#define G72X_HEADER_FILE
/*
** Number of samples per block to process.
** Must be a common multiple of possible bits per sample : 2, 3, 4, 5 and 8.
*/
#define G72x_BLOCK_SIZE (3 * 5 * 8)
/*
** Identifiers for the differing kinds of G72x ADPCM codecs.
** The identifiers also define the number of encoded bits per sample.
*/
enum
{ G723_16_BITS_PER_SAMPLE = 2,
G723_24_BITS_PER_SAMPLE = 3,
G723_40_BITS_PER_SAMPLE = 5,
G721_32_BITS_PER_SAMPLE = 4,
G721_40_BITS_PER_SAMPLE = 5,
G723_16_SAMPLES_PER_BLOCK = G72x_BLOCK_SIZE,
G723_24_SAMPLES_PER_BLOCK = G723_24_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G723_24_BITS_PER_SAMPLE),
G723_40_SAMPLES_PER_BLOCK = G723_40_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G723_40_BITS_PER_SAMPLE),
G721_32_SAMPLES_PER_BLOCK = G72x_BLOCK_SIZE,
G721_40_SAMPLES_PER_BLOCK = G721_40_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G721_40_BITS_PER_SAMPLE),
G723_16_BYTES_PER_BLOCK = (G723_16_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
G723_24_BYTES_PER_BLOCK = (G723_24_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
G723_40_BYTES_PER_BLOCK = (G723_40_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
G721_32_BYTES_PER_BLOCK = (G721_32_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
G721_40_BYTES_PER_BLOCK = (G721_40_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8
} ;
/* Forward declaration of of g72x_state. */
struct g72x_state ;
/* External function definitions. */
struct g72x_state * g72x_reader_init (int codec, int *blocksize, int *samplesperblock) ;
struct g72x_state * g72x_writer_init (int codec, int *blocksize, int *samplesperblock) ;
/*
** Initialize the ADPCM state table for the given codec.
** Return 0 on success, 1 on fail.
*/
int g72x_decode_block (struct g72x_state *pstate, const unsigned char *block, short *samples) ;
/*
** The caller fills data->block with data->bytes bytes before calling the
** function. The value data->bytes must be an integer multiple of
** data->blocksize and be <= data->max_bytes.
** When it returns, the caller can read out data->samples samples.
*/
int g72x_encode_block (struct g72x_state *pstate, short *samples, unsigned char *block) ;
/*
** The caller fills state->samples some integer multiple data->samples_per_block
** (up to G72x_BLOCK_SIZE) samples before calling the function.
** When it returns, the caller can read out bytes encoded bytes.
*/
#endif /* !G72X_HEADER_FILE */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 6ca84e5f-f932-4ba1-87ee-37056d921621
*/

View File

@@ -1,118 +0,0 @@
/*
* This source code is a product of Sun Microsystems, Inc. and is provided
* for unrestricted use. Users may copy or modify this source code without
* charge.
*
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun source code is provided with no support and without any obligation on
* the part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#ifndef G72X_PRIVATE_H
#define G72X_PRIVATE_H
#ifdef __cplusplus
#error "This code is not designed to be compiled with a C++ compiler."
#endif
/*
** The following is the definition of the state structure used by the
** G.721/G.723 encoder and decoder to preserve their internal state
** between successive calls. The meanings of the majority of the state
** structure fields are explained in detail in the CCITT Recommendation
** G.721. The field names are essentially identical to variable names
** in the bit level description of the coding algorithm included in this
** Recommendation.
*/
struct g72x_state
{ long yl; /* Locked or steady state step size multiplier. */
short yu; /* Unlocked or non-steady state step size multiplier. */
short dms; /* Short term energy estimate. */
short dml; /* Long term energy estimate. */
short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */
short a[2]; /* Coefficients of pole portion of prediction filter. */
short b[6]; /* Coefficients of zero portion of prediction filter. */
short pk[2]; /*
** Signs of previous two samples of a partially
** reconstructed signal.
**/
short dq[6]; /*
** Previous 6 samples of the quantized difference
** signal represented in an internal floating point
** format.
**/
short sr[2]; /*
** Previous 2 samples of the quantized difference
** signal represented in an internal floating point
** format.
*/
char td; /* delayed tone detect, new in 1988 version */
/* The following struct members were added for libsndfile. The original
** code worked by calling a set of functions on a sample by sample basis
** which is slow on architectures like Intel x86. For libsndfile, this
** was changed so that the encoding and decoding routines could work on
** a block of samples at a time to reduce the function call overhead.
*/
int (*encoder) (int, struct g72x_state* state) ;
int (*decoder) (int, struct g72x_state* state) ;
int codec_bits, blocksize, samplesperblock ;
} ;
typedef struct g72x_state G72x_STATE ;
int predictor_zero (G72x_STATE *state_ptr);
int predictor_pole (G72x_STATE *state_ptr);
int step_size (G72x_STATE *state_ptr);
int quantize (int d, int y, short *table, int size);
int reconstruct (int sign, int dqln, int y);
void update (int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, G72x_STATE *state_ptr);
int g721_encoder (int sample, G72x_STATE *state_ptr);
int g721_decoder (int code, G72x_STATE *state_ptr);
int g723_16_encoder (int sample, G72x_STATE *state_ptr);
int g723_16_decoder (int code, G72x_STATE *state_ptr);
int g723_24_encoder (int sample, G72x_STATE *state_ptr);
int g723_24_decoder (int code, G72x_STATE *state_ptr);
int g723_40_encoder (int sample, G72x_STATE *state_ptr);
int g723_40_decoder (int code, G72x_STATE *state_ptr);
void private_init_state (G72x_STATE *state_ptr) ;
#endif /* G72X_PRIVATE_H */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: d9ad4da7-0fa3-471d-8020-720b5cfb5e5b
*/

View File

@@ -1,222 +0,0 @@
/*
** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** 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.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "g72x.h"
#include "g72x_priv.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846264338
#endif
#define BUFFER_SIZE (1<<14) /* Should be (1<<14) */
#define SAMPLE_RATE 11025
static void g721_test (void) ;
static void g723_test (double margin) ;
static void gen_signal_double (double *data, double scale, int datalen) ;
static int error_function (double data, double orig, double margin) ;
static int oct_save_short (short *a, short *b, int len) ;
int
main (int argc, char *argv [])
{ int bDoAll = 0 ;
int nTests = 0 ;
if (argc != 2)
{ printf ("Usage : %s <test>\n", argv [0]) ;
printf (" Where <test> is one of the following:\n") ;
printf (" g721 - test G721 encoder and decoder\n") ;
printf (" g723 - test G721 encoder and decoder\n") ;
printf (" all - perform all tests\n") ;
exit (1) ;
} ;
bDoAll=!strcmp (argv [1], "all");
if (bDoAll || ! strcmp (argv [1], "g721"))
{ g721_test () ;
nTests++ ;
} ;
if (bDoAll || ! strcmp (argv [1], "g723"))
{ g723_test (0.53) ;
nTests++ ;
} ;
if (nTests == 0)
{ printf ("Mono : ************************************\n") ;
printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
printf ("Mono : ************************************\n") ;
return 1 ;
} ;
return 0 ;
} /* main */
static void
g721_test (void)
{
return ;
} /* g721_test */
static void
g723_test (double margin)
{ static double orig_buffer [BUFFER_SIZE] ;
static short orig [BUFFER_SIZE] ;
static short data [BUFFER_SIZE] ;
G72x_STATE encoder_state, decoder_state ;
long k ;
int code, position, max_err ;
private_init_state (&encoder_state) ;
encoder_state.encoder = g723_24_encoder ;
encoder_state.codec_bits = 3 ;
private_init_state (&decoder_state) ;
decoder_state.decoder = g723_24_decoder ;
decoder_state.codec_bits = 3 ;
memset (data, 0, BUFFER_SIZE * sizeof (short)) ;
memset (orig, 0, BUFFER_SIZE * sizeof (short)) ;
printf (" g723_test : ") ;
fflush (stdout) ;
gen_signal_double (orig_buffer, 32000.0, BUFFER_SIZE) ;
for (k = 0 ; k < BUFFER_SIZE ; k++)
orig [k] = (short) orig_buffer [k] ;
/* Write and read data here. */
position = 0 ;
max_err = 0 ;
for (k = 0 ; k < BUFFER_SIZE ; k++)
{ code = encoder_state.encoder (orig [k], &encoder_state) ;
data [k] = decoder_state.decoder (code, &decoder_state) ;
if (abs (orig [k] - data [k]) > max_err)
{ position = k ;
max_err = abs (orig [k] - data [k]) ;
} ;
} ;
printf ("\n\nMax error of %d at postion %d.\n", max_err, position) ;
for (k = 0 ; k < BUFFER_SIZE ; k++)
{ if (error_function (data [k], orig [k], margin))
{ printf ("Line %d: Incorrect sample A (#%ld : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ;
oct_save_short (orig, data, BUFFER_SIZE) ;
exit (1) ;
} ;
} ;
printf ("ok\n") ;
return ;
} /* g723_test */
#define SIGNAL_MAXVAL 30000.0
#define DECAY_COUNT 1000
static void
gen_signal_double (double *gendata, double scale, int gendatalen)
{ int k, ramplen ;
double amp = 0.0 ;
ramplen = DECAY_COUNT ;
for (k = 0 ; k < gendatalen ; k++)
{ if (k <= ramplen)
amp = scale * k / ((double) ramplen) ;
else if (k > gendatalen - ramplen)
amp = scale * (gendatalen - k) / ((double) ramplen) ;
gendata [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
} ;
return ;
} /* gen_signal_double */
static int
error_function (double data, double orig, double margin)
{ double error ;
if (fabs (orig) <= 500.0)
error = fabs (fabs (data) - fabs(orig)) / 2000.0 ;
else if (fabs (orig) <= 1000.0)
error = fabs (data - orig) / 3000.0 ;
else
error = fabs (data - orig) / fabs (orig) ;
if (error > margin)
{ printf ("\n\n*******************\nError : %f\n", error) ;
return 1 ;
} ;
return 0 ;
} /* error_function */
static int
oct_save_short (short *a, short *b, int len)
{ FILE *file ;
int k ;
if (! (file = fopen ("error.dat", "w")))
return 1 ;
fprintf (file, "# Not created by Octave\n") ;
fprintf (file, "# name: a\n") ;
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", a [k]) ;
fprintf (file, "# name: b\n") ;
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", b [k]) ;
fclose (file) ;
return 0 ;
} /* oct_save_short */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 0597b442-a5b0-4abf-92a4-92f6c24e85a6
*/

View File

@@ -1,16 +0,0 @@
Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
Technische Universitaet Berlin
Any use of this software is permitted provided that this notice is not
removed and that neither the authors nor the Technische Universitaet Berlin
are deemed to have made any representations as to the suitability of this
software for any purpose nor are held responsible for any defects of
this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
As a matter of courtesy, the authors request to be informed about uses
this software has found, about bugs in this software, and about any
improvements that may be of general interest.
Berlin, 28.11.1994
Jutta Degener
Carsten Bormann

View File

@@ -1,56 +0,0 @@
2004-05-12 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* gsm610_priv.h
Replace ugly macros with inline functions.
* *.c
Remove temporary variables used by macros and other minor fixes required by
above change.
2003-06-02 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* rpe.c
Renamed variables "exp" to "expon" to avoid shadowed parameter warnigns.
2002-06-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* long_term.c
Changes tp removed compiler warnings about shadowed parameters.
2002-06-08 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* private.h
Made declarations of gsm_A, gsm_B, gsm_MIC etc extern. This fixed a compile
problem on MacOSX.
2002-05-10 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* *.[ch]
Removed all pre-ANSI prototype kludges. Removed proto.h and unproto.h.
Started work on making GSM 6.10 files seekable. Currently they are not.
* code.c private.h
Function Gsm_Coder () used a statically defined array. This was obviously
not re-entrant so moved it to struct gsm_state.
2001-09-16 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* code.c
Added #includes for string.h and stdlib.h.
2000-10-27 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* config.h
Removed some commented out #defines (ie //*efine) which were causing problems on
the Sun cc compiler.
2000-02-29 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* private.h
Added #defines to emulate normal compile time options.
2000-02-28 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
* everthing
Created this directory and copied files from libgsm.
http://kbs.cs.tu-berlin.de/~jutta/toast.html

View File

@@ -1,36 +0,0 @@
GSM 06.10 13 kbit/s RPE/LTP speech codec
----------------------------------------
All the file in this directory were written by Jutta Degener
and Carsten Borman for The Communications and Operating Systems
Research Group (KBS) at the Technische Universitaet Berlin.
Their work was released under the following license which is
assumed to be compatible with The GNU Lesser General Public License.
----------------------------------------------------------------------------
Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
Technische Universitaet Berlin
Any use of this software is permitted provided that this notice is not
removed and that neither the authors nor the Technische Universitaet Berlin
are deemed to have made any representations as to the suitability of this
software for any purpose nor are held responsible for any defects of
this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
As a matter of courtesy, the authors request to be informed about uses
this software has found, about bugs in this software, and about any
improvements that may be of general interest.
Berlin, 28.11.1994
Jutta Degener (jutta@cs.tu-berlin.de)
Carsten Bormann (cabo@cs.tu-berlin.de)
----------------------------------------------------------------------------
Jutta Degener and Carsten Bormann's work can be found on their homepage
at:
http://kbs.cs.tu-berlin.de/~jutta/toast.html

View File

@@ -1,248 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
/*
* See private.h for the more commonly used macro versions.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
#define saturate(x) \
((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
word gsm_add ( word a, word b)
{
longword sum = (longword)a + (longword)b;
return saturate(sum);
}
word gsm_sub ( word a, word b)
{
longword diff = (longword)a - (longword)b;
return saturate(diff);
}
word gsm_mult ( word a, word b)
{
if (a == MIN_WORD && b == MIN_WORD)
return MAX_WORD;
return SASR_L( (longword)a * (longword)b, 15 );
}
word gsm_mult_r ( word a, word b)
{
if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
else {
longword prod = (longword)a * (longword)b + 16384;
prod >>= 15;
return prod & 0xFFFF;
}
}
word gsm_abs (word a)
{
return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
}
longword gsm_L_mult (word a, word b)
{
assert( a != MIN_WORD || b != MIN_WORD );
return ((longword)a * (longword)b) << 1;
}
longword gsm_L_add ( longword a, longword b)
{
if (a < 0) {
if (b >= 0) return a + b;
else {
ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
}
}
else if (b <= 0) return a + b;
else {
ulongword A = (ulongword)a + (ulongword)b;
return A > MAX_LONGWORD ? MAX_LONGWORD : A;
}
}
longword gsm_L_sub ( longword a, longword b)
{
if (a >= 0) {
if (b >= 0) return a - b;
else {
/* a>=0, b<0 */
ulongword A = (ulongword)a + -(b + 1);
return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
}
}
else if (b <= 0) return a - b;
else {
/* a<0, b>0 */
ulongword A = (ulongword)-(a + 1) + b;
return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
}
}
static unsigned char const bitoff[ 256 ] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
word gsm_norm (longword a )
/*
* the number of left shifts needed to normalize the 32 bit
* variable L_var1 for positive values on the interval
*
* with minimum of
* minimum of 1073741824 (01000000000000000000000000000000) and
* maximum of 2147483647 (01111111111111111111111111111111)
*
*
* and for negative values on the interval with
* minimum of -2147483648 (-10000000000000000000000000000000) and
* maximum of -1073741824 ( -1000000000000000000000000000000).
*
* in order to normalize the result, the following
* operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
*
* (That's 'ffs', only from the left, not the right..)
*/
{
assert(a != 0);
if (a < 0) {
if (a <= -1073741824) return 0;
a = ~a;
}
return a & 0xffff0000
? ( a & 0xff000000
? -1 + bitoff[ 0xFF & (a >> 24) ]
: 7 + bitoff[ 0xFF & (a >> 16) ] )
: ( a & 0xff00
? 15 + bitoff[ 0xFF & (a >> 8) ]
: 23 + bitoff[ 0xFF & a ] );
}
longword gsm_L_asl (longword a, int n)
{
if (n >= 32) return 0;
if (n <= -32) return -(a < 0);
if (n < 0) return gsm_L_asr(a, -n);
return a << n;
}
word gsm_asr (word a, int n)
{
if (n >= 16) return -(a < 0);
if (n <= -16) return 0;
if (n < 0) return a << -n;
return SASR_W (a, (word) n);
}
word gsm_asl (word a, int n)
{
if (n >= 16) return 0;
if (n <= -16) return -(a < 0);
if (n < 0) return gsm_asr(a, -n);
return a << n;
}
longword gsm_L_asr (longword a, int n)
{
if (n >= 32) return -(a < 0);
if (n <= -32) return 0;
if (n < 0) return a << -n;
return SASR_L (a, (word) n);
}
/*
** word gsm_asr (word a, int n)
** {
** if (n >= 16) return -(a < 0);
** if (n <= -16) return 0;
** if (n < 0) return a << -n;
**
** # ifdef SASR_W
** return a >> n;
** # else
** if (a >= 0) return a >> n;
** else return -(word)( -(uword)a >> n );
** # endif
** }
**
*/
/*
* (From p. 46, end of section 4.2.5)
*
* NOTE: The following lines gives [sic] one correct implementation
* of the div(num, denum) arithmetic operation. Compute div
* which is the integer division of num by denum: with denum
* >= num > 0
*/
word gsm_div (word num, word denum)
{
longword L_num = num;
longword L_denum = denum;
word div = 0;
int k = 15;
/* The parameter num sometimes becomes zero.
* Although this is explicitly guarded against in 4.2.5,
* we assume that the result should then be zero as well.
*/
/* assert(num != 0); */
assert(num >= 0 && denum >= num);
if (num == 0)
return 0;
while (k--) {
div <<= 1;
L_num <<= 1;
if (L_num >= L_denum) {
L_num -= L_denum;
div++;
}
}
return div;
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: a7398579-e2e1-4733-aa2d-4c6efc0c58ff
*/

View File

@@ -1,97 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "gsm610_priv.h"
#include "gsm.h"
/*
* 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
*/
void Gsm_Coder (
struct gsm_state * State,
word * s, /* [0..159] samples IN */
/*
* The RPE-LTD coder works on a frame by frame basis. The length of
* the frame is equal to 160 samples. Some computations are done
* once per frame to produce at the output of the coder the
* LARc[1..8] parameters which are the coded LAR coefficients and
* also to realize the inverse filtering operation for the entire
* frame (160 samples of signal d[0..159]). These parts produce at
* the output of the coder:
*/
word * LARc, /* [0..7] LAR coefficients OUT */
/*
* Procedure 4.2.11 to 4.2.18 are to be executed four times per
* frame. That means once for each sub-segment RPE-LTP analysis of
* 40 samples. These parts produce at the output of the coder:
*/
word * Nc, /* [0..3] LTP lag OUT */
word * bc, /* [0..3] coded LTP gain OUT */
word * Mc, /* [0..3] RPE grid selection OUT */
word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
word * xMc /* [13*4] normalized RPE samples OUT */
)
{
int k;
word * dp = State->dp0 + 120; /* [ -120...-1 ] */
word * dpp = dp; /* [ 0...39 ] */
word so[160];
Gsm_Preprocess (State, s, so);
Gsm_LPC_Analysis (State, so, LARc);
Gsm_Short_Term_Analysis_Filter (State, LARc, so);
for (k = 0; k <= 3; k++, xMc += 13) {
Gsm_Long_Term_Predictor ( State,
so+k*40, /* d [0..39] IN */
dp, /* dp [-120..-1] IN */
State->e + 5, /* e [0..39] OUT */
dpp, /* dpp [0..39] OUT */
Nc++,
bc++);
Gsm_RPE_Encoding ( /*-S,-*/
State->e + 5, /* e ][0..39][ IN/OUT */
xmaxc++, Mc++, xMc );
/*
* Gsm_Update_of_reconstructed_short_time_residual_signal
* ( dpp, e + 5, dp );
*/
{ register int i;
for (i = 0; i <= 39; i++)
dp[ i ] = GSM_ADD( State->e[5 + i], dpp[i] );
}
dp += 40;
dpp += 40;
}
(void)memcpy( (char *)State->dp0, (char *)(State->dp0 + 160),
120 * sizeof(*State->dp0) );
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: ae8ef1b2-5a1e-4263-94cd-42b15dca81a3
*/

View File

@@ -1,33 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#ifndef CONFIG_H
#define CONFIG_H
#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
#define HAS_FSTAT 1 /* fstat syscall */
#define HAS_FCHMOD 1 /* fchmod syscall */
#define HAS_CHMOD 1 /* chmod syscall */
#define HAS_FCHOWN 1 /* fchown syscall */
#define HAS_CHOWN 1 /* chown syscall */
#define HAS_STRING_H 1 /* /usr/include/string.h */
#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
#define HAS_UTIME 1 /* POSIX utime(path, times) */
#define HAS_UTIME_H 1 /* UTIME header file */
#endif /* CONFIG_H */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 5338dfef-8e59-4f51-af47-627c9ea85353
*/

View File

@@ -1,67 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include "gsm610_priv.h"
#include "gsm.h"
/*
* 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
*/
static void Postprocessing (
struct gsm_state * S,
register word * s)
{
register int k;
register word msr = S->msr;
register word tmp;
for (k = 160; k--; s++) {
tmp = GSM_MULT_R( msr, 28180 );
msr = GSM_ADD(*s, tmp); /* Deemphasis */
*s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */
}
S->msr = msr;
}
void Gsm_Decoder (
struct gsm_state * S,
word * LARcr, /* [0..7] IN */
word * Ncr, /* [0..3] IN */
word * bcr, /* [0..3] IN */
word * Mcr, /* [0..3] IN */
word * xmaxcr, /* [0..3] IN */
word * xMcr, /* [0..13*4] IN */
word * s) /* [0..159] OUT */
{
int j, k;
word erp[40], wt[160];
word * drp = S->dp0 + 120;
for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
Gsm_RPE_Decoding( /*-S,-*/ *xmaxcr, *Mcr, xMcr, erp );
Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ];
}
Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
Postprocessing(S, s);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 11ae5b90-2e8b-400b-ac64-a69a1fc6cc41
*/

View File

@@ -1,58 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#ifndef GSM_H
#define GSM_H
#include <stdio.h> /* for FILE * */
/*
* Interface
*/
typedef struct gsm_state * gsm;
typedef short gsm_signal; /* signed 16 bit */
typedef unsigned char gsm_byte;
typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */
#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */
#define GSM_PATCHLEVEL 10
#define GSM_MINOR 0
#define GSM_MAJOR 1
#define GSM_OPT_VERBOSE 1
#define GSM_OPT_FAST 2
#define GSM_OPT_LTP_CUT 3
#define GSM_OPT_WAV49 4
#define GSM_OPT_FRAME_INDEX 5
#define GSM_OPT_FRAME_CHAIN 6
gsm gsm_create (void);
/* Added for libsndfile : May 6, 2002 */
void gsm_init (gsm);
void gsm_destroy (gsm);
int gsm_print (FILE *, gsm, gsm_byte *);
int gsm_option (gsm, int, int *);
void gsm_encode (gsm, gsm_signal *, gsm_byte *);
int gsm_decode (gsm, gsm_byte *, gsm_signal *);
int gsm_explode (gsm, gsm_byte *, gsm_signal *);
void gsm_implode (gsm, gsm_signal *, gsm_byte *);
#endif /* GSM_H */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 8cfc7698-5433-4b6f-aeca-967c6fda4dec
*/

View File

@@ -1,308 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#ifndef PRIVATE_H
#define PRIVATE_H
/* Added by Erik de Castro Lopo */
#define USE_FLOAT_MUL
#define FAST
#define WAV49
#ifdef __cplusplus
#error "This code is not designed to be compiled with a C++ compiler."
#endif
/* Added by Erik de Castro Lopo */
typedef short word; /* 16 bit signed int */
typedef int longword; /* 32 bit signed int */
typedef unsigned short uword; /* unsigned word */
typedef unsigned int ulongword; /* unsigned longword */
struct gsm_state
{ word dp0[ 280 ] ;
word z1; /* preprocessing.c, Offset_com. */
longword L_z2; /* Offset_com. */
int mp; /* Preemphasis */
word u[8] ; /* short_term_aly_filter.c */
word LARpp[2][8] ; /* */
word j; /* */
word ltp_cut; /* long_term.c, LTP crosscorr. */
word nrp; /* 40 */ /* long_term.c, synthesis */
word v[9] ; /* short_term.c, synthesis */
word msr; /* decoder.c, Postprocessing */
char verbose; /* only used if !NDEBUG */
char fast; /* only used if FAST */
char wav_fmt; /* only used if WAV49 defined */
unsigned char frame_index; /* odd/even chaining */
unsigned char frame_chain; /* half-byte to carry forward */
/* Moved here from code.c where it was defined as static */
word e[50] ;
} ;
typedef struct gsm_state GSM_STATE ;
#define MIN_WORD (-32767 - 1)
#define MAX_WORD 32767
#define MIN_LONGWORD (-2147483647 - 1)
#define MAX_LONGWORD 2147483647
/* Signed arithmetic shift right. */
static inline word
SASR_W (word x, word by)
{ return (x >> by) ;
} /* SASR */
static inline longword
SASR_L (longword x, word by)
{ return (x >> by) ;
} /* SASR */
/*
* Prototypes from add.c
*/
word gsm_mult (word a, word b) ;
longword gsm_L_mult (word a, word b) ;
word gsm_mult_r (word a, word b) ;
word gsm_div (word num, word denum) ;
word gsm_add (word a, word b ) ;
longword gsm_L_add (longword a, longword b ) ;
word gsm_sub (word a, word b) ;
longword gsm_L_sub (longword a, longword b) ;
word gsm_abs (word a) ;
word gsm_norm (longword a ) ;
longword gsm_L_asl (longword a, int n) ;
word gsm_asl (word a, int n) ;
longword gsm_L_asr (longword a, int n) ;
word gsm_asr (word a, int n) ;
/*
* Inlined functions from add.h
*/
static inline longword
GSM_MULT_R (word a, word b)
{ return (((longword) (a)) * ((longword) (b)) + 16384) >> 15 ;
} /* GSM_MULT_R */
static inline longword
GSM_MULT (word a, word b)
{ return (((longword) (a)) * ((longword) (b))) >> 15 ;
} /* GSM_MULT */
static inline longword
GSM_L_MULT (word a, word b)
{ return ((longword) (a)) * ((longword) (b)) << 1 ;
} /* GSM_L_MULT */
static inline longword
GSM_L_ADD (longword a, longword b)
{ ulongword utmp ;
if (a < 0 && b < 0)
{ utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1) ;
return (utmp >= (ulongword) MAX_LONGWORD) ? MIN_LONGWORD : -(longword)utmp-2 ;
} ;
if (a > 0 && b > 0)
{ utmp = (ulongword) a + (ulongword) b ;
return (utmp >= (ulongword) MAX_LONGWORD) ? MAX_LONGWORD : utmp ;
} ;
return a + b ;
} /* GSM_L_ADD */
static inline longword
GSM_ADD (word a, word b)
{ longword ltmp ;
ltmp = ((longword) a) + ((longword) b) ;
if (ltmp >= MAX_WORD)
return MAX_WORD ;
if (ltmp <= MIN_WORD)
return MIN_WORD ;
return ltmp ;
} /* GSM_ADD */
static inline longword
GSM_SUB (word a, word b)
{ longword ltmp ;
ltmp = ((longword) a) - ((longword) b) ;
if (ltmp >= MAX_WORD)
ltmp = MAX_WORD ;
else if (ltmp <= MIN_WORD)
ltmp = MIN_WORD ;
return ltmp ;
} /* GSM_SUB */
static inline word
GSM_ABS (word a)
{
if (a > 0)
return a ;
if (a == MIN_WORD)
return MAX_WORD ;
return -a ;
} /* GSM_ADD */
/*
* More prototypes from implementations..
*/
void Gsm_Coder (
struct gsm_state * S,
word * s, /* [0..159] samples IN */
word * LARc, /* [0..7] LAR coefficients OUT */
word * Nc, /* [0..3] LTP lag OUT */
word * bc, /* [0..3] coded LTP gain OUT */
word * Mc, /* [0..3] RPE grid selection OUT */
word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
word * xMc) ;/* [13*4] normalized RPE samples OUT */
void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */
struct gsm_state * S,
word * d, /* [0..39] residual signal IN */
word * dp, /* [-120..-1] d' IN */
word * e, /* [0..40] OUT */
word * dpp, /* [0..40] OUT */
word * Nc, /* correlation lag OUT */
word * bc) ; /* gain factor OUT */
void Gsm_LPC_Analysis (
struct gsm_state * S,
word * s, /* 0..159 signals IN/OUT */
word * LARc) ; /* 0..7 LARc's OUT */
void Gsm_Preprocess (
struct gsm_state * S,
word * s, word * so) ;
void Gsm_Encoding (
struct gsm_state * S,
word * e,
word * ep,
word * xmaxc,
word * Mc,
word * xMc) ;
void Gsm_Short_Term_Analysis_Filter (
struct gsm_state * S,
word * LARc, /* coded log area ratio [0..7] IN */
word * d) ; /* st res. signal [0..159] IN/OUT */
void Gsm_Decoder (
struct gsm_state * S,
word * LARcr, /* [0..7] IN */
word * Ncr, /* [0..3] IN */
word * bcr, /* [0..3] IN */
word * Mcr, /* [0..3] IN */
word * xmaxcr, /* [0..3] IN */
word * xMcr, /* [0..13*4] IN */
word * s) ; /* [0..159] OUT */
void Gsm_Decoding (
struct gsm_state * S,
word xmaxcr,
word Mcr,
word * xMcr, /* [0..12] IN */
word * erp) ; /* [0..39] OUT */
void Gsm_Long_Term_Synthesis_Filtering (
struct gsm_state* S,
word Ncr,
word bcr,
word * erp, /* [0..39] IN */
word * drp) ; /* [-120..-1] IN, [0..40] OUT */
void Gsm_RPE_Decoding (
/*-struct gsm_state *S,-*/
word xmaxcr,
word Mcr,
word * xMcr, /* [0..12], 3 bits IN */
word * erp) ; /* [0..39] OUT */
void Gsm_RPE_Encoding (
/*-struct gsm_state * S,-*/
word * e, /* -5..-1][0..39][40..44 IN/OUT */
word * xmaxc, /* OUT */
word * Mc, /* OUT */
word * xMc) ; /* [0..12] OUT */
void Gsm_Short_Term_Synthesis_Filter (
struct gsm_state * S,
word * LARcr, /* log area ratios [0..7] IN */
word * drp, /* received d [0...39] IN */
word * s) ; /* signal s [0..159] OUT */
void Gsm_Update_of_reconstructed_short_time_residual_signal (
word * dpp, /* [0...39] IN */
word * ep, /* [0...39] IN */
word * dp) ; /* [-120...-1] IN/OUT */
/*
* Tables from table.c
*/
#ifndef GSM_TABLE_C
extern word gsm_A [8], gsm_B [8], gsm_MIC [8], gsm_MAC [8] ;
extern word gsm_INVA [8] ;
extern word gsm_DLB [4], gsm_QLB [4] ;
extern word gsm_H [11] ;
extern word gsm_NRFAC [8] ;
extern word gsm_FAC [8] ;
#endif /* GSM_TABLE_C */
/*
* Debugging
*/
#ifdef NDEBUG
# define gsm_debug_words(a, b, c, d) /* nil */
# define gsm_debug_longwords(a, b, c, d) /* nil */
# define gsm_debug_word(a, b) /* nil */
# define gsm_debug_longword(a, b) /* nil */
#else /* !NDEBUG => DEBUG */
void gsm_debug_words (char * name, int, int, word *) ;
void gsm_debug_longwords (char * name, int, int, longword *) ;
void gsm_debug_longword (char * name, longword) ;
void gsm_debug_word (char * name, word) ;
#endif /* !NDEBUG */
#endif /* PRIVATE_H */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 8bc5fdf2-e8c8-4686-9bd7-a30b512bef0c
*/

View File

@@ -1,44 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gsm.h"
#include "gsm610_priv.h"
gsm gsm_create (void)
{
gsm r;
r = malloc (sizeof(struct gsm_state));
if (!r) return r;
memset((char *)r, 0, sizeof (struct gsm_state));
r->nrp = 40;
return r;
}
/* Added for libsndfile : May 6, 2002. Not sure if it works. */
void gsm_init (gsm state)
{
memset (state, 0, sizeof (struct gsm_state)) ;
state->nrp = 40 ;
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 9fedb6b3-ed99-40c2-aac1-484c536261fe
*/

View File

@@ -1,366 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include "gsm610_priv.h"
#include "gsm.h"
int gsm_decode (gsm s, gsm_byte * c, gsm_signal * target)
{
word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
#ifdef WAV49
if (s->wav_fmt) {
uword sr = 0;
s->frame_index = !s->frame_index;
if (s->frame_index) {
sr = *c++;
LARc[0] = sr & 0x3f; sr >>= 6;
sr |= (uword)*c++ << 2;
LARc[1] = sr & 0x3f; sr >>= 6;
sr |= (uword)*c++ << 4;
LARc[2] = sr & 0x1f; sr >>= 5;
LARc[3] = sr & 0x1f; sr >>= 5;
sr |= (uword)*c++ << 2;
LARc[4] = sr & 0xf; sr >>= 4;
LARc[5] = sr & 0xf; sr >>= 4;
sr |= (uword)*c++ << 2; /* 5 */
LARc[6] = sr & 0x7; sr >>= 3;
LARc[7] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 4;
Nc[0] = sr & 0x7f; sr >>= 7;
bc[0] = sr & 0x3; sr >>= 2;
Mc[0] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 1;
xmaxc[0] = sr & 0x3f; sr >>= 6;
xmc[0] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[1] = sr & 0x7; sr >>= 3;
xmc[2] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[3] = sr & 0x7; sr >>= 3;
xmc[4] = sr & 0x7; sr >>= 3;
xmc[5] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1; /* 10 */
xmc[6] = sr & 0x7; sr >>= 3;
xmc[7] = sr & 0x7; sr >>= 3;
xmc[8] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[9] = sr & 0x7; sr >>= 3;
xmc[10] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[11] = sr & 0x7; sr >>= 3;
xmc[12] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 4;
Nc[1] = sr & 0x7f; sr >>= 7;
bc[1] = sr & 0x3; sr >>= 2;
Mc[1] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 1;
xmaxc[1] = sr & 0x3f; sr >>= 6;
xmc[13] = sr & 0x7; sr >>= 3;
sr = *c++; /* 15 */
xmc[14] = sr & 0x7; sr >>= 3;
xmc[15] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[16] = sr & 0x7; sr >>= 3;
xmc[17] = sr & 0x7; sr >>= 3;
xmc[18] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[19] = sr & 0x7; sr >>= 3;
xmc[20] = sr & 0x7; sr >>= 3;
xmc[21] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[22] = sr & 0x7; sr >>= 3;
xmc[23] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[24] = sr & 0x7; sr >>= 3;
xmc[25] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 4; /* 20 */
Nc[2] = sr & 0x7f; sr >>= 7;
bc[2] = sr & 0x3; sr >>= 2;
Mc[2] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 1;
xmaxc[2] = sr & 0x3f; sr >>= 6;
xmc[26] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[27] = sr & 0x7; sr >>= 3;
xmc[28] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[29] = sr & 0x7; sr >>= 3;
xmc[30] = sr & 0x7; sr >>= 3;
xmc[31] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[32] = sr & 0x7; sr >>= 3;
xmc[33] = sr & 0x7; sr >>= 3;
xmc[34] = sr & 0x7; sr >>= 3;
sr = *c++; /* 25 */
xmc[35] = sr & 0x7; sr >>= 3;
xmc[36] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[37] = sr & 0x7; sr >>= 3;
xmc[38] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 4;
Nc[3] = sr & 0x7f; sr >>= 7;
bc[3] = sr & 0x3; sr >>= 2;
Mc[3] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 1;
xmaxc[3] = sr & 0x3f; sr >>= 6;
xmc[39] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[40] = sr & 0x7; sr >>= 3;
xmc[41] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2; /* 30 */
xmc[42] = sr & 0x7; sr >>= 3;
xmc[43] = sr & 0x7; sr >>= 3;
xmc[44] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[45] = sr & 0x7; sr >>= 3;
xmc[46] = sr & 0x7; sr >>= 3;
xmc[47] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[48] = sr & 0x7; sr >>= 3;
xmc[49] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[50] = sr & 0x7; sr >>= 3;
xmc[51] = sr & 0x7; sr >>= 3;
s->frame_chain = sr & 0xf;
}
else {
sr = s->frame_chain;
sr |= (uword)*c++ << 4; /* 1 */
LARc[0] = sr & 0x3f; sr >>= 6;
LARc[1] = sr & 0x3f; sr >>= 6;
sr = *c++;
LARc[2] = sr & 0x1f; sr >>= 5;
sr |= (uword)*c++ << 3;
LARc[3] = sr & 0x1f; sr >>= 5;
LARc[4] = sr & 0xf; sr >>= 4;
sr |= (uword)*c++ << 2;
LARc[5] = sr & 0xf; sr >>= 4;
LARc[6] = sr & 0x7; sr >>= 3;
LARc[7] = sr & 0x7; sr >>= 3;
sr = *c++; /* 5 */
Nc[0] = sr & 0x7f; sr >>= 7;
sr |= (uword)*c++ << 1;
bc[0] = sr & 0x3; sr >>= 2;
Mc[0] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 5;
xmaxc[0] = sr & 0x3f; sr >>= 6;
xmc[0] = sr & 0x7; sr >>= 3;
xmc[1] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[2] = sr & 0x7; sr >>= 3;
xmc[3] = sr & 0x7; sr >>= 3;
xmc[4] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[5] = sr & 0x7; sr >>= 3;
xmc[6] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2; /* 10 */
xmc[7] = sr & 0x7; sr >>= 3;
xmc[8] = sr & 0x7; sr >>= 3;
xmc[9] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[10] = sr & 0x7; sr >>= 3;
xmc[11] = sr & 0x7; sr >>= 3;
xmc[12] = sr & 0x7; sr >>= 3;
sr = *c++;
Nc[1] = sr & 0x7f; sr >>= 7;
sr |= (uword)*c++ << 1;
bc[1] = sr & 0x3; sr >>= 2;
Mc[1] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 5;
xmaxc[1] = sr & 0x3f; sr >>= 6;
xmc[13] = sr & 0x7; sr >>= 3;
xmc[14] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1; /* 15 */
xmc[15] = sr & 0x7; sr >>= 3;
xmc[16] = sr & 0x7; sr >>= 3;
xmc[17] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[18] = sr & 0x7; sr >>= 3;
xmc[19] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[20] = sr & 0x7; sr >>= 3;
xmc[21] = sr & 0x7; sr >>= 3;
xmc[22] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[23] = sr & 0x7; sr >>= 3;
xmc[24] = sr & 0x7; sr >>= 3;
xmc[25] = sr & 0x7; sr >>= 3;
sr = *c++;
Nc[2] = sr & 0x7f; sr >>= 7;
sr |= (uword)*c++ << 1; /* 20 */
bc[2] = sr & 0x3; sr >>= 2;
Mc[2] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 5;
xmaxc[2] = sr & 0x3f; sr >>= 6;
xmc[26] = sr & 0x7; sr >>= 3;
xmc[27] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[28] = sr & 0x7; sr >>= 3;
xmc[29] = sr & 0x7; sr >>= 3;
xmc[30] = sr & 0x7; sr >>= 3;
sr = *c++;
xmc[31] = sr & 0x7; sr >>= 3;
xmc[32] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[33] = sr & 0x7; sr >>= 3;
xmc[34] = sr & 0x7; sr >>= 3;
xmc[35] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1; /* 25 */
xmc[36] = sr & 0x7; sr >>= 3;
xmc[37] = sr & 0x7; sr >>= 3;
xmc[38] = sr & 0x7; sr >>= 3;
sr = *c++;
Nc[3] = sr & 0x7f; sr >>= 7;
sr |= (uword)*c++ << 1;
bc[3] = sr & 0x3; sr >>= 2;
Mc[3] = sr & 0x3; sr >>= 2;
sr |= (uword)*c++ << 5;
xmaxc[3] = sr & 0x3f; sr >>= 6;
xmc[39] = sr & 0x7; sr >>= 3;
xmc[40] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[41] = sr & 0x7; sr >>= 3;
xmc[42] = sr & 0x7; sr >>= 3;
xmc[43] = sr & 0x7; sr >>= 3;
sr = *c++; /* 30 */
xmc[44] = sr & 0x7; sr >>= 3;
xmc[45] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 2;
xmc[46] = sr & 0x7; sr >>= 3;
xmc[47] = sr & 0x7; sr >>= 3;
xmc[48] = sr & 0x7; sr >>= 3;
sr |= (uword)*c++ << 1;
xmc[49] = sr & 0x7; sr >>= 3;
xmc[50] = sr & 0x7; sr >>= 3;
xmc[51] = sr & 0x7; sr >>= 3;
}
}
else
#endif
{
/* GSM_MAGIC = (*c >> 4) & 0xF; */
if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
LARc[0] = (*c++ & 0xF) << 2; /* 1 */
LARc[0] |= (*c >> 6) & 0x3;
LARc[1] = *c++ & 0x3F;
LARc[2] = (*c >> 3) & 0x1F;
LARc[3] = (*c++ & 0x7) << 2;
LARc[3] |= (*c >> 6) & 0x3;
LARc[4] = (*c >> 2) & 0xF;
LARc[5] = (*c++ & 0x3) << 2;
LARc[5] |= (*c >> 6) & 0x3;
LARc[6] = (*c >> 3) & 0x7;
LARc[7] = *c++ & 0x7;
Nc[0] = (*c >> 1) & 0x7F;
bc[0] = (*c++ & 0x1) << 1;
bc[0] |= (*c >> 7) & 0x1;
Mc[0] = (*c >> 5) & 0x3;
xmaxc[0] = (*c++ & 0x1F) << 1;
xmaxc[0] |= (*c >> 7) & 0x1;
xmc[0] = (*c >> 4) & 0x7;
xmc[1] = (*c >> 1) & 0x7;
xmc[2] = (*c++ & 0x1) << 2;
xmc[2] |= (*c >> 6) & 0x3;
xmc[3] = (*c >> 3) & 0x7;
xmc[4] = *c++ & 0x7;
xmc[5] = (*c >> 5) & 0x7;
xmc[6] = (*c >> 2) & 0x7;
xmc[7] = (*c++ & 0x3) << 1; /* 10 */
xmc[7] |= (*c >> 7) & 0x1;
xmc[8] = (*c >> 4) & 0x7;
xmc[9] = (*c >> 1) & 0x7;
xmc[10] = (*c++ & 0x1) << 2;
xmc[10] |= (*c >> 6) & 0x3;
xmc[11] = (*c >> 3) & 0x7;
xmc[12] = *c++ & 0x7;
Nc[1] = (*c >> 1) & 0x7F;
bc[1] = (*c++ & 0x1) << 1;
bc[1] |= (*c >> 7) & 0x1;
Mc[1] = (*c >> 5) & 0x3;
xmaxc[1] = (*c++ & 0x1F) << 1;
xmaxc[1] |= (*c >> 7) & 0x1;
xmc[13] = (*c >> 4) & 0x7;
xmc[14] = (*c >> 1) & 0x7;
xmc[15] = (*c++ & 0x1) << 2;
xmc[15] |= (*c >> 6) & 0x3;
xmc[16] = (*c >> 3) & 0x7;
xmc[17] = *c++ & 0x7;
xmc[18] = (*c >> 5) & 0x7;
xmc[19] = (*c >> 2) & 0x7;
xmc[20] = (*c++ & 0x3) << 1;
xmc[20] |= (*c >> 7) & 0x1;
xmc[21] = (*c >> 4) & 0x7;
xmc[22] = (*c >> 1) & 0x7;
xmc[23] = (*c++ & 0x1) << 2;
xmc[23] |= (*c >> 6) & 0x3;
xmc[24] = (*c >> 3) & 0x7;
xmc[25] = *c++ & 0x7;
Nc[2] = (*c >> 1) & 0x7F;
bc[2] = (*c++ & 0x1) << 1; /* 20 */
bc[2] |= (*c >> 7) & 0x1;
Mc[2] = (*c >> 5) & 0x3;
xmaxc[2] = (*c++ & 0x1F) << 1;
xmaxc[2] |= (*c >> 7) & 0x1;
xmc[26] = (*c >> 4) & 0x7;
xmc[27] = (*c >> 1) & 0x7;
xmc[28] = (*c++ & 0x1) << 2;
xmc[28] |= (*c >> 6) & 0x3;
xmc[29] = (*c >> 3) & 0x7;
xmc[30] = *c++ & 0x7;
xmc[31] = (*c >> 5) & 0x7;
xmc[32] = (*c >> 2) & 0x7;
xmc[33] = (*c++ & 0x3) << 1;
xmc[33] |= (*c >> 7) & 0x1;
xmc[34] = (*c >> 4) & 0x7;
xmc[35] = (*c >> 1) & 0x7;
xmc[36] = (*c++ & 0x1) << 2;
xmc[36] |= (*c >> 6) & 0x3;
xmc[37] = (*c >> 3) & 0x7;
xmc[38] = *c++ & 0x7;
Nc[3] = (*c >> 1) & 0x7F;
bc[3] = (*c++ & 0x1) << 1;
bc[3] |= (*c >> 7) & 0x1;
Mc[3] = (*c >> 5) & 0x3;
xmaxc[3] = (*c++ & 0x1F) << 1;
xmaxc[3] |= (*c >> 7) & 0x1;
xmc[39] = (*c >> 4) & 0x7;
xmc[40] = (*c >> 1) & 0x7;
xmc[41] = (*c++ & 0x1) << 2;
xmc[41] |= (*c >> 6) & 0x3;
xmc[42] = (*c >> 3) & 0x7;
xmc[43] = *c++ & 0x7; /* 30 */
xmc[44] = (*c >> 5) & 0x7;
xmc[45] = (*c >> 2) & 0x7;
xmc[46] = (*c++ & 0x3) << 1;
xmc[46] |= (*c >> 7) & 0x1;
xmc[47] = (*c >> 4) & 0x7;
xmc[48] = (*c >> 1) & 0x7;
xmc[49] = (*c++ & 0x1) << 2;
xmc[49] |= (*c >> 6) & 0x3;
xmc[50] = (*c >> 3) & 0x7;
xmc[51] = *c & 0x7; /* 33 */
}
Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
return 0;
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 6a9b6628-821c-4a96-84c1-485ebd35f170
*/

View File

@@ -1,31 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include "gsm.h"
#include "config.h"
#ifdef HAS_STDLIB_H
# include <stdlib.h>
#else
# ifdef HAS_MALLOC_H
# include <malloc.h>
# else
extern void free();
# endif
#endif
void gsm_destroy (gsm S)
{
if (S) free((char *)S);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: f423d09b-6ccc-47e0-9b18-ee1cf7a8e473
*/

View File

@@ -1,456 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include "gsm610_priv.h"
#include "gsm.h"
void gsm_encode (gsm s, gsm_signal * source, gsm_byte * c)
{
word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
/* variable size
GSM_MAGIC 4
LARc[0] 6
LARc[1] 6
LARc[2] 5
LARc[3] 5
LARc[4] 4
LARc[5] 4
LARc[6] 3
LARc[7] 3
Nc[0] 7
bc[0] 2
Mc[0] 2
xmaxc[0] 6
xmc[0] 3
xmc[1] 3
xmc[2] 3
xmc[3] 3
xmc[4] 3
xmc[5] 3
xmc[6] 3
xmc[7] 3
xmc[8] 3
xmc[9] 3
xmc[10] 3
xmc[11] 3
xmc[12] 3
Nc[1] 7
bc[1] 2
Mc[1] 2
xmaxc[1] 6
xmc[13] 3
xmc[14] 3
xmc[15] 3
xmc[16] 3
xmc[17] 3
xmc[18] 3
xmc[19] 3
xmc[20] 3
xmc[21] 3
xmc[22] 3
xmc[23] 3
xmc[24] 3
xmc[25] 3
Nc[2] 7
bc[2] 2
Mc[2] 2
xmaxc[2] 6
xmc[26] 3
xmc[27] 3
xmc[28] 3
xmc[29] 3
xmc[30] 3
xmc[31] 3
xmc[32] 3
xmc[33] 3
xmc[34] 3
xmc[35] 3
xmc[36] 3
xmc[37] 3
xmc[38] 3
Nc[3] 7
bc[3] 2
Mc[3] 2
xmaxc[3] 6
xmc[39] 3
xmc[40] 3
xmc[41] 3
xmc[42] 3
xmc[43] 3
xmc[44] 3
xmc[45] 3
xmc[46] 3
xmc[47] 3
xmc[48] 3
xmc[49] 3
xmc[50] 3
xmc[51] 3
*/
#ifdef WAV49
if (s->wav_fmt) {
s->frame_index = !s->frame_index;
if (s->frame_index) {
uword sr;
sr = 0;
sr = sr >> 6 | LARc[0] << 10;
sr = sr >> 6 | LARc[1] << 10;
*c++ = sr >> 4;
sr = sr >> 5 | LARc[2] << 11;
*c++ = sr >> 7;
sr = sr >> 5 | LARc[3] << 11;
sr = sr >> 4 | LARc[4] << 12;
*c++ = sr >> 6;
sr = sr >> 4 | LARc[5] << 12;
sr = sr >> 3 | LARc[6] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | LARc[7] << 13;
sr = sr >> 7 | Nc[0] << 9;
*c++ = sr >> 5;
sr = sr >> 2 | bc[0] << 14;
sr = sr >> 2 | Mc[0] << 14;
sr = sr >> 6 | xmaxc[0] << 10;
*c++ = sr >> 3;
sr = sr >> 3 | xmc[0] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[1] << 13;
sr = sr >> 3 | xmc[2] << 13;
sr = sr >> 3 | xmc[3] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[4] << 13;
sr = sr >> 3 | xmc[5] << 13;
sr = sr >> 3 | xmc[6] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[7] << 13;
sr = sr >> 3 | xmc[8] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[9] << 13;
sr = sr >> 3 | xmc[10] << 13;
sr = sr >> 3 | xmc[11] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[12] << 13;
sr = sr >> 7 | Nc[1] << 9;
*c++ = sr >> 5;
sr = sr >> 2 | bc[1] << 14;
sr = sr >> 2 | Mc[1] << 14;
sr = sr >> 6 | xmaxc[1] << 10;
*c++ = sr >> 3;
sr = sr >> 3 | xmc[13] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[14] << 13;
sr = sr >> 3 | xmc[15] << 13;
sr = sr >> 3 | xmc[16] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[17] << 13;
sr = sr >> 3 | xmc[18] << 13;
sr = sr >> 3 | xmc[19] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[20] << 13;
sr = sr >> 3 | xmc[21] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[22] << 13;
sr = sr >> 3 | xmc[23] << 13;
sr = sr >> 3 | xmc[24] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[25] << 13;
sr = sr >> 7 | Nc[2] << 9;
*c++ = sr >> 5;
sr = sr >> 2 | bc[2] << 14;
sr = sr >> 2 | Mc[2] << 14;
sr = sr >> 6 | xmaxc[2] << 10;
*c++ = sr >> 3;
sr = sr >> 3 | xmc[26] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[27] << 13;
sr = sr >> 3 | xmc[28] << 13;
sr = sr >> 3 | xmc[29] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[30] << 13;
sr = sr >> 3 | xmc[31] << 13;
sr = sr >> 3 | xmc[32] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[33] << 13;
sr = sr >> 3 | xmc[34] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[35] << 13;
sr = sr >> 3 | xmc[36] << 13;
sr = sr >> 3 | xmc[37] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[38] << 13;
sr = sr >> 7 | Nc[3] << 9;
*c++ = sr >> 5;
sr = sr >> 2 | bc[3] << 14;
sr = sr >> 2 | Mc[3] << 14;
sr = sr >> 6 | xmaxc[3] << 10;
*c++ = sr >> 3;
sr = sr >> 3 | xmc[39] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[40] << 13;
sr = sr >> 3 | xmc[41] << 13;
sr = sr >> 3 | xmc[42] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[43] << 13;
sr = sr >> 3 | xmc[44] << 13;
sr = sr >> 3 | xmc[45] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[46] << 13;
sr = sr >> 3 | xmc[47] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[48] << 13;
sr = sr >> 3 | xmc[49] << 13;
sr = sr >> 3 | xmc[50] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[51] << 13;
sr = sr >> 4;
*c = sr >> 8;
s->frame_chain = *c;
}
else {
uword sr;
sr = 0;
sr = sr >> 4 | s->frame_chain << 12;
sr = sr >> 6 | LARc[0] << 10;
*c++ = sr >> 6;
sr = sr >> 6 | LARc[1] << 10;
*c++ = sr >> 8;
sr = sr >> 5 | LARc[2] << 11;
sr = sr >> 5 | LARc[3] << 11;
*c++ = sr >> 6;
sr = sr >> 4 | LARc[4] << 12;
sr = sr >> 4 | LARc[5] << 12;
*c++ = sr >> 6;
sr = sr >> 3 | LARc[6] << 13;
sr = sr >> 3 | LARc[7] << 13;
*c++ = sr >> 8;
sr = sr >> 7 | Nc[0] << 9;
sr = sr >> 2 | bc[0] << 14;
*c++ = sr >> 7;
sr = sr >> 2 | Mc[0] << 14;
sr = sr >> 6 | xmaxc[0] << 10;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[0] << 13;
sr = sr >> 3 | xmc[1] << 13;
sr = sr >> 3 | xmc[2] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[3] << 13;
sr = sr >> 3 | xmc[4] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[5] << 13;
sr = sr >> 3 | xmc[6] << 13;
sr = sr >> 3 | xmc[7] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[8] << 13;
sr = sr >> 3 | xmc[9] << 13;
sr = sr >> 3 | xmc[10] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[11] << 13;
sr = sr >> 3 | xmc[12] << 13;
*c++ = sr >> 8;
sr = sr >> 7 | Nc[1] << 9;
sr = sr >> 2 | bc[1] << 14;
*c++ = sr >> 7;
sr = sr >> 2 | Mc[1] << 14;
sr = sr >> 6 | xmaxc[1] << 10;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[13] << 13;
sr = sr >> 3 | xmc[14] << 13;
sr = sr >> 3 | xmc[15] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[16] << 13;
sr = sr >> 3 | xmc[17] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[18] << 13;
sr = sr >> 3 | xmc[19] << 13;
sr = sr >> 3 | xmc[20] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[21] << 13;
sr = sr >> 3 | xmc[22] << 13;
sr = sr >> 3 | xmc[23] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[24] << 13;
sr = sr >> 3 | xmc[25] << 13;
*c++ = sr >> 8;
sr = sr >> 7 | Nc[2] << 9;
sr = sr >> 2 | bc[2] << 14;
*c++ = sr >> 7;
sr = sr >> 2 | Mc[2] << 14;
sr = sr >> 6 | xmaxc[2] << 10;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[26] << 13;
sr = sr >> 3 | xmc[27] << 13;
sr = sr >> 3 | xmc[28] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[29] << 13;
sr = sr >> 3 | xmc[30] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[31] << 13;
sr = sr >> 3 | xmc[32] << 13;
sr = sr >> 3 | xmc[33] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[34] << 13;
sr = sr >> 3 | xmc[35] << 13;
sr = sr >> 3 | xmc[36] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[37] << 13;
sr = sr >> 3 | xmc[38] << 13;
*c++ = sr >> 8;
sr = sr >> 7 | Nc[3] << 9;
sr = sr >> 2 | bc[3] << 14;
*c++ = sr >> 7;
sr = sr >> 2 | Mc[3] << 14;
sr = sr >> 6 | xmaxc[3] << 10;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[39] << 13;
sr = sr >> 3 | xmc[40] << 13;
sr = sr >> 3 | xmc[41] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[42] << 13;
sr = sr >> 3 | xmc[43] << 13;
*c++ = sr >> 8;
sr = sr >> 3 | xmc[44] << 13;
sr = sr >> 3 | xmc[45] << 13;
sr = sr >> 3 | xmc[46] << 13;
*c++ = sr >> 7;
sr = sr >> 3 | xmc[47] << 13;
sr = sr >> 3 | xmc[48] << 13;
sr = sr >> 3 | xmc[49] << 13;
*c++ = sr >> 6;
sr = sr >> 3 | xmc[50] << 13;
sr = sr >> 3 | xmc[51] << 13;
*c++ = sr >> 8;
}
}
else
#endif /* WAV49 */
{
*c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
| ((LARc[0] >> 2) & 0xF);
*c++ = ((LARc[0] & 0x3) << 6)
| (LARc[1] & 0x3F);
*c++ = ((LARc[2] & 0x1F) << 3)
| ((LARc[3] >> 2) & 0x7);
*c++ = ((LARc[3] & 0x3) << 6)
| ((LARc[4] & 0xF) << 2)
| ((LARc[5] >> 2) & 0x3);
*c++ = ((LARc[5] & 0x3) << 6)
| ((LARc[6] & 0x7) << 3)
| (LARc[7] & 0x7);
*c++ = ((Nc[0] & 0x7F) << 1)
| ((bc[0] >> 1) & 0x1);
*c++ = ((bc[0] & 0x1) << 7)
| ((Mc[0] & 0x3) << 5)
| ((xmaxc[0] >> 1) & 0x1F);
*c++ = ((xmaxc[0] & 0x1) << 7)
| ((xmc[0] & 0x7) << 4)
| ((xmc[1] & 0x7) << 1)
| ((xmc[2] >> 2) & 0x1);
*c++ = ((xmc[2] & 0x3) << 6)
| ((xmc[3] & 0x7) << 3)
| (xmc[4] & 0x7);
*c++ = ((xmc[5] & 0x7) << 5) /* 10 */
| ((xmc[6] & 0x7) << 2)
| ((xmc[7] >> 1) & 0x3);
*c++ = ((xmc[7] & 0x1) << 7)
| ((xmc[8] & 0x7) << 4)
| ((xmc[9] & 0x7) << 1)
| ((xmc[10] >> 2) & 0x1);
*c++ = ((xmc[10] & 0x3) << 6)
| ((xmc[11] & 0x7) << 3)
| (xmc[12] & 0x7);
*c++ = ((Nc[1] & 0x7F) << 1)
| ((bc[1] >> 1) & 0x1);
*c++ = ((bc[1] & 0x1) << 7)
| ((Mc[1] & 0x3) << 5)
| ((xmaxc[1] >> 1) & 0x1F);
*c++ = ((xmaxc[1] & 0x1) << 7)
| ((xmc[13] & 0x7) << 4)
| ((xmc[14] & 0x7) << 1)
| ((xmc[15] >> 2) & 0x1);
*c++ = ((xmc[15] & 0x3) << 6)
| ((xmc[16] & 0x7) << 3)
| (xmc[17] & 0x7);
*c++ = ((xmc[18] & 0x7) << 5)
| ((xmc[19] & 0x7) << 2)
| ((xmc[20] >> 1) & 0x3);
*c++ = ((xmc[20] & 0x1) << 7)
| ((xmc[21] & 0x7) << 4)
| ((xmc[22] & 0x7) << 1)
| ((xmc[23] >> 2) & 0x1);
*c++ = ((xmc[23] & 0x3) << 6)
| ((xmc[24] & 0x7) << 3)
| (xmc[25] & 0x7);
*c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
| ((bc[2] >> 1) & 0x1);
*c++ = ((bc[2] & 0x1) << 7)
| ((Mc[2] & 0x3) << 5)
| ((xmaxc[2] >> 1) & 0x1F);
*c++ = ((xmaxc[2] & 0x1) << 7)
| ((xmc[26] & 0x7) << 4)
| ((xmc[27] & 0x7) << 1)
| ((xmc[28] >> 2) & 0x1);
*c++ = ((xmc[28] & 0x3) << 6)
| ((xmc[29] & 0x7) << 3)
| (xmc[30] & 0x7);
*c++ = ((xmc[31] & 0x7) << 5)
| ((xmc[32] & 0x7) << 2)
| ((xmc[33] >> 1) & 0x3);
*c++ = ((xmc[33] & 0x1) << 7)
| ((xmc[34] & 0x7) << 4)
| ((xmc[35] & 0x7) << 1)
| ((xmc[36] >> 2) & 0x1);
*c++ = ((xmc[36] & 0x3) << 6)
| ((xmc[37] & 0x7) << 3)
| (xmc[38] & 0x7);
*c++ = ((Nc[3] & 0x7F) << 1)
| ((bc[3] >> 1) & 0x1);
*c++ = ((bc[3] & 0x1) << 7)
| ((Mc[3] & 0x3) << 5)
| ((xmaxc[3] >> 1) & 0x1F);
*c++ = ((xmaxc[3] & 0x1) << 7)
| ((xmc[39] & 0x7) << 4)
| ((xmc[40] & 0x7) << 1)
| ((xmc[41] >> 2) & 0x1);
*c++ = ((xmc[41] & 0x3) << 6) /* 30 */
| ((xmc[42] & 0x7) << 3)
| (xmc[43] & 0x7);
*c++ = ((xmc[44] & 0x7) << 5)
| ((xmc[45] & 0x7) << 2)
| ((xmc[46] >> 1) & 0x3);
*c++ = ((xmc[46] & 0x1) << 7)
| ((xmc[47] & 0x7) << 4)
| ((xmc[48] & 0x7) << 1)
| ((xmc[49] >> 2) & 0x1);
*c++ = ((xmc[49] & 0x3) << 6)
| ((xmc[50] & 0x7) << 3)
| (xmc[51] & 0x7);
}
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: cfe9c43d-d97c-4216-b5e5-ccd6a25b582b
*/

View File

@@ -1,74 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include "gsm610_priv.h"
#include "gsm.h"
int gsm_option (gsm r, int opt, int * val)
{
int result = -1;
switch (opt) {
case GSM_OPT_LTP_CUT:
#ifdef LTP_CUT
result = r->ltp_cut;
if (val) r->ltp_cut = *val;
#endif
break;
case GSM_OPT_VERBOSE:
#ifndef NDEBUG
result = r->verbose;
if (val) r->verbose = *val;
#endif
break;
case GSM_OPT_FAST:
#if defined(FAST) && defined(USE_FLOAT_MUL)
result = r->fast;
if (val) r->fast = !!*val;
#endif
break;
case GSM_OPT_FRAME_CHAIN:
#ifdef WAV49
result = r->frame_chain;
if (val) r->frame_chain = *val;
#endif
break;
case GSM_OPT_FRAME_INDEX:
#ifdef WAV49
result = r->frame_index;
if (val) r->frame_index = *val;
#endif
break;
case GSM_OPT_WAV49:
#ifdef WAV49
result = r->wav_fmt;
if (val) r->wav_fmt = !!*val;
#endif
break;
default:
break;
}
return result;
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 963ff156-506f-4359-9145-371e9060b030
*/

View File

@@ -1,951 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
/*
* 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
*/
/*
* This module computes the LTP gain (bc) and the LTP lag (Nc)
* for the long term analysis filter. This is done by calculating a
* maximum of the cross-correlation function between the current
* sub-segment short term residual signal d[0..39] (output of
* the short term analysis filter; for simplification the index
* of this array begins at 0 and ends at 39 for each sub-segment of the
* RPE-LTP analysis) and the previous reconstructed short term
* residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
* performed to avoid overflow.
*/
/* The next procedure exists in six versions. First two integer
* version (if USE_FLOAT_MUL is not defined); then four floating
* point versions, twice with proper scaling (USE_FLOAT_MUL defined),
* once without (USE_FLOAT_MUL and FAST defined, and fast run-time
* option used). Every pair has first a Cut version (see the -C
* option to toast or the LTP_CUT option to gsm_option()), then the
* uncut one. (For a detailed explanation of why this is altogether
* a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
* Harmful''.)
*/
#ifndef USE_FLOAT_MUL
#ifdef LTP_CUT
static void Cut_Calculation_of_the_LTP_parameters (
struct gsm_state * st,
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
word wt[40];
longword L_result;
longword L_max, L_power;
word R, S, dmax, scal, best_k;
word ltp_cut;
register word temp, wt_k;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = d[k];
temp = GSM_ABS( temp );
if (temp > dmax) {
dmax = temp;
best_k = k;
}
}
temp = 0;
if (dmax == 0) scal = 0;
else {
assert(dmax > 0);
temp = gsm_norm( (longword)dmax << 16 );
}
if (temp > 6) scal = 0;
else scal = 6 - temp;
assert(scal >= 0);
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
wt_k = SASR_W(d[best_k], scal);
for (lambda = 40; lambda <= 120; lambda++) {
L_result = (longword)wt_k * dp[best_k - lambda];
if (L_result > L_max) {
Nc = lambda;
L_max = L_result;
}
}
*Nc_out = Nc;
L_max <<= 1;
/* Rescaling of L_max
*/
assert(scal <= 100 && scal >= -100);
L_max = L_max >> (6 - scal); /* sub(6, scal) */
assert( Nc <= 120 && Nc >= 40);
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
L_power = 0;
for (k = 0; k <= 39; k++) {
register longword L_temp;
L_temp = SASR_W( dp[k - Nc], 3 );
L_power += L_temp * L_temp;
}
L_power <<= 1; /* from L_MULT */
/* Normalization of L_max and L_power
*/
if (L_max <= 0) {
*bc_out = 0;
return;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
temp = gsm_norm( L_power );
R = SASR( L_max << temp, 16 );
S = SASR( L_power << temp, 16 );
/* Coding of the LTP gain
*/
/* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
*bc_out = bc;
}
#endif /* LTP_CUT */
static void Calculation_of_the_LTP_parameters (
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
word wt[40];
longword L_max, L_power;
word R, S, dmax, scal;
register word temp;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = d[k];
temp = GSM_ABS( temp );
if (temp > dmax) dmax = temp;
}
temp = 0;
if (dmax == 0) scal = 0;
else {
assert(dmax > 0);
temp = gsm_norm( (longword)dmax << 16 );
}
if (temp > 6) scal = 0;
else scal = 6 - temp;
assert(scal >= 0);
/* Initialization of a working array wt
*/
for (k = 0; k <= 39; k++) wt[k] = SASR_W( d[k], scal );
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
for (lambda = 40; lambda <= 120; lambda++) {
# undef STEP
# define STEP(k) (longword)wt[k] * dp[k - lambda]
register longword L_result;
L_result = STEP(0) ; L_result += STEP(1) ;
L_result += STEP(2) ; L_result += STEP(3) ;
L_result += STEP(4) ; L_result += STEP(5) ;
L_result += STEP(6) ; L_result += STEP(7) ;
L_result += STEP(8) ; L_result += STEP(9) ;
L_result += STEP(10) ; L_result += STEP(11) ;
L_result += STEP(12) ; L_result += STEP(13) ;
L_result += STEP(14) ; L_result += STEP(15) ;
L_result += STEP(16) ; L_result += STEP(17) ;
L_result += STEP(18) ; L_result += STEP(19) ;
L_result += STEP(20) ; L_result += STEP(21) ;
L_result += STEP(22) ; L_result += STEP(23) ;
L_result += STEP(24) ; L_result += STEP(25) ;
L_result += STEP(26) ; L_result += STEP(27) ;
L_result += STEP(28) ; L_result += STEP(29) ;
L_result += STEP(30) ; L_result += STEP(31) ;
L_result += STEP(32) ; L_result += STEP(33) ;
L_result += STEP(34) ; L_result += STEP(35) ;
L_result += STEP(36) ; L_result += STEP(37) ;
L_result += STEP(38) ; L_result += STEP(39) ;
if (L_result > L_max) {
Nc = lambda;
L_max = L_result;
}
}
*Nc_out = Nc;
L_max <<= 1;
/* Rescaling of L_max
*/
assert(scal <= 100 && scal >= -100);
L_max = L_max >> (6 - scal); /* sub(6, scal) */
assert( Nc <= 120 && Nc >= 40);
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
L_power = 0;
for (k = 0; k <= 39; k++) {
register longword L_temp;
L_temp = SASR_W( dp[k - Nc], 3 );
L_power += L_temp * L_temp;
}
L_power <<= 1; /* from L_MULT */
/* Normalization of L_max and L_power
*/
if (L_max <= 0) {
*bc_out = 0;
return;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
temp = gsm_norm( L_power );
R = SASR_L( L_max << temp, 16 );
S = SASR_L( L_power << temp, 16 );
/* Coding of the LTP gain
*/
/* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
*bc_out = bc;
}
#else /* USE_FLOAT_MUL */
#ifdef LTP_CUT
static void Cut_Calculation_of_the_LTP_parameters (
struct gsm_state * st, /* IN */
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
word ltp_cut;
float wt_float[40];
float dp_float_base[120], * dp_float = dp_float_base + 120;
longword L_max, L_power;
word R, S, dmax, scal;
register word temp;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = d[k];
temp = GSM_ABS( temp );
if (temp > dmax) dmax = temp;
}
temp = 0;
if (dmax == 0) scal = 0;
else {
assert(dmax > 0);
temp = gsm_norm( (longword)dmax << 16 );
}
if (temp > 6) scal = 0;
else scal = 6 - temp;
assert(scal >= 0);
ltp_cut = (longword)SASR_W(dmax, scal) * st->ltp_cut / 100;
/* Initialization of a working array wt
*/
for (k = 0; k < 40; k++) {
register word w = SASR_W( d[k], scal );
if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
wt_float[k] = 0.0;
}
else {
wt_float[k] = w;
}
}
for (k = -120; k < 0; k++) dp_float[k] = dp[k];
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
for (lambda = 40; lambda <= 120; lambda += 9) {
/* Calculate L_result for l = lambda .. lambda + 9.
*/
register float *lp = dp_float - lambda;
register float W;
register float a = lp[-8], b = lp[-7], c = lp[-6],
d = lp[-5], e = lp[-4], f = lp[-3],
g = lp[-2], h = lp[-1];
register float E;
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
# undef STEP
# define STEP(K, a, b, c, d, e, f, g, h) \
if ((W = wt_float[K]) != 0.0) { \
E = W * a; S8 += E; \
E = W * b; S7 += E; \
E = W * c; S6 += E; \
E = W * d; S5 += E; \
E = W * e; S4 += E; \
E = W * f; S3 += E; \
E = W * g; S2 += E; \
E = W * h; S1 += E; \
a = lp[K]; \
E = W * a; S0 += E; } else (a = lp[K])
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
if (S0 > L_max) { L_max = S0; Nc = lambda; }
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
}
*Nc_out = Nc;
L_max <<= 1;
/* Rescaling of L_max
*/
assert(scal <= 100 && scal >= -100);
L_max = L_max >> (6 - scal); /* sub(6, scal) */
assert( Nc <= 120 && Nc >= 40);
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
L_power = 0;
for (k = 0; k <= 39; k++) {
register longword L_temp;
L_temp = SASR_W( dp[k - Nc], 3 );
L_power += L_temp * L_temp;
}
L_power <<= 1; /* from L_MULT */
/* Normalization of L_max and L_power
*/
if (L_max <= 0) {
*bc_out = 0;
return;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
temp = gsm_norm( L_power );
R = SASR( L_max << temp, 16 );
S = SASR( L_power << temp, 16 );
/* Coding of the LTP gain
*/
/* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
*bc_out = bc;
}
#endif /* LTP_CUT */
static void Calculation_of_the_LTP_parameters (
register word * din, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
float wt_float[40];
float dp_float_base[120], * dp_float = dp_float_base + 120;
longword L_max, L_power;
word R, S, dmax, scal;
register word temp;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = din [k] ;
temp = GSM_ABS (temp) ;
if (temp > dmax) dmax = temp;
}
temp = 0;
if (dmax == 0) scal = 0;
else {
assert(dmax > 0);
temp = gsm_norm( (longword)dmax << 16 );
}
if (temp > 6) scal = 0;
else scal = 6 - temp;
assert(scal >= 0);
/* Initialization of a working array wt
*/
for (k = 0; k < 40; k++) wt_float[k] = SASR_W (din [k], scal) ;
for (k = -120; k < 0; k++) dp_float[k] = dp[k];
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
for (lambda = 40; lambda <= 120; lambda += 9) {
/* Calculate L_result for l = lambda .. lambda + 9.
*/
register float *lp = dp_float - lambda;
register float W;
register float a = lp[-8], b = lp[-7], c = lp[-6],
d = lp[-5], e = lp[-4], f = lp[-3],
g = lp[-2], h = lp[-1];
register float E;
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
# undef STEP
# define STEP(K, a, b, c, d, e, f, g, h) \
W = wt_float[K]; \
E = W * a; S8 += E; \
E = W * b; S7 += E; \
E = W * c; S6 += E; \
E = W * d; S5 += E; \
E = W * e; S4 += E; \
E = W * f; S3 += E; \
E = W * g; S2 += E; \
E = W * h; S1 += E; \
a = lp[K]; \
E = W * a; S0 += E
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
if (S0 > L_max) { L_max = S0; Nc = lambda; }
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
}
*Nc_out = Nc;
L_max <<= 1;
/* Rescaling of L_max
*/
assert(scal <= 100 && scal >= -100);
L_max = L_max >> (6 - scal); /* sub(6, scal) */
assert( Nc <= 120 && Nc >= 40);
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
L_power = 0;
for (k = 0; k <= 39; k++) {
register longword L_temp;
L_temp = SASR_W( dp[k - Nc], 3 );
L_power += L_temp * L_temp;
}
L_power <<= 1; /* from L_MULT */
/* Normalization of L_max and L_power
*/
if (L_max <= 0) {
*bc_out = 0;
return;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
temp = gsm_norm( L_power );
R = SASR_L ( L_max << temp, 16 );
S = SASR_L ( L_power << temp, 16 );
/* Coding of the LTP gain
*/
/* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
*bc_out = bc;
}
#ifdef FAST
#ifdef LTP_CUT
static void Cut_Fast_Calculation_of_the_LTP_parameters (
struct gsm_state * st, /* IN */
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
register float wt_float;
word Nc, bc;
word wt_max, best_k, ltp_cut;
float dp_float_base[120], * dp_float = dp_float_base + 120;
register float L_result, L_max, L_power;
wt_max = 0;
for (k = 0; k < 40; ++k) {
if ( d[k] > wt_max) wt_max = d[best_k = k];
else if (-d[k] > wt_max) wt_max = -d[best_k = k];
}
assert(wt_max >= 0);
wt_float = (float)wt_max;
for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
for (lambda = 40; lambda <= 120; lambda++) {
L_result = wt_float * dp_float[best_k - lambda];
if (L_result > L_max) {
Nc = lambda;
L_max = L_result;
}
}
*Nc_out = Nc;
if (L_max <= 0.) {
*bc_out = 0;
return;
}
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
dp_float -= Nc;
L_power = 0;
for (k = 0; k < 40; ++k) {
register float f = dp_float[k];
L_power += f * f;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
/* Coding of the LTP gain
* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
lambda = L_max / L_power * 32768.;
for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
*bc_out = bc;
}
#endif /* LTP_CUT */
static void Fast_Calculation_of_the_LTP_parameters (
register word * din, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
float wt_float[40];
float dp_float_base[120], * dp_float = dp_float_base + 120;
register float L_max, L_power;
for (k = 0; k < 40; ++k) wt_float[k] = (float) din [k] ;
for (k = -120; k < 0; ++k) dp_float[k] = (float) dp [k] ;
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
for (lambda = 40; lambda <= 120; lambda += 9) {
/* Calculate L_result for l = lambda .. lambda + 9.
*/
register float *lp = dp_float - lambda;
register float W;
register float a = lp[-8], b = lp[-7], c = lp[-6],
d = lp[-5], e = lp[-4], f = lp[-3],
g = lp[-2], h = lp[-1];
register float E;
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
# undef STEP
# define STEP(K, a, b, c, d, e, f, g, h) \
W = wt_float[K]; \
E = W * a; S8 += E; \
E = W * b; S7 += E; \
E = W * c; S6 += E; \
E = W * d; S5 += E; \
E = W * e; S4 += E; \
E = W * f; S3 += E; \
E = W * g; S2 += E; \
E = W * h; S1 += E; \
a = lp[K]; \
E = W * a; S0 += E
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
if (S0 > L_max) { L_max = S0; Nc = lambda; }
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
}
*Nc_out = Nc;
if (L_max <= 0.) {
*bc_out = 0;
return;
}
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
dp_float -= Nc;
L_power = 0;
for (k = 0; k < 40; ++k) {
register float f = dp_float[k];
L_power += f * f;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
/* Coding of the LTP gain
* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
lambda = L_max / L_power * 32768.;
for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
*bc_out = bc;
}
#endif /* FAST */
#endif /* USE_FLOAT_MUL */
/* 4.2.12 */
static void Long_term_analysis_filtering (
word bc, /* IN */
word Nc, /* IN */
register word * dp, /* previous d [-120..-1] IN */
register word * d, /* d [0..39] IN */
register word * dpp, /* estimate [0..39] OUT */
register word * e /* long term res. signal [0..39] OUT */
)
/*
* In this part, we have to decode the bc parameter to compute
* the samples of the estimate dpp[0..39]. The decoding of bc needs the
* use of table 4.3b. The long term residual signal e[0..39]
* is then calculated to be fed to the RPE encoding section.
*/
{
register int k;
# undef STEP
# define STEP(BP) \
for (k = 0; k <= 39; k++) { \
dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \
e[k] = GSM_SUB( d[k], dpp[k] ); \
}
switch (bc) {
case 0: STEP( 3277 ); break;
case 1: STEP( 11469 ); break;
case 2: STEP( 21299 ); break;
case 3: STEP( 32767 ); break;
}
}
void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */
struct gsm_state * S,
word * d, /* [0..39] residual signal IN */
word * dp, /* [-120..-1] d' IN */
word * e, /* [0..39] OUT */
word * dpp, /* [0..39] OUT */
word * Nc, /* correlation lag OUT */
word * bc /* gain factor OUT */
)
{
assert( d ); assert( dp ); assert( e );
assert( dpp); assert( Nc ); assert( bc );
#if defined(FAST) && defined(USE_FLOAT_MUL)
if (S->fast)
#if defined (LTP_CUT)
if (S->ltp_cut)
Cut_Fast_Calculation_of_the_LTP_parameters(S,
d, dp, bc, Nc);
else
#endif /* LTP_CUT */
Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
else
#endif /* FAST & USE_FLOAT_MUL */
#ifdef LTP_CUT
if (S->ltp_cut)
Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
else
#endif
Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
}
/* 4.3.2 */
void Gsm_Long_Term_Synthesis_Filtering (
struct gsm_state * S,
word Ncr,
word bcr,
register word * erp, /* [0..39] IN */
register word * drp /* [-120..-1] IN, [-120..40] OUT */
)
/*
* This procedure uses the bcr and Ncr parameter to realize the
* long term synthesis filtering. The decoding of bcr needs
* table 4.3b.
*/
{
register int k;
word brp, drpp, Nr;
/* Check the limits of Nr.
*/
Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
S->nrp = Nr;
assert(Nr >= 40 && Nr <= 120);
/* Decoding of the LTP gain bcr
*/
brp = gsm_QLB[ bcr ];
/* Computation of the reconstructed short term residual
* signal drp[0..39]
*/
assert(brp != MIN_WORD);
for (k = 0; k <= 39; k++) {
drpp = GSM_MULT_R( brp, drp[ k - Nr ] );
drp[k] = GSM_ADD( erp[k], drpp );
}
/*
* Update of the reconstructed short term residual signal
* drp[ -1..-120 ]
*/
for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: b369b90d-0284-42a0-87b0-99a25bbd93ac
*/

View File

@@ -1,341 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
/*
* 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
*/
/* 4.2.4 */
static void Autocorrelation (
word * s, /* [0..159] IN/OUT */
longword * L_ACF) /* [0..8] OUT */
/*
* The goal is to compute the array L_ACF[k]. The signal s[i] must
* be scaled in order to avoid an overflow situation.
*/
{
register int k, i;
word temp, smax, scalauto;
#ifdef USE_FLOAT_MUL
float float_s[160];
#endif
/* Dynamic scaling of the array s[0..159]
*/
/* Search for the maximum.
*/
smax = 0;
for (k = 0; k <= 159; k++) {
temp = GSM_ABS( s[k] );
if (temp > smax) smax = temp;
}
/* Computation of the scaling factor.
*/
if (smax == 0) scalauto = 0;
else {
assert(smax > 0);
scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
}
/* Scaling of the array s[0...159]
*/
if (scalauto > 0) {
# ifdef USE_FLOAT_MUL
# define SCALE(n) \
case n: for (k = 0; k <= 159; k++) \
float_s[k] = (float) \
(s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
break;
# else
# define SCALE(n) \
case n: for (k = 0; k <= 159; k++) \
s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
break;
# endif /* USE_FLOAT_MUL */
switch (scalauto) {
SCALE(1)
SCALE(2)
SCALE(3)
SCALE(4)
}
# undef SCALE
}
# ifdef USE_FLOAT_MUL
else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
# endif
/* Compute the L_ACF[..].
*/
{
# ifdef USE_FLOAT_MUL
register float * sp = float_s;
register float sl = *sp;
# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]);
# else
word * sp = s;
word sl = *sp;
# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]);
# endif
# define NEXTI sl = *++sp
for (k = 9; k--; L_ACF[k] = 0) ;
STEP (0);
NEXTI;
STEP(0); STEP(1);
NEXTI;
STEP(0); STEP(1); STEP(2);
NEXTI;
STEP(0); STEP(1); STEP(2); STEP(3);
NEXTI;
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
NEXTI;
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
NEXTI;
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
NEXTI;
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
for (i = 8; i <= 159; i++) {
NEXTI;
STEP(0);
STEP(1); STEP(2); STEP(3); STEP(4);
STEP(5); STEP(6); STEP(7); STEP(8);
}
for (k = 9; k--; L_ACF[k] <<= 1) ;
}
/* Rescaling of the array s[0..159]
*/
if (scalauto > 0) {
assert(scalauto <= 4);
for (k = 160; k--; *s++ <<= scalauto) ;
}
}
#if defined(USE_FLOAT_MUL) && defined(FAST)
static void Fast_Autocorrelation (
word * s, /* [0..159] IN/OUT */
longword * L_ACF) /* [0..8] OUT */
{
register int k, i;
float f_L_ACF[9];
float scale;
float s_f[160];
register float *sf = s_f;
for (i = 0; i < 160; ++i) sf[i] = s[i];
for (k = 0; k <= 8; k++) {
register float L_temp2 = 0;
register float *sfl = sf - k;
for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
f_L_ACF[k] = L_temp2;
}
scale = MAX_LONGWORD / f_L_ACF[0];
for (k = 0; k <= 8; k++) {
L_ACF[k] = f_L_ACF[k] * scale;
}
}
#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
/* 4.2.5 */
static void Reflection_coefficients (
longword * L_ACF, /* 0...8 IN */
register word * r /* 0...7 OUT */
)
{
register int i, m, n;
register word temp;
word ACF[9]; /* 0..8 */
word P[ 9]; /* 0..8 */
word K[ 9]; /* 2..8 */
/* Schur recursion with 16 bits arithmetic.
*/
if (L_ACF[0] == 0) {
for (i = 8; i--; *r++ = 0) ;
return;
}
assert( L_ACF[0] != 0 );
temp = gsm_norm( L_ACF[0] );
assert(temp >= 0 && temp < 32);
/* ? overflow ? */
for (i = 0; i <= 8; i++) ACF[i] = SASR_L( L_ACF[i] << temp, 16 );
/* Initialize array P[..] and K[..] for the recursion.
*/
for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
/* Compute reflection coefficients
*/
for (n = 1; n <= 8; n++, r++) {
temp = P[1];
temp = GSM_ABS(temp);
if (P[0] < temp) {
for (i = n; i <= 8; i++) *r++ = 0;
return;
}
*r = gsm_div( temp, P[0] );
assert(*r >= 0);
if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */
assert (*r != MIN_WORD);
if (n == 8) return;
/* Schur recursion
*/
temp = GSM_MULT_R( P[1], *r );
P[0] = GSM_ADD( P[0], temp );
for (m = 1; m <= 8 - n; m++) {
temp = GSM_MULT_R( K[ m ], *r );
P[m] = GSM_ADD( P[ m+1 ], temp );
temp = GSM_MULT_R( P[ m+1 ], *r );
K[m] = GSM_ADD( K[ m ], temp );
}
}
}
/* 4.2.6 */
static void Transformation_to_Log_Area_Ratios (
register word * r /* 0..7 IN/OUT */
)
/*
* The following scaling for r[..] and LAR[..] has been used:
*
* r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1.
* LAR[..] = integer( real_LAR[..] * 16384 );
* with -1.625 <= real_LAR <= 1.625
*/
{
register word temp;
register int i;
/* Computation of the LAR[0..7] from the r[0..7]
*/
for (i = 1; i <= 8; i++, r++) {
temp = *r;
temp = GSM_ABS(temp);
assert(temp >= 0);
if (temp < 22118) {
temp >>= 1;
} else if (temp < 31130) {
assert( temp >= 11059 );
temp -= 11059;
} else {
assert( temp >= 26112 );
temp -= 26112;
temp <<= 2;
}
*r = *r < 0 ? -temp : temp;
assert( *r != MIN_WORD );
}
}
/* 4.2.7 */
static void Quantization_and_coding (
register word * LAR /* [0..7] IN/OUT */
)
{
register word temp;
/* This procedure needs four tables; the following equations
* give the optimum scaling for the constants:
*
* A[0..7] = integer( real_A[0..7] * 1024 )
* B[0..7] = integer( real_B[0..7] * 512 )
* MAC[0..7] = maximum of the LARc[0..7]
* MIC[0..7] = minimum of the LARc[0..7]
*/
# undef STEP
# define STEP( A, B, MAC, MIC ) \
temp = GSM_MULT( A, *LAR ); \
temp = GSM_ADD( temp, B ); \
temp = GSM_ADD( temp, 256 ); \
temp = SASR_W( temp, 9 ); \
*LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
LAR++;
STEP( 20480, 0, 31, -32 );
STEP( 20480, 0, 31, -32 );
STEP( 20480, 2048, 15, -16 );
STEP( 20480, -2560, 15, -16 );
STEP( 13964, 94, 7, -8 );
STEP( 15360, -1792, 7, -8 );
STEP( 8534, -341, 3, -4 );
STEP( 9036, -1144, 3, -4 );
# undef STEP
}
void Gsm_LPC_Analysis (
struct gsm_state *S,
word * s, /* 0..159 signals IN/OUT */
word * LARc) /* 0..7 LARc's OUT */
{
longword L_ACF[9];
#if defined(USE_FLOAT_MUL) && defined(FAST)
if (S->fast) Fast_Autocorrelation (s, L_ACF );
else
#endif
Autocorrelation (s, L_ACF );
Reflection_coefficients (L_ACF, LARc );
Transformation_to_Log_Area_Ratios (LARc);
Quantization_and_coding (LARc);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 63146664-a002-4e1e-8b7b-f0cc8a6a53da
*/

View File

@@ -1,115 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION
*
* After A-law to linear conversion (or directly from the
* Ato D converter) the following scaling is assumed for
* input to the RPE-LTP algorithm:
*
* in: 0.1.....................12
* S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
*
* Where S is the sign bit, v a valid bit, and * a "don't care" bit.
* The original signal is called sop[..]
*
* out: 0.1................... 12
* S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
*/
void Gsm_Preprocess (
struct gsm_state * S,
word * s,
word * so ) /* [0..159] IN/OUT */
{
word z1 = S->z1;
longword L_z2 = S->L_z2;
word mp = S->mp;
word s1;
longword L_s2;
longword L_temp;
word msp, lsp;
word SO;
register int k = 160;
while (k--) {
/* 4.2.1 Downscaling of the input signal
*/
SO = SASR_W( *s, 3 ) << 2;
s++;
assert (SO >= -0x4000); /* downscaled by */
assert (SO <= 0x3FFC); /* previous routine. */
/* 4.2.2 Offset compensation
*
* This part implements a high-pass filter and requires extended
* arithmetic precision for the recursive part of this filter.
* The input of this procedure is the array so[0...159] and the
* output the array sof[ 0...159 ].
*/
/* Compute the non-recursive part
*/
s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */
z1 = SO;
assert(s1 != MIN_WORD);
/* Compute the recursive part
*/
L_s2 = s1;
L_s2 <<= 15;
/* Execution of a 31 bv 16 bits multiplication
*/
msp = SASR_L( L_z2, 15 );
lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */
L_s2 += GSM_MULT_R( lsp, 32735 );
L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
L_z2 = GSM_L_ADD( L_temp, L_s2 );
/* Compute sof[k] with rounding
*/
L_temp = GSM_L_ADD( L_z2, 16384 );
/* 4.2.3 Preemphasis
*/
msp = GSM_MULT_R( mp, -28180 );
mp = SASR_L( L_temp, 15 );
*so++ = GSM_ADD( mp, msp );
}
S->z1 = z1;
S->L_z2 = L_z2;
S->mp = mp;
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: b760b0d9-3a05-4da3-9dc9-441ffb905d87
*/

View File

@@ -1,490 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION
*/
/* 4.2.13 */
static void Weighting_filter (
register word * e, /* signal [-5..0.39.44] IN */
word * x /* signal [0..39] OUT */
)
/*
* The coefficients of the weighting filter are stored in a table
* (see table 4.4). The following scaling is used:
*
* H[0..10] = integer( real_H[ 0..10] * 8192 );
*/
{
/* word wt[ 50 ]; */
register longword L_result;
register int k /* , i */ ;
/* Initialization of a temporary working array wt[0...49]
*/
/* for (k = 0; k <= 4; k++) wt[k] = 0;
* for (k = 5; k <= 44; k++) wt[k] = *e++;
* for (k = 45; k <= 49; k++) wt[k] = 0;
*
* (e[-5..-1] and e[40..44] are allocated by the caller,
* are initially zero and are not written anywhere.)
*/
e -= 5;
/* Compute the signal x[0..39]
*/
for (k = 0; k <= 39; k++) {
L_result = 8192 >> 1;
/* for (i = 0; i <= 10; i++) {
* L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] );
* L_result = GSM_L_ADD( L_result, L_temp );
* }
*/
#undef STEP
#define STEP( i, H ) (e[ k + i ] * (longword)H)
/* Every one of these multiplications is done twice --
* but I don't see an elegant way to optimize this.
* Do you?
*/
#ifdef STUPID_COMPILER
L_result += STEP( 0, -134 ) ;
L_result += STEP( 1, -374 ) ;
/* + STEP( 2, 0 ) */
L_result += STEP( 3, 2054 ) ;
L_result += STEP( 4, 5741 ) ;
L_result += STEP( 5, 8192 ) ;
L_result += STEP( 6, 5741 ) ;
L_result += STEP( 7, 2054 ) ;
/* + STEP( 8, 0 ) */
L_result += STEP( 9, -374 ) ;
L_result += STEP( 10, -134 ) ;
#else
L_result +=
STEP( 0, -134 )
+ STEP( 1, -374 )
/* + STEP( 2, 0 ) */
+ STEP( 3, 2054 )
+ STEP( 4, 5741 )
+ STEP( 5, 8192 )
+ STEP( 6, 5741 )
+ STEP( 7, 2054 )
/* + STEP( 8, 0 ) */
+ STEP( 9, -374 )
+ STEP(10, -134 )
;
#endif
/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
*
* x[k] = SASR( L_result, 16 );
*/
/* 2 adds vs. >>16 => 14, minus one shift to compensate for
* those we lost when replacing L_MULT by '*'.
*/
L_result = SASR_L( L_result, 13 );
x[k] = ( L_result < MIN_WORD ? MIN_WORD
: (L_result > MAX_WORD ? MAX_WORD : L_result ));
}
}
/* 4.2.14 */
static void RPE_grid_selection (
word * x, /* [0..39] IN */
word * xM, /* [0..12] OUT */
word * Mc_out /* OUT */
)
/*
* The signal x[0..39] is used to select the RPE grid which is
* represented by Mc.
*/
{
/* register word temp1; */
register int /* m, */ i;
register longword L_result, L_temp;
longword EM; /* xxx should be L_EM? */
word Mc;
longword L_common_0_3;
EM = 0;
Mc = 0;
/* for (m = 0; m <= 3; m++) {
* L_result = 0;
*
*
* for (i = 0; i <= 12; i++) {
*
* temp1 = SASR_W( x[m + 3*i], 2 );
*
* assert(temp1 != MIN_WORD);
*
* L_temp = GSM_L_MULT( temp1, temp1 );
* L_result = GSM_L_ADD( L_temp, L_result );
* }
*
* if (L_result > EM) {
* Mc = m;
* EM = L_result;
* }
* }
*/
#undef STEP
#define STEP( m, i ) L_temp = SASR_W( x[m + 3 * i], 2 ); \
L_result += L_temp * L_temp;
/* common part of 0 and 3 */
L_result = 0;
STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
L_common_0_3 = L_result;
/* i = 0 */
STEP( 0, 0 );
L_result <<= 1; /* implicit in L_MULT */
EM = L_result;
/* i = 1 */
L_result = 0;
STEP( 1, 0 );
STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
L_result <<= 1;
if (L_result > EM) {
Mc = 1;
EM = L_result;
}
/* i = 2 */
L_result = 0;
STEP( 2, 0 );
STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
L_result <<= 1;
if (L_result > EM) {
Mc = 2;
EM = L_result;
}
/* i = 3 */
L_result = L_common_0_3;
STEP( 3, 12 );
L_result <<= 1;
if (L_result > EM) {
Mc = 3;
EM = L_result;
}
/**/
/* Down-sampling by a factor 3 to get the selected xM[0..12]
* RPE sequence.
*/
for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
*Mc_out = Mc;
}
/* 4.12.15 */
static void APCM_quantization_xmaxc_to_exp_mant (
word xmaxc, /* IN */
word * expon_out, /* OUT */
word * mant_out ) /* OUT */
{
word expon, mant;
/* Compute expononent and mantissa of the decoded version of xmaxc
*/
expon = 0;
if (xmaxc > 15) expon = SASR_W(xmaxc, 3) - 1;
mant = xmaxc - (expon << 3);
if (mant == 0) {
expon = -4;
mant = 7;
}
else {
while (mant <= 7) {
mant = mant << 1 | 1;
expon--;
}
mant -= 8;
}
assert( expon >= -4 && expon <= 6 );
assert( mant >= 0 && mant <= 7 );
*expon_out = expon;
*mant_out = mant;
}
static void APCM_quantization (
word * xM, /* [0..12] IN */
word * xMc, /* [0..12] OUT */
word * mant_out, /* OUT */
word * expon_out, /* OUT */
word * xmaxc_out /* OUT */
)
{
int i, itest;
word xmax, xmaxc, temp, temp1, temp2;
word expon, mant;
/* Find the maximum absolute value xmax of xM[0..12].
*/
xmax = 0;
for (i = 0; i <= 12; i++) {
temp = xM[i];
temp = GSM_ABS(temp);
if (temp > xmax) xmax = temp;
}
/* Qantizing and coding of xmax to get xmaxc.
*/
expon = 0;
temp = SASR_W( xmax, 9 );
itest = 0;
for (i = 0; i <= 5; i++) {
itest |= (temp <= 0);
temp = SASR_W( temp, 1 );
assert(expon <= 5);
if (itest == 0) expon++; /* expon = add (expon, 1) */
}
assert(expon <= 6 && expon >= 0);
temp = expon + 5;
assert(temp <= 11 && temp >= 0);
xmaxc = gsm_add( SASR_W(xmax, temp), (word) (expon << 3) );
/* Quantizing and coding of the xM[0..12] RPE sequence
* to get the xMc[0..12]
*/
APCM_quantization_xmaxc_to_exp_mant( xmaxc, &expon, &mant );
/* This computation uses the fact that the decoded version of xmaxc
* can be calculated by using the expononent and the mantissa part of
* xmaxc (logarithmic table).
* So, this method avoids any division and uses only a scaling
* of the RPE samples by a function of the expononent. A direct
* multiplication by the inverse of the mantissa (NRFAC[0..7]
* found in table 4.5) gives the 3 bit coded version xMc[0..12]
* of the RPE samples.
*/
/* Direct computation of xMc[0..12] using table 4.5
*/
assert( expon <= 4096 && expon >= -4096);
assert( mant >= 0 && mant <= 7 );
temp1 = 6 - expon; /* normalization by the expononent */
temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */
for (i = 0; i <= 12; i++) {
assert(temp1 >= 0 && temp1 < 16);
temp = xM[i] << temp1;
temp = GSM_MULT( temp, temp2 );
temp = SASR_W(temp, 12);
xMc[i] = temp + 4; /* see note below */
}
/* NOTE: This equation is used to make all the xMc[i] positive.
*/
*mant_out = mant;
*expon_out = expon;
*xmaxc_out = xmaxc;
}
/* 4.2.16 */
static void APCM_inverse_quantization (
register word * xMc, /* [0..12] IN */
word mant,
word expon,
register word * xMp) /* [0..12] OUT */
/*
* This part is for decoding the RPE sequence of coded xMc[0..12]
* samples to obtain the xMp[0..12] array. Table 4.6 is used to get
* the mantissa of xmaxc (FAC[0..7]).
*/
{
int i;
word temp, temp1, temp2, temp3;
assert( mant >= 0 && mant <= 7 );
temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */
temp2 = gsm_sub( 6, expon ); /* see 4.2-15 for exp */
temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
for (i = 13; i--;) {
assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */
/* temp = gsm_sub( *xMc++ << 1, 7 ); */
temp = (*xMc++ << 1) - 7; /* restore sign */
assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */
temp <<= 12; /* 16 bit signed */
temp = GSM_MULT_R( temp1, temp );
temp = GSM_ADD( temp, temp3 );
*xMp++ = gsm_asr( temp, temp2 );
}
}
/* 4.2.17 */
static void RPE_grid_positioning (
word Mc, /* grid position IN */
register word * xMp, /* [0..12] IN */
register word * ep /* [0..39] OUT */
)
/*
* This procedure computes the reconstructed long term residual signal
* ep[0..39] for the LTP analysis filter. The inputs are the Mc
* which is the grid position selection and the xMp[0..12] decoded
* RPE samples which are upsampled by a factor of 3 by inserting zero
* values.
*/
{
int i = 13;
assert(0 <= Mc && Mc <= 3);
switch (Mc) {
case 3: *ep++ = 0;
case 2: do {
*ep++ = 0;
case 1: *ep++ = 0;
case 0: *ep++ = *xMp++;
} while (--i);
}
while (++Mc < 4) *ep++ = 0;
/*
int i, k;
for (k = 0; k <= 39; k++) ep[k] = 0;
for (i = 0; i <= 12; i++) {
ep[ Mc + (3*i) ] = xMp[i];
}
*/
}
/* 4.2.18 */
/* This procedure adds the reconstructed long term residual signal
* ep[0..39] to the estimated signal dpp[0..39] from the long term
* analysis filter to compute the reconstructed short term residual
* signal dp[-40..-1]; also the reconstructed short term residual
* array dp[-120..-41] is updated.
*/
#if 0 /* Has been inlined in code.c */
void Gsm_Update_of_reconstructed_short_time_residual_signal (
word * dpp, /* [0...39] IN */
word * ep, /* [0...39] IN */
word * dp) /* [-120...-1] IN/OUT */
{
int k;
for (k = 0; k <= 79; k++)
dp[ -120 + k ] = dp[ -80 + k ];
for (k = 0; k <= 39; k++)
dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
}
#endif /* Has been inlined in code.c */
void Gsm_RPE_Encoding (
/*-struct gsm_state * S,-*/
word * e, /* -5..-1][0..39][40..44 IN/OUT */
word * xmaxc, /* OUT */
word * Mc, /* OUT */
word * xMc) /* [0..12] OUT */
{
word x[40];
word xM[13], xMp[13];
word mant, expon;
Weighting_filter(e, x);
RPE_grid_selection(x, xM, Mc);
APCM_quantization( xM, xMc, &mant, &expon, xmaxc);
APCM_inverse_quantization( xMc, mant, expon, xMp);
RPE_grid_positioning( *Mc, xMp, e );
}
void Gsm_RPE_Decoding (
/*-struct gsm_state * S,-*/
word xmaxcr,
word Mcr,
word * xMcr, /* [0..12], 3 bits IN */
word * erp /* [0..39] OUT */
)
{
word expon, mant;
word xMp[ 13 ];
APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &expon, &mant );
APCM_inverse_quantization( xMcr, mant, expon, xMp );
RPE_grid_positioning( Mcr, xMp, erp );
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 82005b9e-1560-4e94-9ddb-00cb14867295
*/

View File

@@ -1,427 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <stdio.h>
#include <assert.h>
#include "gsm610_priv.h"
#include "gsm.h"
/*
* SHORT TERM ANALYSIS FILTERING SECTION
*/
/* 4.2.8 */
static void Decoding_of_the_coded_Log_Area_Ratios (
word * LARc, /* coded log area ratio [0..7] IN */
word * LARpp) /* out: decoded .. */
{
register word temp1 /* , temp2 */;
/* This procedure requires for efficient implementation
* two tables.
*
* INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
* MIC[1..8] = minimum value of the LARc[1..8]
*/
/* Compute the LARpp[1..8]
*/
/* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
*
* temp1 = GSM_ADD( *LARc, *MIC ) << 10;
* temp2 = *B << 1;
* temp1 = GSM_SUB( temp1, temp2 );
*
* assert(*INVA != MIN_WORD);
*
* temp1 = GSM_MULT_R( *INVA, temp1 );
* *LARpp = GSM_ADD( temp1, temp1 );
* }
*/
#undef STEP
#define STEP( B, MIC, INVA ) \
temp1 = GSM_ADD( *LARc++, MIC ) << 10; \
temp1 = GSM_SUB( temp1, B << 1 ); \
temp1 = GSM_MULT_R( INVA, temp1 ); \
*LARpp++ = GSM_ADD( temp1, temp1 );
STEP( 0, -32, 13107 );
STEP( 0, -32, 13107 );
STEP( 2048, -16, 13107 );
STEP( -2560, -16, 13107 );
STEP( 94, -8, 19223 );
STEP( -1792, -8, 17476 );
STEP( -341, -4, 31454 );
STEP( -1144, -4, 29708 );
/* NOTE: the addition of *MIC is used to restore
* the sign of *LARc.
*/
}
/* 4.2.9 */
/* Computation of the quantized reflection coefficients
*/
/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
*/
/*
* Within each frame of 160 analyzed speech samples the short term
* analysis and synthesis filters operate with four different sets of
* coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
* and the actual set of decoded LARs (LARpp(j))
*
* (Initial value: LARpp(j-1)[1..8] = 0.)
*/
static void Coefficients_0_12 (
register word * LARpp_j_1,
register word * LARpp_j,
register word * LARp)
{
register int i;
for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
*LARp = GSM_ADD( SASR_W( *LARpp_j_1, 2 ), SASR_W( *LARpp_j, 2 ));
*LARp = GSM_ADD( *LARp, SASR_W( *LARpp_j_1, 1));
}
}
static void Coefficients_13_26 (
register word * LARpp_j_1,
register word * LARpp_j,
register word * LARp)
{
register int i;
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
*LARp = GSM_ADD( SASR_W( *LARpp_j_1, 1), SASR_W( *LARpp_j, 1 ));
}
}
static void Coefficients_27_39 (
register word * LARpp_j_1,
register word * LARpp_j,
register word * LARp)
{
register int i;
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
*LARp = GSM_ADD( SASR_W( *LARpp_j_1, 2 ), SASR_W( *LARpp_j, 2 ));
*LARp = GSM_ADD( *LARp, SASR_W( *LARpp_j, 1 ));
}
}
static void Coefficients_40_159 (
register word * LARpp_j,
register word * LARp)
{
register int i;
for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
*LARp = *LARpp_j;
}
/* 4.2.9.2 */
static void LARp_to_rp (
register word * LARp) /* [0..7] IN/OUT */
/*
* The input of this procedure is the interpolated LARp[0..7] array.
* The reflection coefficients, rp[i], are used in the analysis
* filter and in the synthesis filter.
*/
{
register int i;
register word temp;
for (i = 1; i <= 8; i++, LARp++) {
/* temp = GSM_ABS( *LARp );
*
* if (temp < 11059) temp <<= 1;
* else if (temp < 20070) temp += 11059;
* else temp = GSM_ADD( temp >> 2, 26112 );
*
* *LARp = *LARp < 0 ? -temp : temp;
*/
if (*LARp < 0) {
temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
*LARp = - ((temp < 11059) ? temp << 1
: ((temp < 20070) ? temp + 11059
: GSM_ADD( (word) (temp >> 2), (word) 26112 )));
} else {
temp = *LARp;
*LARp = (temp < 11059) ? temp << 1
: ((temp < 20070) ? temp + 11059
: GSM_ADD( (word) (temp >> 2), (word) 26112 ));
}
}
}
/* 4.2.10 */
static void Short_term_analysis_filtering (
struct gsm_state * S,
register word * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register word * s /* [0..n-1] IN/OUT */
)
/*
* This procedure computes the short term residual signal d[..] to be fed
* to the RPE-LTP loop from the s[..] signal and from the local rp[..]
* array (quantized reflection coefficients). As the call of this
* procedure can be done in many ways (see the interpolation of the LAR
* coefficient), it is assumed that the computation begins with index
* k_start (for arrays d[..] and s[..]) and stops with index k_end
* (k_start and k_end are defined in 4.2.9.1). This procedure also
* needs to keep the array u[0..7] in memory for each call.
*/
{
register word * u = S->u;
register int i;
register word di, zzz, ui, sav, rpi;
for (; k_n--; s++) {
di = sav = *s;
for (i = 0; i < 8; i++) { /* YYY */
ui = u[i];
rpi = rp[i];
u[i] = sav;
zzz = GSM_MULT_R(rpi, di);
sav = GSM_ADD( ui, zzz);
zzz = GSM_MULT_R(rpi, ui);
di = GSM_ADD( di, zzz );
}
*s = di;
}
}
#if defined(USE_FLOAT_MUL) && defined(FAST)
static void Fast_Short_term_analysis_filtering (
struct gsm_state * S,
register word * rp, /* [0..7] IN */
register int k_n, /* k_end - k_start */
register word * s /* [0..n-1] IN/OUT */
)
{
register word * u = S->u;
register int i;
float uf[8],
rpf[8];
register float scalef = 3.0517578125e-5;
register float sav, di, temp;
for (i = 0; i < 8; ++i) {
uf[i] = u[i];
rpf[i] = rp[i] * scalef;
}
for (; k_n--; s++) {
sav = di = *s;
for (i = 0; i < 8; ++i) {
register float rpfi = rpf[i];
register float ufi = uf[i];
uf[i] = sav;
temp = rpfi * di + ufi;
di += rpfi * ufi;
sav = temp;
}
*s = di;
}
for (i = 0; i < 8; ++i) u[i] = uf[i];
}
#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
static void Short_term_synthesis_filtering (
struct gsm_state * S,
register word * rrp, /* [0..7] IN */
register int k, /* k_end - k_start */
register word * wt, /* [0..k-1] IN */
register word * sr /* [0..k-1] OUT */
)
{
register word * v = S->v;
register int i;
register word sri, tmp1, tmp2;
while (k--) {
sri = *wt++;
for (i = 8; i--;) {
/* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
*/
tmp1 = rrp[i];
tmp2 = v[i];
tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
? MAX_WORD
: 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+ 16384) >> 15)) ;
sri = GSM_SUB( sri, tmp2 );
/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
*/
tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD
? MAX_WORD
: 0x0FFFF & (( (longword)tmp1 * (longword)sri
+ 16384) >> 15)) ;
v[i+1] = GSM_ADD( v[i], tmp1);
}
*sr++ = v[0] = sri;
}
}
#if defined(FAST) && defined(USE_FLOAT_MUL)
static void Fast_Short_term_synthesis_filtering (
struct gsm_state * S,
register word * rrp, /* [0..7] IN */
register int k, /* k_end - k_start */
register word * wt, /* [0..k-1] IN */
register word * sr /* [0..k-1] OUT */
)
{
register word * v = S->v;
register int i;
float va[9], rrpa[8];
register float scalef = 3.0517578125e-5, temp;
for (i = 0; i < 8; ++i) {
va[i] = v[i];
rrpa[i] = (float)rrp[i] * scalef;
}
while (k--) {
register float sri = *wt++;
for (i = 8; i--;) {
sri -= rrpa[i] * va[i];
if (sri < -32768.) sri = -32768.;
else if (sri > 32767.) sri = 32767.;
temp = va[i] + rrpa[i] * sri;
if (temp < -32768.) temp = -32768.;
else if (temp > 32767.) temp = 32767.;
va[i+1] = temp;
}
*sr++ = va[0] = sri;
}
for (i = 0; i < 9; ++i) v[i] = va[i];
}
#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
void Gsm_Short_Term_Analysis_Filter (
struct gsm_state * S,
word * LARc, /* coded log area ratio [0..7] IN */
word * s /* signal [0..159] IN/OUT */
)
{
word * LARpp_j = S->LARpp[ S->j ];
word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
word LARp[8];
#undef FILTER
#if defined(FAST) && defined(USE_FLOAT_MUL)
# define FILTER (* (S->fast \
? Fast_Short_term_analysis_filtering \
: Short_term_analysis_filtering ))
#else
# define FILTER Short_term_analysis_filtering
#endif
Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
LARp_to_rp( LARp );
FILTER( S, LARp, 13, s);
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S, LARp, 14, s + 13);
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S, LARp, 13, s + 27);
Coefficients_40_159( LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S, LARp, 120, s + 40);
}
void Gsm_Short_Term_Synthesis_Filter (
struct gsm_state * S,
word * LARcr, /* received log area ratios [0..7] IN */
word * wt, /* received d [0..159] IN */
word * s /* signal s [0..159] OUT */
)
{
word * LARpp_j = S->LARpp[ S->j ];
word * LARpp_j_1 = S->LARpp[ S->j ^=1 ];
word LARp[8];
#undef FILTER
#if defined(FAST) && defined(USE_FLOAT_MUL)
# define FILTER (* (S->fast \
? Fast_Short_term_synthesis_filtering \
: Short_term_synthesis_filtering ))
#else
# define FILTER Short_term_synthesis_filtering
#endif
Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
LARp_to_rp( LARp );
FILTER( S, LARp, 13, wt, s );
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S, LARp, 14, wt + 13, s + 13 );
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S, LARp, 13, wt + 27, s + 27 );
Coefficients_40_159( LARpp_j, LARp );
LARp_to_rp( LARp );
FILTER(S, LARp, 120, wt + 40, s + 40);
}
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 019ac7ba-c6dd-4540-abf0-8644b6c4a633
*/

View File

@@ -1,69 +0,0 @@
/*
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
/* Most of these tables are inlined at their point of use.
*/
/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
* CODER AND DECODER
*
* (Most of them inlined, so watch out.)
*/
#define GSM_TABLE_C
#include "gsm610_priv.h"
#include "gsm.h"
/* Table 4.1 Quantization of the Log.-Area Ratios
*/
/* i 1 2 3 4 5 6 7 8 */
word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036};
word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144};
word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 };
word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 };
/* Table 4.2 Tabulation of 1/A[1..8]
*/
word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 };
/* Table 4.3a Decision level of the LTP gain quantizer
*/
/* bc 0 1 2 3 */
word gsm_DLB[4] = { 6554, 16384, 26214, 32767 };
/* Table 4.3b Quantization levels of the LTP gain quantizer
*/
/* bc 0 1 2 3 */
word gsm_QLB[4] = { 3277, 11469, 21299, 32767 };
/* Table 4.4 Coefficients of the weighting filter
*/
/* i 0 1 2 3 4 5 6 7 8 9 10 */
word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax
*/
/* i 0 1 2 3 4 5 6 7 */
word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
/* Table 4.6 Normalized direct mantissa used to compute xM/xmax
*/
/* i 0 1 2 3 4 5 6 7 */
word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 8957c531-e6b0-4097-9202-da7ca42729ca
*/

View File

@@ -1,36 +0,0 @@
# Auto-generated by create_symbols_file.py
_sf_command
_sf_open
_sf_close
_sf_seek
_sf_error
_sf_perror
_sf_error_str
_sf_error_number
_sf_format_check
_sf_read_raw
_sf_readf_short
_sf_readf_int
_sf_readf_float
_sf_readf_double
_sf_read_short
_sf_read_int
_sf_read_float
_sf_read_double
_sf_write_raw
_sf_writef_short
_sf_writef_int
_sf_writef_float
_sf_writef_double
_sf_write_short
_sf_write_int
_sf_write_float
_sf_write_double
_sf_strerror
_sf_get_string
_sf_set_string
_sf_open_fd
_sf_open_virtual
_sf_write_sync

View File

@@ -1,42 +0,0 @@
# Auto-generated by create_symbols_file.py
libsndfile.so.1.0
{
global:
sf_command ;
sf_open ;
sf_close ;
sf_seek ;
sf_error ;
sf_perror ;
sf_error_str ;
sf_error_number ;
sf_format_check ;
sf_read_raw ;
sf_readf_short ;
sf_readf_int ;
sf_readf_float ;
sf_readf_double ;
sf_read_short ;
sf_read_int ;
sf_read_float ;
sf_read_double ;
sf_write_raw ;
sf_writef_short ;
sf_writef_int ;
sf_writef_float ;
sf_writef_double ;
sf_write_short ;
sf_write_int ;
sf_write_float ;
sf_write_double ;
sf_strerror ;
sf_get_string ;
sf_set_string ;
sf_open_fd ;
sf_open_virtual ;
sf_write_sync ;
local:
* ;
} ;

File diff suppressed because it is too large Load Diff

View File

@@ -1,544 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sndfile.h"
#include "float_cast.h"
#include "common.h"
static sf_count_t alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t alaw_write_s2alaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t alaw_write_i2alaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t alaw_write_f2alaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t alaw_write_d2alaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static void alaw2s_array (unsigned char *buffer, int count, short *ptr) ;
static void alaw2i_array (unsigned char *buffer, int count, int *ptr) ;
static void alaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact) ;
static void alaw2d_array (unsigned char *buffer, int count, double *ptr, double normfact) ;
static void s2alaw_array (const short *buffer, int count, unsigned char *ptr) ;
static void i2alaw_array (const int *buffer, int count, unsigned char *ptr) ;
static void f2alaw_array (const float *buffer, int count, unsigned char *ptr, float normfact) ;
static void d2alaw_array (const double *buffer, int count, unsigned char *ptr, double normfact) ;
int
alaw_init (SF_PRIVATE *psf)
{
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
{ psf->read_short = alaw_read_alaw2s ;
psf->read_int = alaw_read_alaw2i ;
psf->read_float = alaw_read_alaw2f ;
psf->read_double = alaw_read_alaw2d ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ psf->write_short = alaw_write_s2alaw ;
psf->write_int = alaw_write_i2alaw ;
psf->write_float = alaw_write_f2alaw ;
psf->write_double = alaw_write_d2alaw ;
} ;
psf->bytewidth = 1 ;
psf->blockwidth = psf->sf.channels ;
if (psf->filelength > psf->dataoffset)
psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ;
else
psf->datalength = 0 ;
psf->sf.frames = psf->datalength / psf->blockwidth ;
return 0 ;
} /* alaw_init */
/*==============================================================================
* Private static functions and data.
*/
static
short alaw_decode [256] =
{ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
-7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
-2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
-3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
-22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
-11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
-15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
-344, -328, -376, -360, -280, -264, -312, -296,
-472, -456, -504, -488, -408, -392, -440, -424,
-88, -72, -120, -104, -24, -8, -56, -40,
-216, -200, -248, -232, -152, -136, -184, -168,
-1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
-1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
-688, -656, -752, -720, -560, -528, -624, -592,
-944, -912, -1008, -976, -816, -784, -880, -848,
5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
344, 328, 376, 360, 280, 264, 312, 296,
472, 456, 504, 488, 408, 392, 440, 424,
88, 72, 120, 104, 24, 8, 56, 40,
216, 200, 248, 232, 152, 136, 184, 168,
1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
688, 656, 752, 720, 560, 528, 624, 592,
944, 912, 1008, 976, 816, 784, 880, 848
} ; /* alaw_decode */
static
unsigned char alaw_encode [2048 + 1] =
{ 0xd5, 0xd4, 0xd7, 0xd6, 0xd1, 0xd0, 0xd3, 0xd2, 0xdd, 0xdc, 0xdf, 0xde,
0xd9, 0xd8, 0xdb, 0xda, 0xc5, 0xc4, 0xc7, 0xc6, 0xc1, 0xc0, 0xc3, 0xc2,
0xcd, 0xcc, 0xcf, 0xce, 0xc9, 0xc8, 0xcb, 0xca, 0xf5, 0xf5, 0xf4, 0xf4,
0xf7, 0xf7, 0xf6, 0xf6, 0xf1, 0xf1, 0xf0, 0xf0, 0xf3, 0xf3, 0xf2, 0xf2,
0xfd, 0xfd, 0xfc, 0xfc, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xf9, 0xf8, 0xf8,
0xfb, 0xfb, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4,
0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1,
0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2,
0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef,
0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95,
0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96,
0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93,
0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a,
0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f,
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5,
0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6,
0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3,
0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc,
0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9,
0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a
} ; /* alaw_encode */
static inline void
alaw2s_array (unsigned char *buffer, int count, short *ptr)
{ while (--count >= 0)
ptr [count] = alaw_decode [(int) buffer [count]] ;
} /* alaw2s_array */
static inline void
alaw2i_array (unsigned char *buffer, int count, int *ptr)
{ while (--count >= 0)
ptr [count] = alaw_decode [(int) buffer [count]] << 16 ;
} /* alaw2i_array */
static inline void
alaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact)
{ while (--count >= 0)
ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
} /* alaw2f_array */
static inline void
alaw2d_array (unsigned char *buffer, int count, double *ptr, double normfact)
{ while (--count >= 0)
ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
} /* alaw2d_array */
static inline void
s2alaw_array (const short *ptr, int count, unsigned char *buffer)
{ while (--count >= 0)
{ if (ptr [count] >= 0)
buffer [count] = alaw_encode [ptr [count] / 16] ;
else
buffer [count] = 0x7F & alaw_encode [ptr [count] / -16] ;
} ;
} /* s2alaw_array */
static inline void
i2alaw_array (const int *ptr, int count, unsigned char *buffer)
{ while (--count >= 0)
{ if (ptr [count] >= 0)
buffer [count] = alaw_encode [ptr [count] >> (16 + 4)] ;
else
buffer [count] = 0x7F & alaw_encode [- ptr [count] >> (16 + 4)] ;
} ;
} /* i2alaw_array */
static inline void
f2alaw_array (const float *ptr, int count, unsigned char *buffer, float normfact)
{ while (--count >= 0)
{ if (ptr [count] >= 0)
buffer [count] = alaw_encode [lrintf (normfact * ptr [count])] ;
else
buffer [count] = 0x7F & alaw_encode [- lrintf (normfact * ptr [count])] ;
} ;
} /* f2alaw_array */
static inline void
d2alaw_array (const double *ptr, int count, unsigned char *buffer, double normfact)
{ while (--count >= 0)
{ if (ptr [count] >= 0)
buffer [count] = alaw_encode [lrint (normfact * ptr [count])] ;
else
buffer [count] = 0x7F & alaw_encode [- lrint (normfact * ptr [count])] ;
} ;
} /* d2alaw_array */
/*==============================================================================
*/
static sf_count_t
alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2s_array (psf->u.ucbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* alaw_read_alaw2s */
static sf_count_t
alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2i_array (psf->u.ucbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* alaw_read_alaw2i */
static sf_count_t
alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
float normfact ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* alaw_read_alaw2f */
static sf_count_t
alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
double normfact ;
normfact = (psf->norm_double) ? 1.0 / ((double) 0x8000) : 1.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* alaw_read_alaw2d */
/*=============================================================================================
*/
static sf_count_t
alaw_write_s2alaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* alaw_write_s2alaw */
static sf_count_t
alaw_write_i2alaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* alaw_write_i2alaw */
static sf_count_t
alaw_write_f2alaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
float normfact ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
f2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* alaw_write_f2alaw */
static sf_count_t
alaw_write_d2alaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
double normfact ;
normfact = (psf->norm_double) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* alaw_write_d2alaw */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 289ccfc2-42a6-4f1f-a29f-4dcc9bfa8752
*/

View File

@@ -1,453 +0,0 @@
/*
** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
#define DOTSND_MARKER (MAKE_MARKER ('.', 's', 'n', 'd'))
#define DNSDOT_MARKER (MAKE_MARKER ('d', 'n', 's', '.'))
#define AU_DATA_OFFSET 24
/*------------------------------------------------------------------------------
** Known AU file encoding types.
*/
enum
{ AU_ENCODING_ULAW_8 = 1, /* 8-bit u-law samples */
AU_ENCODING_PCM_8 = 2, /* 8-bit linear samples */
AU_ENCODING_PCM_16 = 3, /* 16-bit linear samples */
AU_ENCODING_PCM_24 = 4, /* 24-bit linear samples */
AU_ENCODING_PCM_32 = 5, /* 32-bit linear samples */
AU_ENCODING_FLOAT = 6, /* floating-point samples */
AU_ENCODING_DOUBLE = 7, /* double-precision float samples */
AU_ENCODING_INDIRECT = 8, /* fragmented sampled data */
AU_ENCODING_NESTED = 9, /* ? */
AU_ENCODING_DSP_CORE = 10, /* DSP program */
AU_ENCODING_DSP_DATA_8 = 11, /* 8-bit fixed-point samples */
AU_ENCODING_DSP_DATA_16 = 12, /* 16-bit fixed-point samples */
AU_ENCODING_DSP_DATA_24 = 13, /* 24-bit fixed-point samples */
AU_ENCODING_DSP_DATA_32 = 14, /* 32-bit fixed-point samples */
AU_ENCODING_DISPLAY = 16, /* non-audio display data */
AU_ENCODING_MULAW_SQUELCH = 17, /* ? */
AU_ENCODING_EMPHASIZED = 18, /* 16-bit linear with emphasis */
AU_ENCODING_NEXT = 19, /* 16-bit linear with compression (NEXT) */
AU_ENCODING_COMPRESSED_EMPHASIZED = 20, /* A combination of the two above */
AU_ENCODING_DSP_COMMANDS = 21, /* Music Kit DSP commands */
AU_ENCODING_DSP_COMMANDS_SAMPLES = 22, /* ? */
AU_ENCODING_ADPCM_G721_32 = 23, /* G721 32 kbs ADPCM - 4 bits per sample. */
AU_ENCODING_ADPCM_G722 = 24, /* G722 64 kbs ADPCM */
AU_ENCODING_ADPCM_G723_24 = 25, /* G723 24 kbs ADPCM - 3 bits per sample. */
AU_ENCODING_ADPCM_G723_40 = 26, /* G723 40 kbs ADPCM - 5 bits per sample. */
AU_ENCODING_ALAW_8 = 27
} ;
/*------------------------------------------------------------------------------
** Typedefs.
*/
typedef struct
{ int dataoffset ;
int datasize ;
int encoding ;
int samplerate ;
int channels ;
} AU_FMT ;
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int au_close (SF_PRIVATE *psf) ;
static int au_format_to_encoding (int format) ;
static int au_write_header (SF_PRIVATE *psf, int calc_length) ;
static int au_read_header (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
au_open (SF_PRIVATE *psf)
{ int subformat ;
int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = au_read_header (psf)))
return error ;
} ;
if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AU)
return SFE_BAD_OPEN_FORMAT ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
psf->endian = SF_ENDIAN_LITTLE ;
else if (psf->endian != SF_ENDIAN_LITTLE)
psf->endian = SF_ENDIAN_BIG ;
if (au_write_header (psf, SF_FALSE))
return psf->error ;
psf->write_header = au_write_header ;
} ;
psf->container_close = au_close ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
switch (subformat)
{ case SF_FORMAT_ULAW : /* 8-bit Ulaw encoding. */
ulaw_init (psf) ;
break ;
case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
error = pcm_init (psf) ;
break ;
case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
error = pcm_init (psf) ;
break ;
case SF_FORMAT_ALAW : /* 8-bit Alaw encoding. */
alaw_init (psf) ;
break ;
/* Lite remove start */
case SF_FORMAT_FLOAT : /* 32-bit floats. */
error = float32_init (psf) ;
break ;
case SF_FORMAT_DOUBLE : /* 64-bit double precision floats. */
error = double64_init (psf) ;
break ;
case SF_FORMAT_G721_32 :
error = g72x_init (psf) ;
psf->sf.seekable = SF_FALSE ;
break ;
case SF_FORMAT_G723_24 :
error = g72x_init (psf) ;
psf->sf.seekable = SF_FALSE ;
break ;
case SF_FORMAT_G723_40 :
error = g72x_init (psf) ;
psf->sf.seekable = SF_FALSE ;
break ;
/* Lite remove end */
default : break ;
} ;
return error ;
} /* au_open */
/*------------------------------------------------------------------------------
*/
static int
au_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
au_write_header (psf, SF_TRUE) ;
return 0 ;
} /* au_close */
static int
au_write_header (SF_PRIVATE *psf, int calc_length)
{ sf_count_t current ;
int encoding, datalength ;
if (psf->pipeoffset > 0)
return 0 ;
current = psf_ftell (psf) ;
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
psf->datalength -= psf->filelength - psf->dataend ;
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
encoding = au_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ;
if (! encoding)
return (psf->error = SFE_BAD_OPEN_FORMAT) ;
/* Reset the current header length to zero. */
psf->header [0] = 0 ;
psf->headindex = 0 ;
/*
** Only attempt to seek if we are not writng to a pipe. If we are
** writing to a pipe we shouldn't be here anyway.
*/
if (psf->is_pipe == SF_FALSE)
psf_fseek (psf, 0, SEEK_SET) ;
/*
** AU format files allow a datalength value of -1 if the datalength
** is not know at the time the header is written.
** Also use this value of -1 if the datalength > 2 gigabytes.
*/
if (psf->datalength < 0 || psf->datalength > 0x7FFFFFFF)
datalength = -1 ;
else
datalength = (int) (psf->datalength & 0x7FFFFFFF) ;
if (psf->endian == SF_ENDIAN_BIG)
{ psf_binheader_writef (psf, "Em4", DOTSND_MARKER, AU_DATA_OFFSET) ;
psf_binheader_writef (psf, "E4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
}
else if (psf->endian == SF_ENDIAN_LITTLE)
{ psf_binheader_writef (psf, "em4", DNSDOT_MARKER, AU_DATA_OFFSET) ;
psf_binheader_writef (psf, "e4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
}
else
return (psf->error = SFE_BAD_OPEN_FORMAT) ;
/* Header construction complete so write it out. */
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
psf->dataoffset = psf->headindex ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return psf->error ;
} /* au_write_header */
static int
au_format_to_encoding (int format)
{
switch (format)
{ case SF_FORMAT_PCM_S8 : return AU_ENCODING_PCM_8 ;
case SF_FORMAT_PCM_16 : return AU_ENCODING_PCM_16 ;
case SF_FORMAT_PCM_24 : return AU_ENCODING_PCM_24 ;
case SF_FORMAT_PCM_32 : return AU_ENCODING_PCM_32 ;
case SF_FORMAT_FLOAT : return AU_ENCODING_FLOAT ;
case SF_FORMAT_DOUBLE : return AU_ENCODING_DOUBLE ;
case SF_FORMAT_ULAW : return AU_ENCODING_ULAW_8 ;
case SF_FORMAT_ALAW : return AU_ENCODING_ALAW_8 ;
case SF_FORMAT_G721_32 : return AU_ENCODING_ADPCM_G721_32 ;
case SF_FORMAT_G723_24 : return AU_ENCODING_ADPCM_G723_24 ;
case SF_FORMAT_G723_40 : return AU_ENCODING_ADPCM_G723_40 ;
default : break ;
} ;
return 0 ;
} /* au_format_to_encoding */
static int
au_read_header (SF_PRIVATE *psf)
{ AU_FMT au_fmt ;
int marker, dword ;
memset (&au_fmt, 0, sizeof (au_fmt)) ;
psf_binheader_readf (psf, "pm", 0, &marker) ;
psf_log_printf (psf, "%M\n", marker) ;
if (marker == DOTSND_MARKER)
{ psf->endian = SF_ENDIAN_BIG ;
psf_binheader_readf (psf, "E44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
&(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
}
else if (marker == DNSDOT_MARKER)
{ psf->endian = SF_ENDIAN_LITTLE ;
psf_binheader_readf (psf, "e44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
&(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
}
else
return SFE_AU_NO_DOTSND ;
psf_log_printf (psf, " Data Offset : %d\n", au_fmt.dataoffset) ;
if (psf->fileoffset > 0 && au_fmt.datasize == -1)
{ psf_log_printf (psf, " Data Size : -1\n") ;
return SFE_AU_EMBED_BAD_LEN ;
} ;
if (psf->fileoffset > 0)
{ psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
}
else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength)
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength)
{ psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
psf_log_printf (psf, " Data Size : %d\n", au_fmt.datasize) ;
}
else
{ dword = psf->filelength - au_fmt.dataoffset ;
psf_log_printf (psf, " Data Size : %d (should be %d)\n", au_fmt.datasize, dword) ;
au_fmt.datasize = dword ;
} ;
psf->dataoffset = au_fmt.dataoffset ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf_ftell (psf) < psf->dataoffset)
psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;
psf->sf.samplerate = au_fmt.samplerate ;
psf->sf.channels = au_fmt.channels ;
/* Only fill in type major. */
if (psf->endian == SF_ENDIAN_BIG)
psf->sf.format = SF_FORMAT_AU ;
else if (psf->endian == SF_ENDIAN_LITTLE)
psf->sf.format = SF_ENDIAN_LITTLE | SF_FORMAT_AU ;
psf_log_printf (psf, " Encoding : %d => ", au_fmt.encoding) ;
psf->sf.format = psf->sf.format & SF_FORMAT_ENDMASK ;
switch (au_fmt.encoding)
{ case AU_ENCODING_ULAW_8 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ULAW ;
psf->bytewidth = 1 ; /* Before decoding */
psf_log_printf (psf, "8-bit ISDN u-law\n") ;
break ;
case AU_ENCODING_PCM_8 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_S8 ;
psf->bytewidth = 1 ;
psf_log_printf (psf, "8-bit linear PCM\n") ;
break ;
case AU_ENCODING_PCM_16 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
psf_log_printf (psf, "16-bit linear PCM\n") ;
break ;
case AU_ENCODING_PCM_24 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_24 ;
psf->bytewidth = 3 ;
psf_log_printf (psf, "24-bit linear PCM\n") ;
break ;
case AU_ENCODING_PCM_32 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_32 ;
psf->bytewidth = 4 ;
psf_log_printf (psf, "32-bit linear PCM\n") ;
break ;
case AU_ENCODING_FLOAT :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_FLOAT ;
psf->bytewidth = 4 ;
psf_log_printf (psf, "32-bit float\n") ;
break ;
case AU_ENCODING_DOUBLE :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_DOUBLE ;
psf->bytewidth = 8 ;
psf_log_printf (psf, "64-bit double precision float\n") ;
break ;
case AU_ENCODING_ALAW_8 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ALAW ;
psf->bytewidth = 1 ; /* Before decoding */
psf_log_printf (psf, "8-bit ISDN A-law\n") ;
break ;
case AU_ENCODING_ADPCM_G721_32 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G721_32 ;
psf->bytewidth = 0 ;
psf_log_printf (psf, "G721 32kbs ADPCM\n") ;
break ;
case AU_ENCODING_ADPCM_G723_24 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_24 ;
psf->bytewidth = 0 ;
psf_log_printf (psf, "G723 24kbs ADPCM\n") ;
break ;
case AU_ENCODING_ADPCM_G723_40 :
psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_40 ;
psf->bytewidth = 0 ;
psf_log_printf (psf, "G723 40kbs ADPCM\n") ;
break ;
case AU_ENCODING_ADPCM_G722 :
psf_log_printf (psf, "G722 64 kbs ADPCM (unsupported)\n") ;
break ;
case AU_ENCODING_NEXT :
psf_log_printf (psf, "Weird NeXT encoding format (unsupported)\n") ;
break ;
default :
psf_log_printf (psf, "Unknown!!\n") ;
break ;
} ;
psf_log_printf (psf, " Sample Rate : %d\n", au_fmt.samplerate) ;
psf_log_printf (psf, " Channels : %d\n", au_fmt.channels) ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
if (! psf->sf.frames && psf->blockwidth)
psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
return 0 ;
} /* au_read_header */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 31f691b1-cde9-4ed2-9469-6bca60fb9cd0
*/

View File

@@ -1,254 +0,0 @@
/*
** Copyright (C) 2004-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#define TWOBIT_MARKER (MAKE_MARKER ('2', 'B', 'I', 'T'))
#define AVR_HDR_SIZE 128
#define SFE_AVR_X 666
/*
** From: hyc@hanauma.Jpl.Nasa.Gov (Howard Chu)
**
** A lot of PD software exists to play Mac .snd files on the ST. One other
** format that seems pretty popular (used by a number of commercial packages)
** is the AVR format (from Audio Visual Research). This format has a 128 byte
** header that looks like this (its actually packed, but thats not portable):
*/
typedef struct
{ int marker ; /* 2BIT */
char name [8] ; /* null-padded sample name */
short mono ; /* 0 = mono, 0xffff = stereo */
short rez ; /* 8 = 8 bit, 16 = 16 bit */
short sign ; /* 0 = unsigned, 0xffff = signed */
short loop ; /* 0 = no loop, 0xffff = looping sample */
short midi ; /* 0xffff = no MIDI note assigned, */
/* 0xffXX = single key note assignment */
/* 0xLLHH = key split, low/hi note */
int srate ; /* sample frequency in hertz */
int frames ; /* sample length in bytes or words (see rez) */
int lbeg ; /* offset to start of loop in bytes or words. */
/* set to zero if unused */
int lend ; /* offset to end of loop in bytes or words. */
/* set to sample length if unused */
short res1 ; /* Reserved, MIDI keyboard split */
short res2 ; /* Reserved, sample compression */
short res3 ; /* Reserved */
char ext [20] ; /* Additional filename space, used if (name[7] != 0) */
char user [64] ; /* User defined. Typically ASCII message */
} AVR_HEADER ;
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int avr_close (SF_PRIVATE *psf) ;
static int avr_read_header (SF_PRIVATE *psf) ;
static int avr_write_header (SF_PRIVATE *psf, int calc_length) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
avr_open (SF_PRIVATE *psf)
{ int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = avr_read_header (psf)))
return error ;
} ;
if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AVR)
return SFE_BAD_OPEN_FORMAT ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
psf->endian = SF_ENDIAN_BIG ;
if (avr_write_header (psf, SF_FALSE))
return psf->error ;
psf->write_header = avr_write_header ;
} ;
psf->container_close = avr_close ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
error = pcm_init (psf) ;
return error ;
} /* avr_open */
static int
avr_read_header (SF_PRIVATE *psf)
{ AVR_HEADER hdr ;
memset (&hdr, 0, sizeof (hdr)) ;
psf_binheader_readf (psf, "pmb", 0, &hdr.marker, &hdr.name, sizeof (hdr.name)) ;
psf_log_printf (psf, "%M\n", hdr.marker) ;
if (hdr.marker != TWOBIT_MARKER)
return SFE_AVR_X ;
psf_log_printf (psf, " Name : %s\n", hdr.name) ;
psf_binheader_readf (psf, "E22222", &hdr.mono, &hdr.rez, &hdr.sign, &hdr.loop, &hdr.midi) ;
psf->sf.channels = (hdr.mono & 1) + 1 ;
psf_log_printf (psf, " Channels : %d\n Bit width : %d\n Signed : %s\n",
(hdr.mono & 1) + 1, hdr.rez, hdr.sign ? "yes" : "no") ;
switch ((hdr.rez << 16) + (hdr.sign & 1))
{ case ((8 << 16) + 0) :
psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_U8 ;
psf->bytewidth = 1 ;
break ;
case ((8 << 16) + 1) :
psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_S8 ;
psf->bytewidth = 1 ;
break ;
case ((16 << 16) + 1) :
psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
break ;
default :
psf_log_printf (psf, "Error : bad rez/sign combination.\n") ;
return SFE_AVR_X ;
} ;
psf_binheader_readf (psf, "E4444", &hdr.srate, &hdr.frames, &hdr.lbeg, &hdr.lend) ;
psf->sf.frames = hdr.frames ;
psf->sf.samplerate = hdr.srate ;
psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ;
psf_binheader_readf (psf, "E222", &hdr.res1, &hdr.res2, &hdr.res3) ;
psf_binheader_readf (psf, "bb", hdr.ext, sizeof (hdr.ext), hdr.user, sizeof (hdr.user)) ;
psf_log_printf (psf, " Ext : %s\n User : %s\n", hdr.ext, hdr.user) ;
psf->endian = SF_ENDIAN_BIG ;
psf->dataoffset = AVR_HDR_SIZE ;
psf->datalength = hdr.frames * (hdr.rez / 8) ;
if (psf->fileoffset > 0)
psf->filelength = AVR_HDR_SIZE + psf->datalength ;
if (psf_ftell (psf) != psf->dataoffset)
psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
if (psf->sf.frames == 0 && psf->blockwidth)
psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
return 0 ;
} /* avr_read_header */
static int
avr_write_header (SF_PRIVATE *psf, int calc_length)
{ sf_count_t current ;
int sign ;
if (psf->pipeoffset > 0)
return 0 ;
current = psf_ftell (psf) ;
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
psf->datalength -= psf->filelength - psf->dataend ;
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
/* Reset the current header length to zero. */
psf->header [0] = 0 ;
psf->headindex = 0 ;
/*
** Only attempt to seek if we are not writng to a pipe. If we are
** writing to a pipe we shouldn't be here anyway.
*/
if (psf->is_pipe == SF_FALSE)
psf_fseek (psf, 0, SEEK_SET) ;
psf_binheader_writef (psf, "Emz22", TWOBIT_MARKER, make_size_t (8),
psf->sf.channels == 2 ? 0xFFFF : 0, psf->bytewidth * 8) ;
sign = ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8) ? 0 : 0xFFFF ;
psf_binheader_writef (psf, "E222", sign, 0, 0xFFFF) ;
psf_binheader_writef (psf, "E4444", psf->sf.samplerate, psf->sf.frames, 0, 0) ;
psf_binheader_writef (psf, "E222zz", 0, 0, 0, make_size_t (20), make_size_t (64)) ;
/* Header construction complete so write it out. */
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
psf->dataoffset = psf->headindex ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return psf->error ;
} /* avr_write_header */
static int
avr_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
avr_write_header (psf, SF_TRUE) ;
return 0 ;
} /* avr_close */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 0823d454-f39a-4a28-a776-607f1ef33b52
*/

View File

@@ -1,89 +0,0 @@
/*
** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
** Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include <stdio.h>
#include <string.h>
#include "common.h"
/*
** Allocate and initialize a broadcast info structure.
*/
SF_BROADCAST_INFO*
broadcast_info_alloc (void)
{ SF_BROADCAST_INFO* bext ;
if ((bext = calloc (1, sizeof (SF_BROADCAST_INFO))) == NULL)
return NULL ;
return bext ;
} /* broadcast_info_alloc */
int
broadcast_info_copy (SF_BROADCAST_INFO* dst, SF_BROADCAST_INFO* src)
{ memcpy (dst, src, sizeof (SF_BROADCAST_INFO)) ;
/* Currently writing this version. */
dst->version = 1 ;
return SF_TRUE ;
} /* broadcast_info_copy */
int
broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate)
{ char chnstr [16] ;
int count ;
switch (channels)
{ case 0 :
return SF_FALSE ;
case 1 :
strncpy (chnstr, "mono", sizeof (chnstr)) ;
break ;
case 2 :
strncpy (chnstr, "stereo", sizeof (chnstr)) ;
break ;
default :
LSF_SNPRINTF (chnstr, sizeof (chnstr), "%uchn", channels) ;
break ;
}
count = LSF_SNPRINTF (bext->coding_history, sizeof (bext->coding_history), "F=%u,A=PCM,M=%s,W=24,T=%s-%s", samplerate, chnstr, PACKAGE, VERSION) ;
if (count >= SIGNED_SIZEOF (bext->coding_history))
bext->coding_history_size = sizeof (bext->coding_history) ;
else
{ count += count & 1 ;
bext->coding_history_size = count ;
} ;
return SF_TRUE ;
} /* broadcast_add_coding_history */
/*
** Do not edit or modify anything in this comment block.
** The following line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 4b3b69c7-d710-4424-9da0-5048534a0beb
*/

View File

@@ -1,538 +0,0 @@
/*
** Copyright (C) 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "float_cast.h"
#include "common.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
#define aac_MARKER MAKE_MARKER ('a', 'a', 'c', ' ')
#define alac_MARKER MAKE_MARKER ('a', 'l', 'a', 'c')
#define alaw_MARKER MAKE_MARKER ('a', 'l', 'a', 'w')
#define caff_MARKER MAKE_MARKER ('c', 'a', 'f', 'f')
#define chan_MARKER MAKE_MARKER ('c', 'h', 'a', 'n')
#define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a')
#define desc_MARKER MAKE_MARKER ('d', 'e', 's', 'c')
#define edct_MARKER MAKE_MARKER ('e', 'd', 'c', 't')
#define free_MARKER MAKE_MARKER ('f', 'r', 'e', 'e')
#define ima4_MARKER MAKE_MARKER ('i', 'm', 'a', '4')
#define info_MARKER MAKE_MARKER ('i', 'n', 'f', 'o')
#define inst_MARKER MAKE_MARKER ('i', 'n', 's', 't')
#define kuki_MARKER MAKE_MARKER ('k', 'u', 'k', 'i')
#define lpcm_MARKER MAKE_MARKER ('l', 'p', 'c', 'm')
#define mark_MARKER MAKE_MARKER ('m', 'a', 'r', 'k')
#define midi_MARKER MAKE_MARKER ('m', 'i', 'd', 'i')
#define mp1_MARKER MAKE_MARKER ('.', 'm', 'p', '1')
#define mp2_MARKER MAKE_MARKER ('.', 'm', 'p', '2')
#define mp3_MARKER MAKE_MARKER ('.', 'm', 'p', '3')
#define ovvw_MARKER MAKE_MARKER ('o', 'v', 'v', 'w')
#define pakt_MARKER MAKE_MARKER ('p', 'a', 'k', 't')
#define peak_MARKER MAKE_MARKER ('p', 'e', 'a', 'k')
#define regn_MARKER MAKE_MARKER ('r', 'e', 'g', 'n')
#define strg_MARKER MAKE_MARKER ('s', 't', 'r', 'g')
#define umid_MARKER MAKE_MARKER ('u', 'm', 'i', 'd')
#define uuid_MARKER MAKE_MARKER ('u', 'u', 'i', 'd')
#define ulaw_MARKER MAKE_MARKER ('u', 'l', 'a', 'w')
#define MAC3_MARKER MAKE_MARKER ('M', 'A', 'C', '3')
#define MAC6_MARKER MAKE_MARKER ('M', 'A', 'C', '6')
#define CAF_PEAK_CHUNK_SIZE(ch) (sizeof (int) + ch * (sizeof (float) + 8))
#define SFE_CAF_NOT_CAF 666
#define SFE_CAF_NO_DESC 667
#define SFE_CAF_BAD_PEAK 668
/*------------------------------------------------------------------------------
** Typedefs.
*/
typedef struct
{ unsigned char srate [8] ;
unsigned int fmt_id ;
unsigned int fmt_flags ;
unsigned int pkt_bytes ;
unsigned int pkt_frames ;
unsigned int channels_per_frame ;
unsigned int bits_per_chan ;
} DESC_CHUNK ;
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int caf_close (SF_PRIVATE *psf) ;
static int caf_read_header (SF_PRIVATE *psf) ;
static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
caf_open (SF_PRIVATE *psf)
{ int subformat, format, error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = caf_read_header (psf)))
return error ;
} ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
format = psf->sf.format & SF_FORMAT_TYPEMASK ;
if (format != SF_FORMAT_CAF)
return SFE_BAD_OPEN_FORMAT ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
if (psf->mode != SFM_RDWR || psf->filelength < 44)
{ psf->filelength = 0 ;
psf->datalength = 0 ;
psf->dataoffset = 0 ;
psf->sf.frames = 0 ;
} ;
psf->str_flags = SF_STR_ALLOW_START ;
/*
** By default, add the peak chunk to floating point files. Default behaviour
** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
*/
if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
psf->peak_info->peak_loc = SF_PEAK_START ;
} ;
if ((error = caf_write_header (psf, SF_FALSE)) != 0)
return error ;
psf->write_header = caf_write_header ;
} ;
psf->container_close = caf_close ;
/*psf->command = caf_command ;*/
switch (subformat)
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_PCM_32 :
error = pcm_init (psf) ;
break ;
case SF_FORMAT_ULAW :
error = ulaw_init (psf) ;
break ;
case SF_FORMAT_ALAW :
error = alaw_init (psf) ;
break ;
/* Lite remove start */
case SF_FORMAT_FLOAT :
error = float32_init (psf) ;
break ;
case SF_FORMAT_DOUBLE :
error = double64_init (psf) ;
break ;
/* Lite remove end */
default :
return SFE_UNSUPPORTED_ENCODING ;
} ;
return error ;
} /* caf_open */
static int
caf_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
caf_write_header (psf, SF_TRUE) ;
return 0 ;
} /* caf_close */
/*------------------------------------------------------------------------------
*/
static int
decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
{ int format ;
psf->sf.channels = desc->channels_per_frame ;
format = SF_FORMAT_CAF | (psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0) ;
if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
{ /* Floating point data. */
if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
{ psf->bytewidth = 4 ;
return format | SF_FORMAT_FLOAT ;
} ;
if (desc->bits_per_chan == 64 && desc->pkt_bytes == 8 * desc->channels_per_frame)
{ psf->bytewidth = 8 ;
return format | SF_FORMAT_DOUBLE ;
} ;
} ;
if ((desc->fmt_flags & 1) != 0)
{ psf_log_printf (psf, "**** Ooops, 'desc' chunk suggests float data, but other info invalid.\n") ;
return 0 ;
} ;
if (desc->fmt_id == lpcm_MARKER)
{ /* Integer data. */
if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
{ psf->bytewidth = 4 ;
return format | SF_FORMAT_PCM_32 ;
} ;
if (desc->bits_per_chan == 24 && desc->pkt_bytes == 3 * desc->channels_per_frame)
{ psf->bytewidth = 3 ;
return format | SF_FORMAT_PCM_24 ;
} ;
if (desc->bits_per_chan == 16 && desc->pkt_bytes == 2 * desc->channels_per_frame)
{ psf->bytewidth = 2 ;
return format | SF_FORMAT_PCM_16 ;
} ;
if (desc->bits_per_chan == 8 && desc->pkt_bytes == 1 * desc->channels_per_frame)
{ psf->bytewidth = 1 ;
return format | SF_FORMAT_PCM_S8 ;
} ;
} ;
if (desc->fmt_id == alaw_MARKER && desc->bits_per_chan == 8)
{ psf->bytewidth = 1 ;
return format | SF_FORMAT_ALAW ;
} ;
if (desc->fmt_id == ulaw_MARKER && desc->bits_per_chan == 8)
{ psf->bytewidth = 1 ;
return format | SF_FORMAT_ULAW ;
} ;
return 0 ;
} /* decode_desc_chunk */
static int
caf_read_header (SF_PRIVATE *psf)
{ DESC_CHUNK desc ;
sf_count_t chunk_size ;
double srate ;
short version, flags ;
int marker, k, have_data = 0 ;
memset (&desc, 0, sizeof (desc)) ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
psf_log_printf (psf, "%M\n Version : %d\n Flags : %x\n", marker, version, flags) ;
if (marker != caff_MARKER)
return SFE_CAF_NOT_CAF ;
psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, psf->u.ucbuf, 8) ;
srate = double64_be_read (psf->u.ucbuf) ;
LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, psf->u.cbuf) ;
if (marker != desc_MARKER)
return SFE_CAF_NO_DESC ;
if (chunk_size < sizeof (DESC_CHUNK))
{ psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
return SFE_MALFORMED_FILE ;
} ;
psf->sf.samplerate = lrint (srate) ;
psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.pkt_frames,
&desc.channels_per_frame, &desc.bits_per_chan) ;
psf_log_printf (psf, " Format id : %M\n Format flags : %x\n Bytes / packet : %u\n"
" Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n",
desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
if (chunk_size > sizeof (DESC_CHUNK))
psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;
psf->sf.channels = desc.channels_per_frame ;
while (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
{ psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
switch (marker)
{ case peak_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
{ psf_binheader_readf (psf, "j", (int) chunk_size) ;
psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
return SFE_CAF_BAD_PEAK ;
} ;
if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
/* read in rest of PEAK chunk. */
psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ;
psf_log_printf (psf, " Ch Position Value\n") ;
for (k = 0 ; k < psf->sf.channels ; k++)
{ sf_count_t position ;
float value ;
psf_binheader_readf (psf, "Ef8", &value, &position) ;
psf->peak_info->peaks [k].value = value ;
psf->peak_info->peaks [k].position = position ;
LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12ld %g\n", k, (long) position, value) ;
psf_log_printf (psf, psf->u.cbuf) ;
} ;
psf->peak_info->peak_loc = SF_PEAK_START ;
break ;
case free_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", (int) chunk_size) ;
break ;
case data_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "E4", &k) ;
psf_log_printf (psf, " edit : %u\n", k) ;
have_data = 1 ;
break ;
default :
psf_log_printf (psf, " %M : %D (skipped)\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", (int) chunk_size) ;
break ;
} ;
} ;
if (have_data == 0)
{ psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
return SFE_MALFORMED_FILE ;
} ;
psf_log_printf (psf, "End\n") ;
psf->dataoffset = psf_ftell (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
return SFE_UNSUPPORTED_ENCODING ;
if (psf->bytewidth > 0)
psf->sf.frames = psf->datalength / psf->bytewidth ;
return 0 ;
} /* caf_read_header */
/*------------------------------------------------------------------------------
*/
static int
caf_write_header (SF_PRIVATE *psf, int calc_length)
{ DESC_CHUNK desc ;
sf_count_t current, free_len ;
int subformat ;
memset (&desc, 0, sizeof (desc)) ;
current = psf_ftell (psf) ;
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
psf->datalength -= psf->filelength - psf->dataend ;
if (psf->bytewidth > 0)
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
/* Reset the current header length to zero. */
psf->header [0] = 0 ;
psf->headindex = 0 ;
psf_fseek (psf, 0, SEEK_SET) ;
/* 'caff' marker, version and flags. */
psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ;
/* 'desc' marker and chunk size. */
psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;
double64_be_write (1.0 * psf->sf.samplerate, psf->u.ucbuf) ;
psf_binheader_writef (psf, "b", psf->u.ucbuf, 8) ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
psf->endian = SF_ENDIAN_BIG ;
else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
psf->endian = SF_ENDIAN_LITTLE ;
if (psf->endian == SF_ENDIAN_LITTLE)
desc.fmt_flags = 2 ;
else
psf->endian = SF_ENDIAN_BIG ;
/* initial section (same for all, it appears) */
switch (subformat)
{ case SF_FORMAT_PCM_S8 :
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
case SF_FORMAT_PCM_16 :
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 2 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 16 ;
break ;
case SF_FORMAT_PCM_24 :
psf->bytewidth = 3 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 24 ;
desc.fmt_id = lpcm_MARKER ;
break ;
case SF_FORMAT_PCM_32 :
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 4 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 32 ;
break ;
case SF_FORMAT_FLOAT :
desc.fmt_id = lpcm_MARKER ;
desc.fmt_flags |= 1 ;
psf->bytewidth = 4 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 32 ;
break ;
case SF_FORMAT_DOUBLE :
desc.fmt_id = lpcm_MARKER ;
desc.fmt_flags |= 1 ;
psf->bytewidth = 8 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 64 ;
break ;
case SF_FORMAT_ALAW :
desc.fmt_id = alaw_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
case SF_FORMAT_ULAW :
desc.fmt_id = ulaw_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
default :
return SFE_UNIMPLEMENTED ;
} ;
psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
#if 0
if (psf->str_flags & SF_STR_LOCATE_START)
caf_write_strings (psf, SF_STR_LOCATE_START) ;
#endif
if (psf->peak_info != NULL)
{ int k ;
psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ;
for (k = 0 ; k < psf->sf.channels ; k++)
psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
free_len = 0x1000 - psf->headindex - 16 - 12 ;
while (free_len < 0)
free_len += 0x1000 ;
psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength, 0) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
psf->dataoffset = psf->headindex ;
if (current < psf->dataoffset)
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
else if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return psf->error ;
} /* caf_write_header */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 65883e65-bd3c-4618-9241-d3c02fd630bd
*/

View File

@@ -1,367 +0,0 @@
/*
** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "sndfile.h"
#include "common.h"
static SF_FORMAT_INFO const simple_formats [] =
{
{ SF_FORMAT_AIFF | SF_FORMAT_PCM_16,
"AIFF (Apple/SGI 16 bit PCM)", "aiff"
},
{ SF_FORMAT_AIFF | SF_FORMAT_FLOAT,
"AIFF (Apple/SGI 32 bit float)", "aifc"
},
{ SF_FORMAT_AIFF | SF_FORMAT_PCM_S8,
"AIFF (Apple/SGI 8 bit PCM)", "aiff"
},
{ SF_FORMAT_AU | SF_FORMAT_PCM_16,
"AU (Sun/Next 16 bit PCM)", "au"
},
{ SF_FORMAT_AU | SF_FORMAT_ULAW,
"AU (Sun/Next 8-bit u-law)", "au"
},
{ SF_FORMAT_CAF | SF_FORMAT_PCM_16,
"CAF (Apple 16 bit PCM)", "caf"
},
#ifdef HAVE_FLAC_ALL_H
{ SF_FORMAT_FLAC | SF_FORMAT_PCM_16,
"FLAC 16 bit", "flac"
},
#endif
{ SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM,
"OKI Dialogic VOX ADPCM", "vox"
},
{ SF_FORMAT_WAV | SF_FORMAT_PCM_16,
"WAV (Microsoft 16 bit PCM)", "wav"
},
{ SF_FORMAT_WAV | SF_FORMAT_FLOAT,
"WAV (Microsoft 32 bit float)", "wav"
},
{ SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM,
"WAV (Microsoft 4 bit IMA ADPCM)", "wav"
},
{ SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM,
"WAV (Microsoft 4 bit MS ADPCM)", "wav"
},
{ SF_FORMAT_WAV | SF_FORMAT_PCM_U8,
"WAV (Microsoft 8 bit PCM)", "wav"
},
} ; /* simple_formats */
int
psf_get_format_simple_count (void)
{ return (sizeof (simple_formats) / sizeof (SF_FORMAT_INFO)) ;
} /* psf_get_format_simple_count */
int
psf_get_format_simple (SF_FORMAT_INFO *data)
{ int indx ;
if (data->format < 0 || data->format >= (SIGNED_SIZEOF (simple_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
return SFE_BAD_CONTROL_CMD ;
indx = data->format ;
memcpy (data, &(simple_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
return 0 ;
} /* psf_get_format_simple */
/*============================================================================
** Major format info.
*/
static SF_FORMAT_INFO const major_formats [] =
{
{ SF_FORMAT_AIFF, "AIFF (Apple/SGI)", "aiff" },
{ SF_FORMAT_AU, "AU (Sun/NeXT)", "au" },
{ SF_FORMAT_AVR, "AVR (Audio Visual Research)", "avr" },
{ SF_FORMAT_CAF, "CAF (Apple Core Audio File)", "caf" },
#ifdef HAVE_FLAC_ALL_H
{ SF_FORMAT_FLAC, "FLAC (FLAC Lossless Audio Codec)", "flac" },
#endif
{ SF_FORMAT_HTK, "HTK (HMM Tool Kit)", "htk" },
{ SF_FORMAT_SVX, "IFF (Amiga IFF/SVX8/SV16)", "iff" },
{ SF_FORMAT_MAT4, "MAT4 (GNU Octave 2.0 / Matlab 4.2)", "mat" },
{ SF_FORMAT_MAT5, "MAT5 (GNU Octave 2.1 / Matlab 5.0)", "mat" },
{ SF_FORMAT_PAF, "PAF (Ensoniq PARIS)", "paf" },
{ SF_FORMAT_PVF, "PVF (Portable Voice Format)", "pvf" },
{ SF_FORMAT_RAW, "RAW (header-less)", "raw" },
{ SF_FORMAT_SD2, "SD2 (Sound Designer II)", "sd2" },
{ SF_FORMAT_SDS, "SDS (Midi Sample Dump Standard)", "sds" },
{ SF_FORMAT_IRCAM, "SF (Berkeley/IRCAM/CARL)", "sf" },
{ SF_FORMAT_VOC, "VOC (Creative Labs)", "voc" },
{ SF_FORMAT_W64, "W64 (SoundFoundry WAVE 64)", "w64" },
{ SF_FORMAT_WAV, "WAV (Microsoft)", "wav" },
{ SF_FORMAT_NIST, "WAV (NIST Sphere)", "wav" },
{ SF_FORMAT_WAVEX, "WAVEX (Microsoft)", "wav" },
{ SF_FORMAT_XI, "XI (FastTracker 2)", "xi" },
} ; /* major_formats */
int
psf_get_format_major_count (void)
{ return (sizeof (major_formats) / sizeof (SF_FORMAT_INFO)) ;
} /* psf_get_format_major_count */
int
psf_get_format_major (SF_FORMAT_INFO *data)
{ int indx ;
if (data->format < 0 || data->format >= (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
return SFE_BAD_CONTROL_CMD ;
indx = data->format ;
memcpy (data, &(major_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
return 0 ;
} /* psf_get_format_major */
/*============================================================================
** Subtype format info.
*/
static SF_FORMAT_INFO subtype_formats [] =
{
{ SF_FORMAT_PCM_S8, "Signed 8 bit PCM", NULL },
{ SF_FORMAT_PCM_16, "Signed 16 bit PCM", NULL },
{ SF_FORMAT_PCM_24, "Signed 24 bit PCM", NULL },
{ SF_FORMAT_PCM_32, "Signed 32 bit PCM", NULL },
{ SF_FORMAT_PCM_U8, "Unsigned 8 bit PCM", NULL },
{ SF_FORMAT_FLOAT, "32 bit float", NULL },
{ SF_FORMAT_DOUBLE, "64 bit float", NULL },
{ SF_FORMAT_ULAW, "U-Law", NULL },
{ SF_FORMAT_ALAW, "A-Law", NULL },
{ SF_FORMAT_IMA_ADPCM, "IMA ADPCM", NULL },
{ SF_FORMAT_MS_ADPCM, "Microsoft ADPCM", NULL },
{ SF_FORMAT_GSM610, "GSM 6.10", NULL },
{ SF_FORMAT_G721_32, "32kbs G721 ADPCM", NULL },
{ SF_FORMAT_G723_24, "24kbs G723 ADPCM", NULL },
{ SF_FORMAT_DWVW_12, "12 bit DWVW", NULL },
{ SF_FORMAT_DWVW_16, "16 bit DWVW", NULL },
{ SF_FORMAT_DWVW_24, "24 bit DWVW", NULL },
{ SF_FORMAT_VOX_ADPCM, "VOX ADPCM", "vox" },
{ SF_FORMAT_DPCM_16, "16 bit DPCM", NULL },
{ SF_FORMAT_DPCM_8, "8 bit DPCM", NULL }
} ; /* subtype_formats */
int
psf_get_format_subtype_count (void)
{ return (sizeof (subtype_formats) / sizeof (SF_FORMAT_INFO)) ;
} /* psf_get_format_subtype_count */
int
psf_get_format_subtype (SF_FORMAT_INFO *data)
{ int indx ;
if (data->format < 0 || data->format >= (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
return SFE_BAD_CONTROL_CMD ;
indx = data->format ;
memcpy (data, &(subtype_formats [indx]), sizeof (SF_FORMAT_INFO)) ;
return 0 ;
} /* psf_get_format_subtype */
/*==============================================================================
*/
int
psf_get_format_info (SF_FORMAT_INFO *data)
{ int k, format ;
if (data->format & SF_FORMAT_TYPEMASK)
{ format = data->format & SF_FORMAT_TYPEMASK ;
for (k = 0 ; k < (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
{ if (format == major_formats [k].format)
{ memcpy (data, &(major_formats [k]), sizeof (SF_FORMAT_INFO)) ;
return 0 ;
} ;
} ;
}
else if (data->format & SF_FORMAT_SUBMASK)
{ format = data->format & SF_FORMAT_SUBMASK ;
for (k = 0 ; k < (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
{ if (format == subtype_formats [k].format)
{ memcpy (data, &(subtype_formats [k]), sizeof (SF_FORMAT_INFO)) ;
return 0 ;
} ;
} ;
} ;
memset (data, 0, sizeof (SF_FORMAT_INFO)) ;
return SFE_BAD_CONTROL_CMD ;
} /* psf_get_format_info */
/*==============================================================================
*/
double
psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
{ sf_count_t position ;
double max_val, temp, *data ;
int k, len, readcount, save_state ;
/* If the file is not seekable, there is nothing we can do. */
if (! psf->sf.seekable)
{ psf->error = SFE_NOT_SEEKABLE ;
return 0.0 ;
} ;
if (! psf->read_double)
{ psf->error = SFE_UNIMPLEMENTED ;
return 0.0 ;
} ;
save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
/* Brute force. Read the whole file and find the biggest sample. */
/* Get current position in file */
position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ;
/* Go to start of file. */
sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;
data = psf->u.dbuf ;
len = ARRAY_LEN (psf->u.dbuf) ;
for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
{ readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
for (k = 0 ; k < readcount ; k++)
{ temp = fabs (data [k]) ;
max_val = temp > max_val ? temp : max_val ;
} ;
} ;
/* Return to SNDFILE to original state. */
sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;
sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
return max_val ;
} /* psf_calc_signal_max */
int
psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
{ sf_count_t position ;
double temp, *data ;
int k, len, readcount, save_state ;
int chan ;
/* If the file is not seekable, there is nothing we can do. */
if (! psf->sf.seekable)
return (psf->error = SFE_NOT_SEEKABLE) ;
if (! psf->read_double)
return (psf->error = SFE_UNIMPLEMENTED) ;
save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
memset (peaks, 0, sizeof (double) * psf->sf.channels) ;
/* Brute force. Read the whole file and find the biggest sample for each channel. */
position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */
sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ; /* Go to start of file. */
len = ARRAY_LEN (psf->u.dbuf) ;
data = psf->u.dbuf ;
chan = 0 ;
readcount = len ;
while (readcount > 0)
{ readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
for (k = 0 ; k < readcount ; k++)
{ temp = fabs (data [k]) ;
peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ;
chan = (chan + 1) % psf->sf.channels ;
} ;
} ;
sf_seek ((SNDFILE*) psf, position, SEEK_SET) ; /* Return to original position. */
sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
return 0 ;
} /* psf_calc_max_all_channels */
int
psf_get_signal_max (SF_PRIVATE *psf, double *peak)
{ int k ;
if (psf->peak_info == NULL)
return SF_FALSE ;
peak [0] = psf->peak_info->peaks [0].value ;
for (k = 1 ; k < psf->sf.channels ; k++)
peak [0] = SF_MAX (peak [0], psf->peak_info->peaks [k].value) ;
return SF_TRUE ;
} /* psf_get_signal_max */
int
psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks)
{ int k ;
if (psf->peak_info == NULL)
return SF_FALSE ;
for (k = 0 ; k < psf->sf.channels ; k++)
peaks [k] = psf->peak_info->peaks [k].value ;
return SF_TRUE ;
} /* psf_get_max_all_channels */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 0aae0d9d-ab2b-4d70-ade3-47a534666f8e
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,766 +0,0 @@
/*
** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#ifndef SNDFILE_COMMON_H
#define SNDFILE_COMMON_H
#include "sfconfig.h"
#include <stdlib.h>
#if HAVE_STDINT_H
#include <stdint.h>
#endif
#ifndef SNDFILE_H
#include "sndfile.h"
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef __cplusplus
#error "This code is not designed to be compiled with a C++ compiler."
#endif
#ifdef UNUSED
#elif defined (__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#elif defined (__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
#ifdef __GNUC__
# define WARN_UNUSED __attribute__ ((warn_unused_result))
#else
# define WARN_UNUSED
#endif
#define SF_BUFFER_LEN (8192*2)
#define SF_FILENAME_LEN (512)
#define SF_SYSERR_LEN (256)
#define SF_MAX_STRINGS (16)
#define SF_STR_BUFFER_LEN (8192)
#define SF_HEADER_LEN (4100 + SF_STR_BUFFER_LEN)
#define PSF_SEEK_ERROR ((sf_count_t) -1)
#define BITWIDTH2BYTES(x) (((x) + 7) / 8)
/* For some reason sizeof returns an unsigned value which causes
** a warning when that value is added or subtracted from a signed
** value. Use SIGNED_SIZEOF instead.
*/
#define SIGNED_SIZEOF(x) ((int) sizeof (x))
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
#define SF_MAX(a,b) ((a) > (b) ? (a) : (b))
#define SF_MIN(a,b) ((a) < (b) ? (a) : (b))
enum
{ /* PEAK chunk location. */
SF_PEAK_START = 42,
SF_PEAK_END = 43,
/* PEAK chunk location. */
SF_SCALE_MAX = 52,
SF_SCALE_MIN = 53,
/* str_flags values. */
SF_STR_ALLOW_START = 0x0100,
SF_STR_ALLOW_END = 0x0200,
/* Location of strings. */
SF_STR_LOCATE_START = 0x0400,
SF_STR_LOCATE_END = 0x0800,
SFD_TYPEMASK = 0x0FFFFFFF
} ;
#define SFM_MASK (SFM_READ | SFM_WRITE | SFM_RDWR)
#define SFM_UNMASK (~SFM_MASK)
/*---------------------------------------------------------------------------------------
** Formats that may be supported at some time in the future.
** When support is finalised, these values move to src/sndfile.h.
*/
enum
{ /* Work in progress. */
/* Formats supported read only. */
SF_FORMAT_WVE = 0x4020000, /* Psion ALaw Sound File */
SF_FORMAT_TXW = 0x4030000, /* Yamaha TX16 sampler file */
SF_FORMAT_DWD = 0x4040000, /* DiamondWare Digirized */
/* Following are detected but not supported. */
SF_FORMAT_OGG = 0x4090000,
SF_FORMAT_REX = 0x40A0000, /* Propellorheads Rex/Rcy */
SF_FORMAT_REX2 = 0x40D0000, /* Propellorheads Rex2 */
SF_FORMAT_KRZ = 0x40E0000, /* Kurzweil sampler file */
SF_FORMAT_WMA = 0x4100000, /* Windows Media Audio. */
SF_FORMAT_SHN = 0x4110000, /* Shorten. */
/* Unsupported encodings. */
SF_FORMAT_VORBIS = 0x1001,
SF_FORMAT_SVX_FIB = 0x1020, /* SVX Fibonacci Delta encoding. */
SF_FORMAT_SVX_EXP = 0x1021, /* SVX Exponential Delta encoding. */
SF_FORMAT_PCM_N = 0x1030
} ;
/*---------------------------------------------------------------------------------------
** PEAK_CHUNK - This chunk type is common to both AIFF and WAVE files although their
** endian encodings are different.
*/
typedef struct
{ double value ; /* signed value of peak */
sf_count_t position ; /* the sample frame for the peak */
} PEAK_POS ;
typedef struct
{ /* libsndfile internal : write a PEAK chunk at the start or end of the file? */
int peak_loc ;
/* WAV/AIFF */
unsigned int version ; /* version of the PEAK chunk */
unsigned int timestamp ; /* secs since 1/1/1970 */
/* CAF */
unsigned int edit_number ;
#if HAVE_FLEXIBLE_ARRAY
/* the per channel peak info */
PEAK_POS peaks [] ;
#else
/*
** This is not ISO compliant C. It works on some compilers which
** don't support the ISO standard flexible struct array which is
** used above. If your compiler doesn't like this I suggest you find
** youself a 1999 ISO C standards compilant compiler. GCC-3.X is
** highly recommended.
*/
PEAK_POS peaks [0] ;
#endif
} PEAK_INFO ;
static inline PEAK_INFO *
peak_info_calloc (int channels)
{ return calloc (1, sizeof (PEAK_INFO) + channels * sizeof (PEAK_POS)) ;
} /* peak_info_calloc */
typedef struct
{ int type ;
int flags ;
char *str ;
} STR_DATA ;
static inline size_t
make_size_t (int x)
{ return (size_t) x ;
} /* size_t_of_int */
/*=======================================================================================
** SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
** sf_open_XXXX functions. The caller however has no knowledge of the struct's
** contents.
*/
typedef struct sf_private_tag
{ /* Force the compiler to double align the start of buffer. */
union
{ double dbuf [SF_BUFFER_LEN / sizeof (double)] ;
#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
int64_t lbuf [SF_BUFFER_LEN / sizeof (int64_t)] ;
#else
long lbuf [SF_BUFFER_LEN / sizeof (double)] ;
#endif
float fbuf [SF_BUFFER_LEN / sizeof (float)] ;
int ibuf [SF_BUFFER_LEN / sizeof (int)] ;
short sbuf [SF_BUFFER_LEN / sizeof (short)] ;
char cbuf [SF_BUFFER_LEN / sizeof (char)] ;
signed char scbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
unsigned char ucbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
} u ;
char filepath [SF_FILENAME_LEN] ;
char rsrcpath [SF_FILENAME_LEN] ;
char directory [SF_FILENAME_LEN] ;
char filename [SF_FILENAME_LEN / 4] ;
char syserr [SF_SYSERR_LEN] ;
/* logbuffer and logindex should only be changed within the logging functions
** of common.c
*/
char logbuffer [SF_BUFFER_LEN] ;
unsigned char header [SF_HEADER_LEN] ; /* Must be unsigned */
int rwf_endian ; /* Header endian-ness flag. */
/* Storage and housekeeping data for adding/reading strings from
** sound files.
*/
STR_DATA strings [SF_MAX_STRINGS] ;
char str_storage [SF_STR_BUFFER_LEN] ;
char *str_end ;
int str_flags ;
/* Guard value. If this changes the buffers above have overflowed. */
int Magick ;
/* Index variables for maintaining logbuffer and header above. */
int logindex ;
int headindex, headend ;
int has_text ;
int do_not_close_descriptor ;
#if USE_WINDOWS_API
/*
** These fields can only be used in src/file_io.c.
** They are basically the same as a windows file HANDLE.
*/
void *hfile, *hrsrc, *hsaved ;
#else
/* These fields can only be used in src/file_io.c. */
int filedes, rsrcdes, savedes ;
#endif
int error ;
int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
int endian ; /* File endianness : SF_ENDIAN_LITTLE or SF_ENDIAN_BIG. */
int float_endswap ; /* Need to endswap float32s? */
/*
** Maximum float value for calculating the multiplier for
** float/double to short/int conversions.
*/
int float_int_mult ;
float float_max ;
/* Vairables for handling pipes. */
int is_pipe ; /* True if file is a pipe. */
sf_count_t pipeoffset ; /* Number of bytes read from a pipe. */
/* True if clipping must be performed on float->int conversions. */
int add_clipping ;
SF_INFO sf ;
int have_written ; /* Has a single write been done to the file? */
PEAK_INFO *peak_info ;
/* Loop Info */
SF_LOOP_INFO *loop_info ;
SF_INSTRUMENT *instrument ;
/* Broadcast (EBU) Info */
SF_BROADCAST_INFO *broadcast_info ;
sf_count_t filelength ; /* Overall length of (embedded) file. */
sf_count_t fileoffset ; /* Offset in number of bytes from beginning of file. */
sf_count_t rsrclength ; /* Length of the resource fork (if it exists). */
sf_count_t dataoffset ; /* Offset in number of bytes from beginning of file. */
sf_count_t datalength ; /* Length in bytes of the audio data. */
sf_count_t dataend ; /* Offset to file tailer. */
int blockwidth ; /* Size in bytes of one set of interleaved samples. */
int bytewidth ; /* Size in bytes of one sample (one channel). */
void *dither ;
void *interleave ;
int last_op ; /* Last operation; either SFM_READ or SFM_WRITE */
sf_count_t read_current ;
sf_count_t write_current ;
void *fdata ; /* This is a pointer to dynamically allocated file format
** specific data.
*/
SF_DITHER_INFO write_dither ;
SF_DITHER_INFO read_dither ;
int norm_double ;
int norm_float ;
int auto_header ;
int ieee_replace ;
/* A set of file specific function pointers */
sf_count_t (*read_short) (struct sf_private_tag*, short *ptr, sf_count_t len) ;
sf_count_t (*read_int) (struct sf_private_tag*, int *ptr, sf_count_t len) ;
sf_count_t (*read_float) (struct sf_private_tag*, float *ptr, sf_count_t len) ;
sf_count_t (*read_double) (struct sf_private_tag*, double *ptr, sf_count_t len) ;
sf_count_t (*write_short) (struct sf_private_tag*, const short *ptr, sf_count_t len) ;
sf_count_t (*write_int) (struct sf_private_tag*, const int *ptr, sf_count_t len) ;
sf_count_t (*write_float) (struct sf_private_tag*, const float *ptr, sf_count_t len) ;
sf_count_t (*write_double) (struct sf_private_tag*, const double *ptr, sf_count_t len) ;
sf_count_t (*seek) (struct sf_private_tag*, int mode, sf_count_t samples_from_start) ;
int (*write_header) (struct sf_private_tag*, int calc_length) ;
int (*command) (struct sf_private_tag*, int command, void *data, int datasize) ;
/*
** Separate close functions for the codec and the container.
** The codec close function is always called first.
*/
int (*codec_close) (struct sf_private_tag*) ;
int (*container_close) (struct sf_private_tag*) ;
char *format_desc ;
/* Virtual I/O functions. */
int virtual_io ;
SF_VIRTUAL_IO vio ;
void *vio_user_data ;
} SF_PRIVATE ;
enum
{ SFE_NO_ERROR = SF_ERR_NO_ERROR,
SFE_BAD_OPEN_FORMAT = SF_ERR_UNRECOGNISED_FORMAT,
SFE_SYSTEM = SF_ERR_SYSTEM,
SFE_MALFORMED_FILE = SF_ERR_MALFORMED_FILE,
SFE_UNSUPPORTED_ENCODING = SF_ERR_UNSUPPORTED_ENCODING,
SFE_BAD_FILE,
SFE_BAD_FILE_READ,
SFE_OPEN_FAILED,
SFE_BAD_SNDFILE_PTR,
SFE_BAD_SF_INFO_PTR,
SFE_BAD_SF_INCOMPLETE,
SFE_BAD_FILE_PTR,
SFE_BAD_INT_PTR,
SFE_BAD_STAT_SIZE,
SFE_MALLOC_FAILED,
SFE_UNIMPLEMENTED,
SFE_BAD_READ_ALIGN,
SFE_BAD_WRITE_ALIGN,
SFE_UNKNOWN_FORMAT,
SFE_NOT_READMODE,
SFE_NOT_WRITEMODE,
SFE_BAD_MODE_RW,
SFE_BAD_SF_INFO,
SFE_BAD_OFFSET,
SFE_NO_EMBED_SUPPORT,
SFE_NO_EMBEDDED_RDWR,
SFE_NO_PIPE_WRITE,
SFE_INTERNAL,
SFE_BAD_CONTROL_CMD,
SFE_BAD_ENDIAN,
SFE_CHANNEL_COUNT,
SFE_BAD_RDWR_FORMAT,
SFE_BAD_VIRTUAL_IO,
SFE_INTERLEAVE_MODE,
SFE_INTERLEAVE_SEEK,
SFE_INTERLEAVE_READ,
SFE_BAD_SEEK,
SFE_NOT_SEEKABLE,
SFE_AMBIGUOUS_SEEK,
SFE_WRONG_SEEK,
SFE_SEEK_FAILED,
SFE_BAD_OPEN_MODE,
SFE_OPEN_PIPE_RDWR,
SFE_RDWR_POSITION,
SFE_RDWR_BAD_HEADER,
SFE_STR_NO_SUPPORT,
SFE_STR_NOT_WRITE,
SFE_STR_MAX_DATA,
SFE_STR_MAX_COUNT,
SFE_STR_BAD_TYPE,
SFE_STR_NO_ADD_END,
SFE_STR_BAD_STRING,
SFE_STR_WEIRD,
SFE_WAV_NO_RIFF,
SFE_WAV_NO_WAVE,
SFE_WAV_NO_FMT,
SFE_WAV_FMT_SHORT,
SFE_WAV_BAD_FACT,
SFE_WAV_BAD_PEAK,
SFE_WAV_PEAK_B4_FMT,
SFE_WAV_BAD_FORMAT,
SFE_WAV_BAD_BLOCKALIGN,
SFE_WAV_NO_DATA,
SFE_WAV_BAD_LIST,
SFE_WAV_ADPCM_NOT4BIT,
SFE_WAV_ADPCM_CHANNELS,
SFE_WAV_GSM610_FORMAT,
SFE_WAV_UNKNOWN_CHUNK,
SFE_WAV_WVPK_DATA,
SFE_AIFF_NO_FORM,
SFE_AIFF_AIFF_NO_FORM,
SFE_AIFF_COMM_NO_FORM,
SFE_AIFF_SSND_NO_COMM,
SFE_AIFF_UNKNOWN_CHUNK,
SFE_AIFF_COMM_CHUNK_SIZE,
SFE_AIFF_BAD_COMM_CHUNK,
SFE_AIFF_PEAK_B4_COMM,
SFE_AIFF_BAD_PEAK,
SFE_AIFF_NO_SSND,
SFE_AIFF_NO_DATA,
SFE_AIFF_RW_SSND_NOT_LAST,
SFE_AU_UNKNOWN_FORMAT,
SFE_AU_NO_DOTSND,
SFE_AU_EMBED_BAD_LEN,
SFE_RAW_READ_BAD_SPEC,
SFE_RAW_BAD_BITWIDTH,
SFE_RAW_BAD_FORMAT,
SFE_PAF_NO_MARKER,
SFE_PAF_VERSION,
SFE_PAF_UNKNOWN_FORMAT,
SFE_PAF_SHORT_HEADER,
SFE_SVX_NO_FORM,
SFE_SVX_NO_BODY,
SFE_SVX_NO_DATA,
SFE_SVX_BAD_COMP,
SFE_SVX_BAD_NAME_LENGTH,
SFE_NIST_BAD_HEADER,
SFE_NIST_CRLF_CONVERISON,
SFE_NIST_BAD_ENCODING,
SFE_VOC_NO_CREATIVE,
SFE_VOC_BAD_FORMAT,
SFE_VOC_BAD_VERSION,
SFE_VOC_BAD_MARKER,
SFE_VOC_BAD_SECTIONS,
SFE_VOC_MULTI_SAMPLERATE,
SFE_VOC_MULTI_SECTION,
SFE_VOC_MULTI_PARAM,
SFE_VOC_SECTION_COUNT,
SFE_VOC_NO_PIPE,
SFE_IRCAM_NO_MARKER,
SFE_IRCAM_BAD_CHANNELS,
SFE_IRCAM_UNKNOWN_FORMAT,
SFE_W64_64_BIT,
SFE_W64_NO_RIFF,
SFE_W64_NO_WAVE,
SFE_W64_NO_FMT,
SFE_W64_NO_DATA,
SFE_W64_FMT_SHORT,
SFE_W64_FMT_TOO_BIG,
SFE_W64_ADPCM_NOT4BIT,
SFE_W64_ADPCM_CHANNELS,
SFE_W64_GSM610_FORMAT,
SFE_MAT4_BAD_NAME,
SFE_MAT4_NO_SAMPLERATE,
SFE_MAT4_ZERO_CHANNELS,
SFE_MAT5_BAD_ENDIAN,
SFE_MAT5_NO_BLOCK,
SFE_MAT5_SAMPLE_RATE,
SFE_MAT5_ZERO_CHANNELS,
SFE_PVF_NO_PVF1,
SFE_PVF_BAD_HEADER,
SFE_PVF_BAD_BITWIDTH,
SFE_DWVW_BAD_BITWIDTH,
SFE_G72X_NOT_MONO,
SFE_XI_BAD_HEADER,
SFE_XI_EXCESS_SAMPLES,
SFE_XI_NO_PIPE,
SFE_HTK_NO_PIPE,
SFE_SDS_NOT_SDS,
SFE_SDS_BAD_BIT_WIDTH,
SFE_SD2_FD_DISALLOWED,
SFE_SD2_BAD_DATA_OFFSET,
SFE_SD2_BAD_MAP_OFFSET,
SFE_SD2_BAD_DATA_LENGTH,
SFE_SD2_BAD_MAP_LENGTH,
SFE_SD2_BAD_RSRC,
SFE_SD2_BAD_SAMPLE_SIZE,
SFE_FLAC_BAD_HEADER,
SFE_FLAC_NEW_DECODER,
SFE_FLAC_INIT_DECODER,
SFE_FLAC_LOST_SYNC,
SFE_FLAC_BAD_SAMPLE_RATE,
SFE_FLAC_UNKOWN_ERROR,
SFE_MAX_ERROR /* This must be last in list. */
} ;
int subformat_to_bytewidth (int format) ;
int s_bitwidth_to_subformat (int bits) ;
int u_bitwidth_to_subformat (int bits) ;
/* Functions for reading and writing floats and doubles on processors
** with non-IEEE floats/doubles.
*/
float float32_be_read (unsigned char *cptr) ;
float float32_le_read (unsigned char *cptr) ;
void float32_be_write (float in, unsigned char *out) ;
void float32_le_write (float in, unsigned char *out) ;
double double64_be_read (unsigned char *cptr) ;
double double64_le_read (unsigned char *cptr) ;
void double64_be_write (double in, unsigned char *out) ;
void double64_le_write (double in, unsigned char *out) ;
/* Functions for writing to the internal logging buffer. */
void psf_log_printf (SF_PRIVATE *psf, const char *format, ...) ;
void psf_log_SF_INFO (SF_PRIVATE *psf) ;
void psf_hexdump (void *ptr, int len) ;
/* Functions used when writing file headers. */
int psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) ;
void psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...) ;
/* Functions used when reading file headers. */
int psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) ;
/* Functions used in the write function for updating the peak chunk. */
void peak_update_short (SF_PRIVATE *psf, short *ptr, size_t items) ;
void peak_update_int (SF_PRIVATE *psf, int *ptr, size_t items) ;
void peak_update_double (SF_PRIVATE *psf, double *ptr, size_t items) ;
/* Functions defined in command.c. */
int psf_get_format_simple_count (void) ;
int psf_get_format_simple (SF_FORMAT_INFO *data) ;
int psf_get_format_info (SF_FORMAT_INFO *data) ;
int psf_get_format_major_count (void) ;
int psf_get_format_major (SF_FORMAT_INFO *data) ;
int psf_get_format_subtype_count (void) ;
int psf_get_format_subtype (SF_FORMAT_INFO *data) ;
void psf_generate_format_desc (SF_PRIVATE *psf) ;
double psf_calc_signal_max (SF_PRIVATE *psf, int normalize) ;
int psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize) ;
int psf_get_signal_max (SF_PRIVATE *psf, double *peak) ;
int psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks) ;
/* Functions in strings.c. */
const char* psf_get_string (SF_PRIVATE *psf, int str_type) ;
int psf_set_string (SF_PRIVATE *psf, int str_type, const char *str) ;
int psf_store_string (SF_PRIVATE *psf, int str_type, const char *str) ;
/* Default seek function. Use for PCM and float encoded data. */
sf_count_t psf_default_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start) ;
/* Generate the currebt date as a string. */
void psf_get_date_str (char *str, int maxlen) ;
int macos_guess_file_type (SF_PRIVATE *psf, const char *filename) ;
/*------------------------------------------------------------------------------------
** File I/O functions which will allow access to large files (> 2 Gig) on
** some 32 bit OSes. Implementation in file_io.c.
*/
int psf_fopen (SF_PRIVATE *psf, const char *pathname, int flags) ;
int psf_set_stdio (SF_PRIVATE *psf, int mode) ;
int psf_file_valid (SF_PRIVATE *psf) ;
void psf_set_file (SF_PRIVATE *psf, int fd) ;
void psf_init_files (SF_PRIVATE *psf) ;
void psf_use_rsrc (SF_PRIVATE *psf, int on_off) ;
sf_count_t psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) ;
sf_count_t psf_fread (void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
sf_count_t psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
sf_count_t psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) ;
sf_count_t psf_ftell (SF_PRIVATE *psf) ;
sf_count_t psf_get_filelen (SF_PRIVATE *psf) ;
void psf_fsync (SF_PRIVATE *psf) ;
int psf_is_pipe (SF_PRIVATE *psf) ;
int psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) ;
int psf_fclose (SF_PRIVATE *psf) ;
/* Open and close the resource fork of a file. */
int psf_open_rsrc (SF_PRIVATE *psf, int mode) ;
int psf_close_rsrc (SF_PRIVATE *psf) ;
/*
void psf_fclearerr (SF_PRIVATE *psf) ;
int psf_ferror (SF_PRIVATE *psf) ;
*/
/*------------------------------------------------------------------------------------
** Functions for reading and writing different file formats.
*/
int aiff_open (SF_PRIVATE *psf) ;
int au_open (SF_PRIVATE *psf) ;
int avr_open (SF_PRIVATE *psf) ;
int htk_open (SF_PRIVATE *psf) ;
int ircam_open (SF_PRIVATE *psf) ;
int mat4_open (SF_PRIVATE *psf) ;
int mat5_open (SF_PRIVATE *psf) ;
int nist_open (SF_PRIVATE *psf) ;
int paf_open (SF_PRIVATE *psf) ;
int pvf_open (SF_PRIVATE *psf) ;
int raw_open (SF_PRIVATE *psf) ;
int sd2_open (SF_PRIVATE *psf) ;
int sds_open (SF_PRIVATE *psf) ;
int svx_open (SF_PRIVATE *psf) ;
int voc_open (SF_PRIVATE *psf) ;
int w64_open (SF_PRIVATE *psf) ;
int wav_open (SF_PRIVATE *psf) ;
int xi_open (SF_PRIVATE *psf) ;
int flac_open (SF_PRIVATE *psf) ;
int caf_open (SF_PRIVATE *psf) ;
/* In progress. Do not currently work. */
int mpeg_open (SF_PRIVATE *psf) ;
int ogg_open (SF_PRIVATE *psf) ;
int rx2_open (SF_PRIVATE *psf) ;
int txw_open (SF_PRIVATE *psf) ;
int wve_open (SF_PRIVATE *psf) ;
int dwd_open (SF_PRIVATE *psf) ;
int macbinary3_open (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------------
** Init functions for a number of common data encodings.
*/
int pcm_init (SF_PRIVATE *psf) ;
int ulaw_init (SF_PRIVATE *psf) ;
int alaw_init (SF_PRIVATE *psf) ;
int float32_init (SF_PRIVATE *psf) ;
int double64_init (SF_PRIVATE *psf) ;
int dwvw_init (SF_PRIVATE *psf, int bitwidth) ;
int gsm610_init (SF_PRIVATE *psf) ;
int vox_adpcm_init (SF_PRIVATE *psf) ;
int flac_init (SF_PRIVATE *psf) ;
int g72x_init (SF_PRIVATE * psf) ;
int dither_init (SF_PRIVATE *psf, int mode) ;
int wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
int wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
int aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
int interleave_init (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------------
** Other helper functions.
*/
void *psf_memset (void *s, int c, sf_count_t n) ;
SF_INSTRUMENT * psf_instrument_alloc (void) ;
SF_BROADCAST_INFO* broadcast_info_alloc (void) ;
int broadcast_info_copy (SF_BROADCAST_INFO* dst, SF_BROADCAST_INFO* src) ;
int broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate) ;
/*------------------------------------------------------------------------------------
** Here's how we fix systems which don't snprintf / vsnprintf.
** Systems without these functions should use the
*/
#if USE_WINDOWS_API
#define LSF_SNPRINTF _snprintf
#elif (HAVE_SNPRINTF && ! FORCE_MISSING_SNPRINTF)
#define LSF_SNPRINTF snprintf
#else
int missing_snprintf (char *str, size_t n, char const *fmt, ...) ;
#define LSF_SNPRINTF missing_snprintf
#endif
#if USE_WINDOWS_API
#define LSF_VSNPRINTF _vsnprintf
#elif (HAVE_VSNPRINTF && ! FORCE_MISSING_SNPRINTF)
#define LSF_VSNPRINTF vsnprintf
#else
int missing_vsnprintf (char *str, size_t n, const char *fmt, ...) ;
#define LSF_VSNPRINTF missing_vsnprintf
#endif
/*------------------------------------------------------------------------------------
** Extra commands for sf_command(). Not for public use yet.
*/
enum
{ SFC_TEST_AIFF_ADD_INST_CHUNK = 0x2000,
SFC_TEST_WAV_ADD_INFO_CHUNK = 0x2010
} ;
/*
** Maybe, one day, make these functions or something like them, public.
**
** Buffer to buffer dithering. Pointer in and out are allowed to point
** to the same buffer for in-place dithering.
*/
#if 0
int sf_dither_short (const SF_DITHER_INFO *dither, const short *in, short *out, int count) ;
int sf_dither_int (const SF_DITHER_INFO *dither, const int *in, int *out, int count) ;
int sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out, int count) ;
int sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int count) ;
#endif
#endif /* SNDFILE_COMMON_H */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 7b45c0ee-5835-4a18-a4ef-994e4cd95b67
*/

View File

@@ -1,247 +0,0 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Set to 1 if the compile is GNU GCC. */
#undef COMPILER_IS_GCC
/* Target processor clips on negative float to int conversion. */
#undef CPU_CLIPS_NEGATIVE
/* Target processor clips on positive float to int conversion. */
#undef CPU_CLIPS_POSITIVE
/* Target processor is big endian. */
#undef CPU_IS_BIG_ENDIAN
/* Target processor is little endian. */
#undef CPU_IS_LITTLE_ENDIAN
/* Set to 1 to enable experimental code. */
#undef ENABLE_EXPERIMENTAL_CODE
/* Major version of GCC or 3 otherwise. */
#undef GCC_MAJOR_VERSION
/* Define to 1 if you have the <alsa/asoundlib.h> header file. */
#undef HAVE_ALSA_ASOUNDLIB_H
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
/* Define to 1 if you have the `calloc' function. */
#undef HAVE_CALLOC
/* Define to 1 if you have the `ceil' function. */
#undef HAVE_CEIL
/* Set to 1 if S_IRGRP is defined. */
#undef HAVE_DECL_S_IRGRP
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
/* Define to 1 if you have the `fdatasync' function. */
#undef HAVE_FDATASYNC
/* Define to 1 if you have libflac 1.1.1 */
#undef HAVE_FLAC_1_1_1
/* Define to 1 if you have the <FLAC/all.h> header file. */
#undef HAVE_FLAC_ALL_H
/* Set to 1 if the compile supports the struct hack. */
#undef HAVE_FLEXIBLE_ARRAY
/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
/* Define to 1 if you have the `fmod' function. */
#undef HAVE_FMOD
/* Define to 1 if you have the `free' function. */
#undef HAVE_FREE
/* Define to 1 if you have the `fstat' function. */
#undef HAVE_FSTAT
/* Define to 1 if you have the `fsync' function. */
#undef HAVE_FSYNC
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `gmtime' function. */
#undef HAVE_GMTIME
/* Define to 1 if you have the `gmtime_r' function. */
#undef HAVE_GMTIME_R
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have C99's lrint function. */
#undef HAVE_LRINT
/* Define if you have C99's lrintf function. */
#undef HAVE_LRINTF
/* Define to 1 if you have the `lseek' function. */
#undef HAVE_LSEEK
/* Define to 1 if you have the `malloc' function. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define to 1 if you have the `open' function. */
#undef HAVE_OPEN
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the `read' function. */
#undef HAVE_READ
/* Define to 1 if you have the `realloc' function. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `setlocale' function. */
#undef HAVE_SETLOCALE
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Set to 1 if you have libsqlite3. */
#undef HAVE_SQLITE3
/* Define to 1 if the system has the type `ssize_t'. */
#undef HAVE_SSIZE_T
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the `write' function. */
#undef HAVE_WRITE
/* Set to 1 if compiling for MacOSX */
#undef OS_IS_MACOSX
/* Set to 1 if compiling for Win32 */
#undef OS_IS_WIN32
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Set to maximum allowed value of sf_count_t type. */
#undef SF_COUNT_MAX
/* The size of a `double', as computed by sizeof. */
#undef SIZEOF_DOUBLE
/* The size of a `float', as computed by sizeof. */
#undef SIZEOF_FLOAT
/* The size of a `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of a `int64_t', as computed by sizeof. */
#undef SIZEOF_INT64_T
/* The size of a `loff_t', as computed by sizeof. */
#undef SIZEOF_LOFF_T
/* The size of a `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of a `long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* The size of a `off64_t', as computed by sizeof. */
#undef SIZEOF_OFF64_T
/* The size of a `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
/* Set to sizeof (long) if unknown. */
#undef SIZEOF_SF_COUNT_T
/* The size of a `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* The size of a `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of a `ssize_t', as computed by sizeof. */
#undef SIZEOF_SSIZE_T
/* The size of a `void*', as computed by sizeof. */
#undef SIZEOF_VOIDP
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Set to long if unknown. */
#undef TYPEOF_SF_COUNT_T
/* Set to 1 to use the native windows API */
#undef USE_WINDOWS_API
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define to make fseeko etc. visible, on some hosts. */
#undef _LARGEFILE_SOURCE
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES

View File

@@ -1,39 +0,0 @@
; Auto-generated by create_symbols_file.py
LIBRARY cygsndfile-1.dll
EXPORTS
sf_command @1
sf_open @2
sf_close @3
sf_seek @4
sf_error @7
sf_perror @8
sf_error_str @9
sf_error_number @10
sf_format_check @11
sf_read_raw @16
sf_readf_short @17
sf_readf_int @18
sf_readf_float @19
sf_readf_double @20
sf_read_short @21
sf_read_int @22
sf_read_float @23
sf_read_double @24
sf_write_raw @32
sf_writef_short @33
sf_writef_int @34
sf_writef_float @35
sf_writef_double @36
sf_write_short @37
sf_write_int @38
sf_write_float @39
sf_write_double @40
sf_strerror @50
sf_get_string @60
sf_set_string @61
sf_open_fd @70
sf_open_virtual @80
sf_write_sync @90

View File

@@ -1,535 +0,0 @@
/*
** Copyright (C) 2003,2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdlib.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
/*============================================================================
** Rule number 1 is to only apply dither when going from a larger bitwidth
** to a smaller bitwidth. This can happen on both read and write.
**
** Need to apply dither on all conversions marked X below.
**
** Dither on write:
**
** Input
** | short int float double
** --------+-----------------------------------------------
** O 8 bit | X X X X
** u 16 bit | none X X X
** t 24 bit | none X X X
** p 32 bit | none none X X
** u float | none none none none
** t double | none none none none
**
** Dither on read:
**
** Input
** O | 8 bit 16 bit 24 bit 32 bit float double
** u --------+-------------------------------------------------
** t short | none none X X X X
** p int | none none none X X X
** u float | none none none none none none
** t double | none none none none none none
*/
#define SFE_DITHER_BAD_PTR 666
#define SFE_DITHER_BAD_TYPE 667
typedef struct
{ int read_short_dither_bits, read_int_dither_bits ;
int write_short_dither_bits, write_int_dither_bits ;
double read_float_dither_scale, read_double_dither_bits ;
double write_float_dither_scale, write_double_dither_bits ;
sf_count_t (*read_short) (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
sf_count_t (*read_int) (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
sf_count_t (*read_float) (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
sf_count_t (*read_double) (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
sf_count_t (*write_short) (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
sf_count_t (*write_int) (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
sf_count_t (*write_float) (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
sf_count_t (*write_double) (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
double buffer [SF_BUFFER_LEN / sizeof (double)] ;
} DITHER_DATA ;
static sf_count_t dither_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t dither_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t dither_write_short (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t dither_write_int (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t dither_write_float (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t dither_write_double (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
int
dither_init (SF_PRIVATE *psf, int mode)
{ DITHER_DATA *pdither ;
pdither = psf->dither ; /* This may be NULL. */
/* Turn off dither on read. */
if (mode == SFM_READ && psf->read_dither.type == SFD_NO_DITHER)
{ if (pdither == NULL)
return 0 ; /* Dither is already off, so just return. */
if (pdither->read_short)
psf->read_short = pdither->read_short ;
if (pdither->read_int)
psf->read_int = pdither->read_int ;
if (pdither->read_float)
psf->read_float = pdither->read_float ;
if (pdither->read_double)
psf->read_double = pdither->read_double ;
return 0 ;
} ;
/* Turn off dither on write. */
if (mode == SFM_WRITE && psf->write_dither.type == SFD_NO_DITHER)
{ if (pdither == NULL)
return 0 ; /* Dither is already off, so just return. */
if (pdither->write_short)
psf->write_short = pdither->write_short ;
if (pdither->write_int)
psf->write_int = pdither->write_int ;
if (pdither->write_float)
psf->write_float = pdither->write_float ;
if (pdither->write_double)
psf->write_double = pdither->write_double ;
return 0 ;
} ;
/* Turn on dither on read if asked. */
if (mode == SFM_READ && psf->read_dither.type != 0)
{ if (pdither == NULL)
pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
if (pdither == NULL)
return SFE_MALLOC_FAILED ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_DOUBLE :
case SF_FORMAT_FLOAT :
pdither->read_int = psf->read_int ;
psf->read_int = dither_read_int ;
case SF_FORMAT_PCM_32 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
pdither->read_short = psf->read_short ;
psf->read_short = dither_read_short ;
default : break ;
} ;
} ;
/* Turn on dither on write if asked. */
if (mode == SFM_WRITE && psf->write_dither.type != 0)
{ if (pdither == NULL)
pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
if (pdither == NULL)
return SFE_MALLOC_FAILED ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_DOUBLE :
case SF_FORMAT_FLOAT :
pdither->write_int = psf->write_int ;
psf->write_int = dither_write_int ;
case SF_FORMAT_PCM_32 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
default : break ;
} ;
pdither->write_short = psf->write_short ;
psf->write_short = dither_write_short ;
pdither->write_int = psf->write_int ;
psf->write_int = dither_write_int ;
pdither->write_float = psf->write_float ;
psf->write_float = dither_write_float ;
pdither->write_double = psf->write_double ;
psf->write_double = dither_write_double ;
} ;
return 0 ;
} /* dither_init */
/*==============================================================================
*/
static void dither_short (const short *in, short *out, int frames, int channels) ;
static void dither_int (const int *in, int *out, int frames, int channels) ;
static void dither_float (const float *in, float *out, int frames, int channels) ;
static void dither_double (const double *in, double *out, int frames, int channels) ;
static sf_count_t
dither_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ psf = psf ;
ptr = ptr ;
return len ;
} /* dither_read_short */
static sf_count_t
dither_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ psf = psf ;
ptr = ptr ;
return len ;
} /* dither_read_int */
/*------------------------------------------------------------------------------
*/
static sf_count_t
dither_write_short (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ DITHER_DATA *pdither ;
int bufferlen, writecount, thiswrite ;
sf_count_t total = 0 ;
if ((pdither = psf->dither) == NULL)
{ psf->error = SFE_DITHER_BAD_PTR ;
return 0 ;
} ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
case SF_FORMAT_DPCM_8 :
break ;
default :
return pdither->write_short (psf, ptr, len) ;
} ;
bufferlen = sizeof (pdither->buffer) / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
writecount /= psf->sf.channels ;
writecount *= psf->sf.channels ;
dither_short (ptr, (short*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
thiswrite = pdither->write_short (psf, (short*) pdither->buffer, writecount) ;
total += thiswrite ;
len -= thiswrite ;
if (thiswrite < writecount)
break ;
} ;
return total ;
} /* dither_write_short */
static sf_count_t
dither_write_int (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ DITHER_DATA *pdither ;
int bufferlen, writecount, thiswrite ;
sf_count_t total = 0 ;
if ((pdither = psf->dither) == NULL)
{ psf->error = SFE_DITHER_BAD_PTR ;
return 0 ;
} ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_DPCM_8 :
case SF_FORMAT_DPCM_16 :
break ;
default :
return pdither->write_int (psf, ptr, len) ;
} ;
bufferlen = sizeof (pdither->buffer) / sizeof (int) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
writecount /= psf->sf.channels ;
writecount *= psf->sf.channels ;
dither_int (ptr, (int*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
thiswrite = pdither->write_int (psf, (int*) pdither->buffer, writecount) ;
total += thiswrite ;
len -= thiswrite ;
if (thiswrite < writecount)
break ;
} ;
return total ;
} /* dither_write_int */
static sf_count_t
dither_write_float (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ DITHER_DATA *pdither ;
int bufferlen, writecount, thiswrite ;
sf_count_t total = 0 ;
if ((pdither = psf->dither) == NULL)
{ psf->error = SFE_DITHER_BAD_PTR ;
return 0 ;
} ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_DPCM_8 :
case SF_FORMAT_DPCM_16 :
break ;
default :
return pdither->write_float (psf, ptr, len) ;
} ;
bufferlen = sizeof (pdither->buffer) / sizeof (float) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (float) len ;
writecount /= psf->sf.channels ;
writecount *= psf->sf.channels ;
dither_float (ptr, (float*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
thiswrite = pdither->write_float (psf, (float*) pdither->buffer, writecount) ;
total += thiswrite ;
len -= thiswrite ;
if (thiswrite < writecount)
break ;
} ;
return total ;
} /* dither_write_float */
static sf_count_t
dither_write_double (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ DITHER_DATA *pdither ;
int bufferlen, writecount, thiswrite ;
sf_count_t total = 0 ;
if ((pdither = psf->dither) == NULL)
{ psf->error = SFE_DITHER_BAD_PTR ;
return 0 ;
} ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_U8 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
case SF_FORMAT_DPCM_8 :
case SF_FORMAT_DPCM_16 :
break ;
default :
return pdither->write_double (psf, ptr, len) ;
} ;
bufferlen = sizeof (pdither->buffer) / sizeof (double) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (double) len ;
writecount /= psf->sf.channels ;
writecount *= psf->sf.channels ;
dither_double (ptr, (double*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
thiswrite = pdither->write_double (psf, (double*) pdither->buffer, writecount) ;
total += thiswrite ;
len -= thiswrite ;
if (thiswrite < writecount)
break ;
} ;
return total ;
} /* dither_write_double */
/*==============================================================================
*/
static void
dither_short (const short *in, short *out, int frames, int channels)
{ int ch, k ;
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
} /* dither_short */
static void
dither_int (const int *in, int *out, int frames, int channels)
{ int ch, k ;
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
} /* dither_int */
static void
dither_float (const float *in, float *out, int frames, int channels)
{ int ch, k ;
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
} /* dither_float */
static void
dither_double (const double *in, double *out, int frames, int channels)
{ int ch, k ;
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
} /* dither_double */
/*==============================================================================
*/
#if 0
/*
** Not made public because this (maybe) requires storage of state information.
**
** Also maybe need separate state info for each channel!!!!
*/
int
DO_NOT_USE_sf_dither_short (const SF_DITHER_INFO *dither, const short *in, short *out, int frames, int channels)
{ int ch, k ;
if (! dither)
return SFE_DITHER_BAD_PTR ;
switch (dither->type & SFD_TYPEMASK)
{ case SFD_WHITE :
case SFD_TRIANGULAR_PDF :
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
break ;
default :
return SFE_DITHER_BAD_TYPE ;
} ;
return 0 ;
} /* DO_NOT_USE_sf_dither_short */
int
DO_NOT_USE_sf_dither_int (const SF_DITHER_INFO *dither, const int *in, int *out, int frames, int channels)
{ int ch, k ;
if (! dither)
return SFE_DITHER_BAD_PTR ;
switch (dither->type & SFD_TYPEMASK)
{ case SFD_WHITE :
case SFD_TRIANGULAR_PDF :
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
break ;
default :
return SFE_DITHER_BAD_TYPE ;
} ;
return 0 ;
} /* DO_NOT_USE_sf_dither_int */
int
DO_NOT_USE_sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out, int frames, int channels)
{ int ch, k ;
if (! dither)
return SFE_DITHER_BAD_PTR ;
switch (dither->type & SFD_TYPEMASK)
{ case SFD_WHITE :
case SFD_TRIANGULAR_PDF :
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
break ;
default :
return SFE_DITHER_BAD_TYPE ;
} ;
return 0 ;
} /* DO_NOT_USE_sf_dither_float */
int
DO_NOT_USE_sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int frames, int channels)
{ int ch, k ;
if (! dither)
return SFE_DITHER_BAD_PTR ;
switch (dither->type & SFD_TYPEMASK)
{ case SFD_WHITE :
case SFD_TRIANGULAR_PDF :
for (ch = 0 ; ch < channels ; ch++)
for (k = ch ; k < channels * frames ; k += channels)
out [k] = in [k] ;
break ;
default :
return SFE_DITHER_BAD_TYPE ;
} ;
return 0 ;
} /* DO_NOT_USE_sf_dither_double */
#endif
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 673fad58-5314-421c-9144-9d54bfdf104c
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,210 +0,0 @@
/*
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#if (ENABLE_EXPERIMENTAL_CODE == 0)
int
dwd_open (SF_PRIVATE *psf)
{ if (psf)
return SFE_UNIMPLEMENTED ;
return (psf && 0) ;
} /* dwd_open */
#else
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
#define SFE_DWD_NO_DWD 1666
#define SFE_DWD_BAND_BIT_WIDTH 1667
#define SFE_DWD_COMPRESSION 1668
#define DWD_IDENTIFIER "DiamondWare Digitized\n\0\x1a"
#define DWD_IDENTIFIER_LEN 24
#define DWD_HEADER_LEN 57
/*------------------------------------------------------------------------------
** Typedefs.
*/
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int dwd_read_header (SF_PRIVATE *psf) ;
static int dwd_close (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
dwd_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = dwd_read_header (psf)))
return error ;
} ;
if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_DWD)
return SFE_BAD_OPEN_FORMAT ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{
/*-psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
psf->endian = SF_ENDIAN_LITTLE ;
else if (psf->endian != SF_ENDIAN_LITTLE)
psf->endian = SF_ENDIAN_BIG ;
if (! (encoding = dwd_write_header (psf, SF_FALSE)))
return psf->error ;
psf->write_header = dwd_write_header ;
-*/
} ;
psf->container_close = dwd_close ;
/*-psf->blockwidth = psf->bytewidth * psf->sf.channels ;-*/
return error ;
} /* dwd_open */
/*------------------------------------------------------------------------------
*/
static int
dwd_close (SF_PRIVATE *psf)
{
psf = psf ;
return 0 ;
} /* dwd_close */
/* This struct contains all the fields of interest om the DWD header, but does not
** do so in the same order and layout as the actual file, header.
** No assumptions are made about the packing of this struct.
*/
typedef struct
{ unsigned char major, minor, compression, channels, bitwidth ;
unsigned short srate, maxval ;
unsigned int id, datalen, frames, offset ;
} DWD_HEADER ;
static int
dwd_read_header (SF_PRIVATE *psf)
{ DWD_HEADER dwdh ;
memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, DWD_IDENTIFIER_LEN) ;
if (memcmp (psf->u.cbuf, DWD_IDENTIFIER, DWD_IDENTIFIER_LEN) != 0)
return SFE_DWD_NO_DWD ;
psf_log_printf (psf, "Read only : DiamondWare Digitized (.dwd)\n", psf->u.cbuf) ;
psf_binheader_readf (psf, "11", &dwdh.major, &dwdh.minor) ;
psf_binheader_readf (psf, "e4j1", &dwdh.id, 1, &dwdh.compression) ;
psf_binheader_readf (psf, "e211", &dwdh.srate, &dwdh.channels, &dwdh.bitwidth) ;
psf_binheader_readf (psf, "e24", &dwdh.maxval, &dwdh.datalen) ;
psf_binheader_readf (psf, "e44", &dwdh.frames, &dwdh.offset) ;
psf_log_printf (psf, " Version Major : %d\n Version Minor : %d\n Unique ID : %08X\n",
dwdh.major, dwdh.minor, dwdh.id) ;
psf_log_printf (psf, " Compression : %d => ", dwdh.compression) ;
if (dwdh.compression != 0)
{ psf_log_printf (psf, "Unsupported compression\n") ;
return SFE_DWD_COMPRESSION ;
}
else
psf_log_printf (psf, "None\n") ;
psf_log_printf (psf, " Sample Rate : %d\n Channels : %d\n"
" Bit Width : %d\n",
dwdh.srate, dwdh.channels, dwdh.bitwidth) ;
switch (dwdh.bitwidth)
{ case 8 :
psf->sf.format = SF_FORMAT_DWD | SF_FORMAT_PCM_S8 ;
psf->bytewidth = 1 ;
break ;
case 16 :
psf->sf.format = SF_FORMAT_DWD | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
break ;
default :
psf_log_printf (psf, "*** Bad bit width %d\n", dwdh.bitwidth) ;
return SFE_DWD_BAND_BIT_WIDTH ;
} ;
if (psf->filelength != dwdh.offset + dwdh.datalen)
{ psf_log_printf (psf, " Data Length : %d (should be %D)\n", dwdh.datalen, psf->filelength - dwdh.offset) ;
dwdh.datalen = (unsigned int) (psf->filelength - dwdh.offset) ;
}
else
psf_log_printf (psf, " Data Length : %d\n", dwdh.datalen) ;
psf_log_printf (psf, " Max Value : %d\n", dwdh.maxval) ;
psf_log_printf (psf, " Frames : %d\n", dwdh.frames) ;
psf_log_printf (psf, " Data Offset : %d\n", dwdh.offset) ;
psf->datalength = dwdh.datalen ;
psf->dataoffset = dwdh.offset ;
psf->endian = SF_ENDIAN_LITTLE ;
psf->sf.samplerate = dwdh.srate ;
psf->sf.channels = dwdh.channels ;
psf->sf.sections = 1 ;
return pcm_init (psf) ;
} /* dwd_read_header */
/*------------------------------------------------------------------------------
*/
#endif
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: a5e1d2a6-a840-4039-a0e7-e1a43eb05a4f
*/

View File

@@ -1,671 +0,0 @@
/*
** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
/*===========================================================================
** Delta Word Variable Width
**
** This decoder and encoder were implemented using information found in this
** document : http://home.swbell.net/rubywand/R011SNDFMTS.TXT
**
** According to the document, the algorithm "was invented 1991 by Magnus
** Lidstrom and is copyright 1993 by NuEdge Development".
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "float_cast.h"
#include "common.h"
typedef struct
{ int dwm_maxsize, bit_width, max_delta, span ;
int samplecount ;
int bit_count, bits, last_delta_width, last_sample ;
struct
{ int index, end ;
unsigned char buffer [256] ;
} b ;
} DWVW_PRIVATE ;
/*============================================================================================
*/
static sf_count_t dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t dwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int dwvw_close (SF_PRIVATE *psf) ;
static int dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;
static int dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count) ;
static int dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len) ;
static void dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits) ;
static void dwvw_read_reset (DWVW_PRIVATE *pdwvw) ;
/*============================================================================================
** DWVW initialisation function.
*/
int
dwvw_init (SF_PRIVATE *psf, int bitwidth)
{ DWVW_PRIVATE *pdwvw ;
if (psf->fdata != NULL)
{ psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
return SFE_INTERNAL ;
} ;
if (bitwidth > 24)
return SFE_DWVW_BAD_BITWIDTH ;
if (psf->mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->fdata = (void*) pdwvw ;
pdwvw->bit_width = bitwidth ;
pdwvw->dwm_maxsize = bitwidth / 2 ;
pdwvw->max_delta = 1 << (bitwidth - 1) ;
pdwvw->span = 1 << bitwidth ;
dwvw_read_reset (pdwvw) ;
if (psf->mode == SFM_READ)
{ psf->read_short = dwvw_read_s ;
psf->read_int = dwvw_read_i ;
psf->read_float = dwvw_read_f ;
psf->read_double = dwvw_read_d ;
} ;
if (psf->mode == SFM_WRITE)
{ psf->write_short = dwvw_write_s ;
psf->write_int = dwvw_write_i ;
psf->write_float = dwvw_write_f ;
psf->write_double = dwvw_write_d ;
} ;
psf->codec_close = dwvw_close ;
psf->seek = dwvw_seek ;
/* FIXME : This is bogus. */
psf->sf.frames = SF_COUNT_MAX ;
psf->datalength = psf->sf.frames ;
/* EMXIF : This is bogus. */
return 0 ;
} /* dwvw_init */
/*--------------------------------------------------------------------------------------------
*/
static int
dwvw_close (SF_PRIVATE *psf)
{ DWVW_PRIVATE *pdwvw ;
if (psf->fdata == NULL)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
if (psf->mode == SFM_WRITE)
{ static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
/* Write 8 zero samples to fully flush output. */
dwvw_encode_data (psf, pdwvw, last_values, 12) ;
/* Write the last buffer worth of data to disk. */
psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
if (psf->write_header)
psf->write_header (psf, SF_TRUE) ;
} ;
return 0 ;
} /* dwvw_close */
static sf_count_t
dwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
{ DWVW_PRIVATE *pdwvw ;
mode = mode ;
if (! psf->fdata)
{ psf->error = SFE_INTERNAL ;
return PSF_SEEK_ERROR ;
} ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
if (offset == 0)
{ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
dwvw_read_reset (pdwvw) ;
return 0 ;
} ;
psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} /* dwvw_seek */
/*==============================================================================
*/
static sf_count_t
dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = iptr [k] >> 16 ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* dwvw_read_s */
static sf_count_t
dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int readcount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
while (len > 0)
{ readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = dwvw_decode_data (psf, pdwvw, ptr, readcount) ;
total += count ;
len -= count ;
if (count != readcount)
break ;
} ;
return total ;
} /* dwvw_read_i */
static sf_count_t
dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * (float) (iptr [k]) ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* dwvw_read_f */
static sf_count_t
dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * (double) (iptr [k]) ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* dwvw_read_d */
static int
dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len)
{ int count ;
int delta_width_modifier, delta_width, delta_negative, delta, sample ;
/* Restore state from last decode call. */
delta_width = pdwvw->last_delta_width ;
sample = pdwvw->last_sample ;
for (count = 0 ; count < len ; count++)
{ /* If bit_count parameter is zero get the delta_width_modifier. */
delta_width_modifier = dwvw_decode_load_bits (psf, pdwvw, -1) ;
/* Check for end of input bit stream. Break loop if end. */
if (delta_width_modifier < 0)
break ;
if (delta_width_modifier && dwvw_decode_load_bits (psf, pdwvw, 1))
delta_width_modifier = - delta_width_modifier ;
/* Calculate the current word width. */
delta_width = (delta_width + delta_width_modifier + pdwvw->bit_width) % pdwvw->bit_width ;
/* Load the delta. */
delta = 0 ;
if (delta_width)
{ delta = dwvw_decode_load_bits (psf, pdwvw, delta_width - 1) | (1 << (delta_width - 1)) ;
delta_negative = dwvw_decode_load_bits (psf, pdwvw, 1) ;
if (delta == pdwvw->max_delta - 1)
delta += dwvw_decode_load_bits (psf, pdwvw, 1) ;
if (delta_negative)
delta = -delta ;
} ;
/* Calculate the sample */
sample += delta ;
if (sample >= pdwvw->max_delta)
sample -= pdwvw->span ;
else if (sample < - pdwvw->max_delta)
sample += pdwvw->span ;
/* Store the sample justifying to the most significant bit. */
ptr [count] = sample << (32 - pdwvw->bit_width) ;
if (pdwvw->b.end == 0 && pdwvw->bit_count == 0)
break ;
} ;
pdwvw->last_delta_width = delta_width ;
pdwvw->last_sample = sample ;
pdwvw->samplecount += count ;
return count ;
} /* dwvw_decode_data */
static int
dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count)
{ int output = 0, get_dwm = SF_FALSE ;
/*
** Depending on the value of parameter bit_count, either get the
** required number of bits (ie bit_count > 0) or the
** delta_width_modifier (otherwise).
*/
if (bit_count < 0)
{ get_dwm = SF_TRUE ;
/* modify bit_count to ensure we have enought bits for finding dwm. */
bit_count = pdwvw->dwm_maxsize ;
} ;
/* Load bits in bit reseviour. */
while (pdwvw->bit_count < bit_count)
{ if (pdwvw->b.index >= pdwvw->b.end)
{ pdwvw->b.end = psf_fread (pdwvw->b.buffer, 1, sizeof (pdwvw->b.buffer), psf) ;
pdwvw->b.index = 0 ;
} ;
/* Check for end of input stream. */
if (bit_count < 8 && pdwvw->b.end == 0)
return -1 ;
pdwvw->bits = (pdwvw->bits << 8) ;
if (pdwvw->b.index < pdwvw->b.end)
{ pdwvw->bits |= pdwvw->b.buffer [pdwvw->b.index] ;
pdwvw->b.index ++ ;
} ;
pdwvw->bit_count += 8 ;
} ;
/* If asked to get bits do so. */
if (! get_dwm)
{ output = (pdwvw->bits >> (pdwvw->bit_count - bit_count)) & ((1 << bit_count) - 1) ;
pdwvw->bit_count -= bit_count ;
return output ;
} ;
/* Otherwise must have been asked to get delta_width_modifier. */
while (output < (pdwvw->dwm_maxsize))
{ pdwvw->bit_count -= 1 ;
if (pdwvw->bits & (1 << pdwvw->bit_count))
break ;
output += 1 ;
} ;
return output ;
} /* dwvw_decode_load_bits */
static void
dwvw_read_reset (DWVW_PRIVATE *pdwvw)
{ pdwvw->samplecount = 0 ;
pdwvw->b.index = 0 ;
pdwvw->b.end = 0 ;
pdwvw->bit_count = 0 ;
pdwvw->bits = 0 ;
pdwvw->last_delta_width = 0 ;
pdwvw->last_sample = 0 ;
} /* dwvw_read_reset */
static void
dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits)
{ int byte ;
/* Shift the bits into the resevoir. */
pdwvw->bits = (pdwvw->bits << new_bits) | (data & ((1 << new_bits) - 1)) ;
pdwvw->bit_count += new_bits ;
/* Transfer bit to buffer. */
while (pdwvw->bit_count >= 8)
{ byte = pdwvw->bits >> (pdwvw->bit_count - 8) ;
pdwvw->bit_count -= 8 ;
pdwvw->b.buffer [pdwvw->b.index] = byte & 0xFF ;
pdwvw->b.index ++ ;
} ;
if (pdwvw->b.index > SIGNED_SIZEOF (pdwvw->b.buffer) - 4)
{ psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
pdwvw->b.index = 0 ;
} ;
return ;
} /* dwvw_encode_store_bits */
#if 0
/* Debigging routine. */
static void
dump_bits (DWVW_PRIVATE *pdwvw)
{ int k, mask ;
for (k = 0 ; k < 10 && k < pdwvw->b.index ; k++)
{ mask = 0x80 ;
while (mask)
{ putchar (mask & pdwvw->b.buffer [k] ? '1' : '0') ;
mask >>= 1 ;
} ;
putchar (' ') ;
}
for (k = pdwvw->bit_count - 1 ; k >= 0 ; k --)
putchar (pdwvw->bits & (1 << k) ? '1' : '0') ;
putchar ('\n') ;
} /* dump_bits */
#endif
#define HIGHEST_BIT(x,count) \
{ int y = x ; \
(count) = 0 ; \
while (y) \
{ (count) ++ ; \
y >>= 1 ; \
} ; \
} ;
static int
dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len)
{ int count ;
int delta_width_modifier, delta, delta_negative, delta_width, extra_bit ;
for (count = 0 ; count < len ; count++)
{ delta = (ptr [count] >> (32 - pdwvw->bit_width)) - pdwvw->last_sample ;
/* Calculate extra_bit if needed. */
extra_bit = -1 ;
delta_negative = 0 ;
if (delta < -pdwvw->max_delta)
delta = pdwvw->max_delta + (delta % pdwvw->max_delta) ;
else if (delta == -pdwvw->max_delta)
{ extra_bit = 1 ;
delta_negative = 1 ;
delta = pdwvw->max_delta - 1 ;
}
else if (delta > pdwvw->max_delta)
{ delta_negative = 1 ;
delta = pdwvw->span - delta ;
delta = abs (delta) ;
}
else if (delta == pdwvw->max_delta)
{ extra_bit = 1 ;
delta = pdwvw->max_delta - 1 ;
}
else if (delta < 0)
{ delta_negative = 1 ;
delta = abs (delta) ;
} ;
if (delta == pdwvw->max_delta - 1 && extra_bit == -1)
extra_bit = 0 ;
/* Find width in bits of delta */
HIGHEST_BIT (delta, delta_width) ;
/* Calculate the delta_width_modifier */
delta_width_modifier = (delta_width - pdwvw->last_delta_width) % pdwvw->bit_width ;
if (delta_width_modifier > pdwvw->dwm_maxsize)
delta_width_modifier -= pdwvw->bit_width ;
if (delta_width_modifier < -pdwvw->dwm_maxsize)
delta_width_modifier += pdwvw->bit_width ;
/* Write delta_width_modifier zeros, followed by terminating '1'. */
dwvw_encode_store_bits (psf, pdwvw, 0, abs (delta_width_modifier)) ;
if (abs (delta_width_modifier) != pdwvw->dwm_maxsize)
dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
/* Write delta_width_modifier sign. */
if (delta_width_modifier < 0)
dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
if (delta_width_modifier > 0)
dwvw_encode_store_bits (psf, pdwvw, 0, 1) ;
/* Write delta and delta sign bit. */
if (delta_width)
{ dwvw_encode_store_bits (psf, pdwvw, delta, abs (delta_width) - 1) ;
dwvw_encode_store_bits (psf, pdwvw, (delta_negative ? 1 : 0), 1) ;
} ;
/* Write extra bit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
if (extra_bit >= 0)
dwvw_encode_store_bits (psf, pdwvw, extra_bit, 1) ;
pdwvw->last_sample = ptr [count] >> (32 - pdwvw->bit_width) ;
pdwvw->last_delta_width = delta_width ;
} ;
pdwvw->samplecount += count ;
return count ;
} /* dwvw_encode_data */
static sf_count_t
dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = ptr [total + k] << 16 ;
count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* dwvw_write_s */
static sf_count_t
dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int writecount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
while (len > 0)
{ writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = dwvw_encode_data (psf, pdwvw, ptr, writecount) ;
total += count ;
len -= count ;
if (count != writecount)
break ;
} ;
return total ;
} /* dwvw_write_i */
static sf_count_t
dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = lrintf (normfact * ptr [total + k]) ;
count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* dwvw_write_f */
static sf_count_t
dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
if (! psf->fdata)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = lrint (normfact * ptr [total + k]) ;
count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* dwvw_write_d */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 1ca09552-b01f-4d7f-9bcf-612f834fe41d
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,961 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#include "float_cast.h"
#if CPU_IS_LITTLE_ENDIAN
#define FLOAT32_READ float32_le_read
#define FLOAT32_WRITE float32_le_write
#elif CPU_IS_BIG_ENDIAN
#define FLOAT32_READ float32_be_read
#define FLOAT32_WRITE float32_be_write
#endif
/*--------------------------------------------------------------------------------------------
** Processor floating point capabilities. float32_get_capability () returns one of the
** latter four values.
*/
enum
{ FLOAT_UNKNOWN = 0x00,
FLOAT_CAN_RW_LE = 0x12,
FLOAT_CAN_RW_BE = 0x23,
FLOAT_BROKEN_LE = 0x34,
FLOAT_BROKEN_BE = 0x45
} ;
/*--------------------------------------------------------------------------------------------
** Prototypes for private functions.
*/
static sf_count_t host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static void float32_peak_update (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx) ;
static sf_count_t replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t replace_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static void bf2f_array (float *buffer, int count) ;
static void f2bf_array (float *buffer, int count) ;
static int float32_get_capability (SF_PRIVATE *psf) ;
/*--------------------------------------------------------------------------------------------
** Exported functions.
*/
int
float32_init (SF_PRIVATE *psf)
{ static int float_caps ;
float_caps = float32_get_capability (psf) ;
psf->blockwidth = sizeof (float) * psf->sf.channels ;
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
psf->float_endswap = SF_FALSE ;
psf->read_short = host_read_f2s ;
psf->read_int = host_read_f2i ;
psf->read_float = host_read_f ;
psf->read_double = host_read_f2d ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
psf->float_endswap = SF_FALSE ;
psf->read_short = host_read_f2s ;
psf->read_int = host_read_f2i ;
psf->read_float = host_read_f ;
psf->read_double = host_read_f2d ;
break ;
case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) :
psf->float_endswap = SF_TRUE ;
psf->read_short = host_read_f2s ;
psf->read_int = host_read_f2i ;
psf->read_float = host_read_f ;
psf->read_double = host_read_f2d ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) :
psf->float_endswap = SF_TRUE ;
psf->read_short = host_read_f2s ;
psf->read_int = host_read_f2i ;
psf->read_float = host_read_f ;
psf->read_double = host_read_f2d ;
break ;
/* When the CPU is not IEEE compatible. */
case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) :
psf->float_endswap = SF_TRUE ;
psf->read_short = replace_read_f2s ;
psf->read_int = replace_read_f2i ;
psf->read_float = replace_read_f ;
psf->read_double = replace_read_f2d ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) :
psf->float_endswap = SF_FALSE ;
psf->read_short = replace_read_f2s ;
psf->read_int = replace_read_f2i ;
psf->read_float = replace_read_f ;
psf->read_double = replace_read_f2d ;
break ;
case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) :
psf->float_endswap = SF_FALSE ;
psf->read_short = replace_read_f2s ;
psf->read_int = replace_read_f2i ;
psf->read_float = replace_read_f ;
psf->read_double = replace_read_f2d ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) :
psf->float_endswap = SF_TRUE ;
psf->read_short = replace_read_f2s ;
psf->read_int = replace_read_f2i ;
psf->read_float = replace_read_f ;
psf->read_double = replace_read_f2d ;
break ;
default : break ;
} ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
psf->float_endswap = SF_FALSE ;
psf->write_short = host_write_s2f ;
psf->write_int = host_write_i2f ;
psf->write_float = host_write_f ;
psf->write_double = host_write_d2f ;
break ;
case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
psf->float_endswap = SF_FALSE ;
psf->write_short = host_write_s2f ;
psf->write_int = host_write_i2f ;
psf->write_float = host_write_f ;
psf->write_double = host_write_d2f ;
break ;
case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) :
psf->float_endswap = SF_TRUE ;
psf->write_short = host_write_s2f ;
psf->write_int = host_write_i2f ;
psf->write_float = host_write_f ;
psf->write_double = host_write_d2f ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) :
psf->float_endswap = SF_TRUE ;
psf->write_short = host_write_s2f ;
psf->write_int = host_write_i2f ;
psf->write_float = host_write_f ;
psf->write_double = host_write_d2f ;
break ;
/* When the CPU is not IEEE compatible. */
case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) :
psf->float_endswap = SF_TRUE ;
psf->write_short = replace_write_s2f ;
psf->write_int = replace_write_i2f ;
psf->write_float = replace_write_f ;
psf->write_double = replace_write_d2f ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) :
psf->float_endswap = SF_FALSE ;
psf->write_short = replace_write_s2f ;
psf->write_int = replace_write_i2f ;
psf->write_float = replace_write_f ;
psf->write_double = replace_write_d2f ;
break ;
case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) :
psf->float_endswap = SF_FALSE ;
psf->write_short = replace_write_s2f ;
psf->write_int = replace_write_i2f ;
psf->write_float = replace_write_f ;
psf->write_double = replace_write_d2f ;
break ;
case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) :
psf->float_endswap = SF_TRUE ;
psf->write_short = replace_write_s2f ;
psf->write_int = replace_write_i2f ;
psf->write_float = replace_write_f ;
psf->write_double = replace_write_d2f ;
break ;
default : break ;
} ;
} ;
if (psf->filelength > psf->dataoffset)
{ psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
psf->filelength - psf->dataoffset ;
}
else
psf->datalength = 0 ;
psf->sf.frames = psf->datalength / psf->blockwidth ;
return 0 ;
} /* float32_init */
float
float32_be_read (unsigned char *cptr)
{ int exponent, mantissa, negative ;
float fvalue ;
negative = cptr [0] & 0x80 ;
exponent = ((cptr [0] & 0x7F) << 1) | ((cptr [1] & 0x80) ? 1 : 0) ;
mantissa = ((cptr [1] & 0x7F) << 16) | (cptr [2] << 8) | (cptr [3]) ;
if (! (exponent || mantissa))
return 0.0 ;
mantissa |= 0x800000 ;
exponent = exponent ? exponent - 127 : 0 ;
fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;
if (negative)
fvalue *= -1 ;
if (exponent > 0)
fvalue *= (1 << exponent) ;
else if (exponent < 0)
fvalue /= (1 << abs (exponent)) ;
return fvalue ;
} /* float32_be_read */
float
float32_le_read (unsigned char *cptr)
{ int exponent, mantissa, negative ;
float fvalue ;
negative = cptr [3] & 0x80 ;
exponent = ((cptr [3] & 0x7F) << 1) | ((cptr [2] & 0x80) ? 1 : 0) ;
mantissa = ((cptr [2] & 0x7F) << 16) | (cptr [1] << 8) | (cptr [0]) ;
if (! (exponent || mantissa))
return 0.0 ;
mantissa |= 0x800000 ;
exponent = exponent ? exponent - 127 : 0 ;
fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;
if (negative)
fvalue *= -1 ;
if (exponent > 0)
fvalue *= (1 << exponent) ;
else if (exponent < 0)
fvalue /= (1 << abs (exponent)) ;
return fvalue ;
} /* float32_le_read */
void
float32_le_write (float in, unsigned char *out)
{ int exponent, mantissa, negative = 0 ;
memset (out, 0, sizeof (int)) ;
if (fabs (in) < 1e-30)
return ;
if (in < 0.0)
{ in *= -1.0 ;
negative = 1 ;
} ;
in = frexp (in, &exponent) ;
exponent += 126 ;
in *= (float) 0x1000000 ;
mantissa = (((int) in) & 0x7FFFFF) ;
if (negative)
out [3] |= 0x80 ;
if (exponent & 0x01)
out [2] |= 0x80 ;
out [0] = mantissa & 0xFF ;
out [1] = (mantissa >> 8) & 0xFF ;
out [2] |= (mantissa >> 16) & 0x7F ;
out [3] |= (exponent >> 1) & 0x7F ;
return ;
} /* float32_le_write */
void
float32_be_write (float in, unsigned char *out)
{ int exponent, mantissa, negative = 0 ;
memset (out, 0, sizeof (int)) ;
if (fabs (in) < 1e-30)
return ;
if (in < 0.0)
{ in *= -1.0 ;
negative = 1 ;
} ;
in = frexp (in, &exponent) ;
exponent += 126 ;
in *= (float) 0x1000000 ;
mantissa = (((int) in) & 0x7FFFFF) ;
if (negative)
out [0] |= 0x80 ;
if (exponent & 0x01)
out [1] |= 0x80 ;
out [3] = mantissa & 0xFF ;
out [2] = (mantissa >> 8) & 0xFF ;
out [1] |= (mantissa >> 16) & 0x7F ;
out [0] |= (exponent >> 1) & 0x7F ;
return ;
} /* float32_be_write */
/*==============================================================================================
** Private functions.
*/
static void
float32_peak_update (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx)
{ int chan ;
int k, position ;
float fmaxval ;
for (chan = 0 ; chan < psf->sf.channels ; chan++)
{ fmaxval = fabs (buffer [chan]) ;
position = 0 ;
for (k = chan ; k < count ; k += psf->sf.channels)
if (fmaxval < fabs (buffer [k]))
{ fmaxval = fabs (buffer [k]) ;
position = k ;
} ;
if (fmaxval > psf->peak_info->peaks [chan].value)
{ psf->peak_info->peaks [chan].value = fmaxval ;
psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ;
} ;
} ;
return ;
} /* float32_peak_update */
static int
float32_get_capability (SF_PRIVATE *psf)
{ union
{ float f ;
int i ;
unsigned char c [4] ;
} data ;
data.f = (float) 1.23456789 ; /* Some abitrary value. */
if (! psf->ieee_replace)
{ /* If this test is true ints and floats are compatible and little endian. */
if (data.c [0] == 0x52 && data.c [1] == 0x06 && data.c [2] == 0x9e && data.c [3] == 0x3f)
return FLOAT_CAN_RW_LE ;
/* If this test is true ints and floats are compatible and big endian. */
if (data.c [3] == 0x52 && data.c [2] == 0x06 && data.c [1] == 0x9e && data.c [0] == 0x3f)
return FLOAT_CAN_RW_BE ;
} ;
/* Floats are broken. Don't expect reading or writing to be fast. */
psf_log_printf (psf, "Using IEEE replacement code for float.\n") ;
return (CPU_IS_LITTLE_ENDIAN) ? FLOAT_BROKEN_LE : FLOAT_BROKEN_BE ;
} /* float32_get_capability */
/*=======================================================================================
*/
static inline void
f2s_array (const float *src, int count, short *dest, float scale)
{ while (--count >= 0)
{ dest [count] = lrintf (scale * src [count]) ;
} ;
} /* f2s_array */
static inline void
f2i_array (const float *src, int count, int *dest, float scale)
{ while (--count >= 0)
{ dest [count] = lrintf (scale * src [count]) ;
} ;
} /* f2i_array */
static inline void
f2d_array (const float *src, int count, double *dest)
{ while (--count >= 0)
{ dest [count] = src [count] ;
} ;
} /* f2d_array */
static inline void
s2f_array (const short *src, float *dest, int count)
{ while (--count >= 0)
{ dest [count] = src [count] ;
} ;
} /* s2f_array */
static inline void
i2f_array (const int *src, float *dest, int count)
{ while (--count >= 0)
{ dest [count] = src [count] ;
} ;
} /* i2f_array */
static inline void
d2f_array (const double *src, float *dest, int count)
{ while (--count >= 0)
{ dest [count] = src [count] ;
} ;
} /* d2f_array */
/*----------------------------------------------------------------------------------------------
*/
static sf_count_t
host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
/* Fix me : Need lef2s_array */
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* host_read_f2s */
static sf_count_t
host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
f2i_array (psf->u.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* host_read_f2i */
static sf_count_t
host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
if (psf->float_endswap != SF_TRUE)
return psf_fread (ptr, sizeof (float), len, psf) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
endswap_int_copy ((int*) (ptr + total), psf->u.ibuf, readcount) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* host_read_f */
static sf_count_t
host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
/* Fix me : Need lef2d_array */
f2d_array (psf->u.fbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* host_read_f2d */
static sf_count_t
host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* host_write_s2f */
static sf_count_t
host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* host_write_i2f */
static sf_count_t
host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
if (psf->peak_info)
float32_peak_update (psf, ptr, len, 0) ;
if (psf->float_endswap != SF_TRUE)
return psf_fwrite (ptr, sizeof (float), len, psf) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
endswap_int_copy (psf->u.ibuf, (const int*) (ptr + total), bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* host_write_f */
static sf_count_t
host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* host_write_d2f */
/*=======================================================================================
*/
static sf_count_t
replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* replace_read_f2s */
static sf_count_t
replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
f2i_array (psf->u.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* replace_read_f2i */
static sf_count_t
replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
/* FIX THIS */
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
memcpy (ptr + total, psf->u.fbuf, bufferlen * sizeof (float)) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* replace_read_f */
static sf_count_t
replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
f2d_array (psf->u.fbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
len -= readcount ;
} ;
return total ;
} /* replace_read_f2d */
static sf_count_t
replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* replace_write_s2f */
static sf_count_t
replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* replace_write_i2f */
static sf_count_t
replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
/* FIX THIS */
if (psf->peak_info)
float32_peak_update (psf, ptr, len, 0) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
memcpy (psf->u.fbuf, ptr + total, bufferlen * sizeof (float)) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* replace_write_f */
static sf_count_t
replace_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
if (psf->float_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
len -= writecount ;
} ;
return total ;
} /* replace_write_d2f */
/*----------------------------------------------------------------------------------------------
*/
static void
bf2f_array (float *buffer, int count)
{ while (--count >= 0)
{ buffer [count] = FLOAT32_READ ((unsigned char *) (buffer + count)) ;
} ;
} /* bf2f_array */
static void
f2bf_array (float *buffer, int count)
{ while (--count >= 0)
{ FLOAT32_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
} ;
} /* f2bf_array */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: b6c34917-488c-4145-9648-f4371fc4c889
*/

View File

@@ -1,262 +0,0 @@
/*
** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
/* Version 1.4 */
#ifndef FLOAT_CAST_HEADER
#define FLOAT_CAST_HEADER
/*============================================================================
** On Intel Pentium processors (especially PIII and probably P4), converting
** from float to int is very slow. To meet the C specs, the code produced by
** most C compilers targeting Pentium needs to change the FPU rounding mode
** before the float to int conversion is performed.
**
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
** is this flushing of the pipeline which is so slow.
**
** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
** llrint and llrintf which fix this problem as a side effect.
**
** On Unix-like systems, the configure process should have detected the
** presence of these functions. If they weren't found we have to replace them
** here with a standard C cast.
*/
/*
** The C99 prototypes for lrint and lrintf are as follows:
**
** long int lrintf (float x) ;
** long int lrint (double x) ;
*/
#include "sfconfig.h"
/*
** The presence of the required functions are detected during the configure
** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
** the sfconfig.h file.
*/
#define HAVE_LRINT_REPLACEMENT 0
#if (HAVE_LRINT && HAVE_LRINTF)
/*
** These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to
** engage them. If optimisation is enabled, these functions will be
** inlined. With optimisation switched off, you have to link in the
** maths library using -lm.
*/
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#elif (defined (__CYGWIN__))
#include <math.h>
#undef HAVE_LRINT_REPLACEMENT
#define HAVE_LRINT_REPLACEMENT 1
#undef lrint
#undef lrintf
#define lrint double2int
#define lrintf float2int
/*
** The native CYGWIN lrint and lrintf functions are buggy:
** http://sourceware.org/ml/cygwin/2005-06/msg00153.html
** http://sourceware.org/ml/cygwin/2005-09/msg00047.html
** and slow.
** These functions (pulled from the Public Domain MinGW math.h header)
** replace the native versions.
*/
static inline long double2int (double in)
{ long retval ;
__asm__ __volatile__
( "fistpl %0"
: "=m" (retval)
: "t" (in)
: "st"
) ;
return retval ;
} /* double2int */
static inline long float2int (float in)
{ long retval ;
__asm__ __volatile__
( "fistpl %0"
: "=m" (retval)
: "t" (in)
: "st"
) ;
return retval ;
} /* float2int */
#elif (defined (WIN32) || defined (_WIN32))
#undef HAVE_LRINT_REPLACEMENT
#define HAVE_LRINT_REPLACEMENT 1
#include <math.h>
/*
** Win32 doesn't seem to have these functions.
** Therefore implement inline versions of these functions here.
*/
__inline long int
lrint (double flt)
{ int intgr ;
_asm
{ fld flt
fistp intgr
} ;
return intgr ;
}
__inline long int
lrintf (float flt)
{ int intgr ;
_asm
{ fld flt
fistp intgr
} ;
return intgr ;
}
#elif (defined (__MWERKS__) && defined (macintosh))
/* This MacOS 9 solution was provided by Stephane Letz */
#undef HAVE_LRINT_REPLACEMENT
#define HAVE_LRINT_REPLACEMENT 1
#include <math.h>
#undef lrint
#undef lrintf
#define lrint double2int
#define lrintf float2int
inline int
float2int (register float in)
{ long res [2] ;
asm
{ fctiw in, in
stfd in, res
}
return res [1] ;
} /* float2int */
inline int
double2int (register double in)
{ long res [2] ;
asm
{ fctiw in, in
stfd in, res
}
return res [1] ;
} /* double2int */
#elif (defined (__MACH__) && defined (__APPLE__))
/* For Apple MacOSX. */
#undef HAVE_LRINT_REPLACEMENT
#define HAVE_LRINT_REPLACEMENT 1
#include <math.h>
#undef lrint
#undef lrintf
#define lrint double2int
#define lrintf float2int
inline static long
float2int (register float in)
{ int res [2] ;
__asm__ __volatile__
( "fctiw %1, %1\n\t"
"stfd %1, %0"
: "=m" (res) /* Output */
: "f" (in) /* Input */
: "memory"
) ;
return res [1] ;
} /* lrintf */
inline static long
double2int (register double in)
{ int res [2] ;
__asm__ __volatile__
( "fctiw %1, %1\n\t"
"stfd %1, %0"
: "=m" (res) /* Output */
: "f" (in) /* Input */
: "memory"
) ;
return res [1] ;
} /* lrint */
#else
#ifndef __sgi
#warning "Don't have the functions lrint() and lrintf()."
#warning "Replacing these functions with a standard C cast."
#endif
#include <math.h>
#define lrint(dbl) ((long) (dbl))
#define lrintf(flt) ((long) (flt))
#endif
#endif /* FLOAT_CAST_HEADER */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 42db1693-ff61-4051-bac1-e4d24c4e30b7
*/

View File

@@ -1,615 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "float_cast.h"
#include "common.h"
#include "G72x/g72x.h"
/* This struct is private to the G72x code. */
struct g72x_state ;
typedef struct g72x_state G72x_STATE ;
typedef struct
{ /* Private data. Don't mess with it. */
struct g72x_state * private ;
/* Public data. Read only. */
int blocksize, samplesperblock, bytesperblock ;
/* Public data. Read and write. */
int blocks_total, block_curr, sample_curr ;
unsigned char block [G72x_BLOCK_SIZE] ;
short samples [G72x_BLOCK_SIZE] ;
} G72x_PRIVATE ;
static int psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
static int psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
static sf_count_t g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int g72x_close (SF_PRIVATE *psf) ;
/*============================================================================================
** WAV G721 Reader initialisation function.
*/
int
g72x_init (SF_PRIVATE * psf)
{ G72x_PRIVATE *pg72x ;
int bitspersample, bytesperblock, codec ;
if (psf->fdata != NULL)
{ psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
return SFE_INTERNAL ;
} ;
psf->sf.seekable = SF_FALSE ;
if (psf->sf.channels != 1)
return SFE_G72X_NOT_MONO ;
if ((pg72x = calloc (1, sizeof (G72x_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->fdata = (void*) pg72x ;
pg72x->block_curr = 0 ;
pg72x->sample_curr = 0 ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
{ case SF_FORMAT_G721_32 :
codec = G721_32_BITS_PER_SAMPLE ;
bytesperblock = G721_32_BYTES_PER_BLOCK ;
bitspersample = G721_32_BITS_PER_SAMPLE ;
break ;
case SF_FORMAT_G723_24:
codec = G723_24_BITS_PER_SAMPLE ;
bytesperblock = G723_24_BYTES_PER_BLOCK ;
bitspersample = G723_24_BITS_PER_SAMPLE ;
break ;
case SF_FORMAT_G723_40:
codec = G723_40_BITS_PER_SAMPLE ;
bytesperblock = G723_40_BYTES_PER_BLOCK ;
bitspersample = G723_40_BITS_PER_SAMPLE ;
break ;
default : return SFE_UNIMPLEMENTED ;
} ;
psf->blockwidth = psf->bytewidth = 1 ;
psf->filelength = psf_get_filelen (psf) ;
if (psf->filelength < psf->dataoffset)
psf->filelength = psf->dataoffset ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend > 0)
psf->datalength -= psf->filelength - psf->dataend ;
if (psf->mode == SFM_READ)
{ pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
pg72x->bytesperblock = bytesperblock ;
psf->read_short = g72x_read_s ;
psf->read_int = g72x_read_i ;
psf->read_float = g72x_read_f ;
psf->read_double = g72x_read_d ;
psf->seek = g72x_seek ;
if (psf->datalength % pg72x->blocksize)
{ psf_log_printf (psf, "*** Odd psf->datalength (%D) should be a multiple of %d\n", psf->datalength, pg72x->blocksize) ;
pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
}
else
pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
psf->sf.frames = pg72x->blocks_total * pg72x->samplesperblock ;
psf_g72x_decode_block (psf, pg72x) ;
}
else if (psf->mode == SFM_WRITE)
{ pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
pg72x->bytesperblock = bytesperblock ;
psf->write_short = g72x_write_s ;
psf->write_int = g72x_write_i ;
psf->write_float = g72x_write_f ;
psf->write_double = g72x_write_d ;
if (psf->datalength % pg72x->blocksize)
pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
else
pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
if (psf->datalength > 0)
psf->sf.frames = (8 * psf->datalength) / bitspersample ;
if ((psf->sf.frames * bitspersample) / 8 != psf->datalength)
psf_log_printf (psf, "*** Warning : weird psf->datalength.\n") ;
} ;
psf->codec_close = g72x_close ;
return 0 ;
} /* g72x_init */
/*============================================================================================
** G721 Read Functions.
*/
static int
psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
{ int k ;
pg72x->block_curr ++ ;
pg72x->sample_curr = 0 ;
if (pg72x->block_curr > pg72x->blocks_total)
{ memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
return 1 ;
} ;
if ((k = psf_fread (pg72x->block, 1, pg72x->bytesperblock, psf)) != pg72x->bytesperblock)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pg72x->bytesperblock) ;
pg72x->blocksize = k ;
g72x_decode_block (pg72x->private, pg72x->block, pg72x->samples) ;
return 1 ;
} /* psf_g72x_decode_block */
static int
g72x_read_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ if (pg72x->block_curr > pg72x->blocks_total)
{ memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
return total ;
} ;
if (pg72x->sample_curr >= pg72x->samplesperblock)
psf_g72x_decode_block (psf, pg72x) ;
count = pg72x->samplesperblock - pg72x->sample_curr ;
count = (len - indx > count) ? count : len - indx ;
memcpy (&(ptr [indx]), &(pg72x->samples [pg72x->sample_curr]), count * sizeof (short)) ;
indx += count ;
pg72x->sample_curr += count ;
total = indx ;
} ;
return total ;
} /* g72x_read_block */
static sf_count_t
g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
int readcount, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
while (len > 0)
{ readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = g72x_read_block (psf, pg72x, ptr, readcount) ;
total += count ;
len -= count ;
if (count != readcount)
break ;
} ;
return total ;
} /* g72x_read_s */
static sf_count_t
g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = g72x_read_block (psf, pg72x, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = sptr [k] << 16 ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* g72x_read_i */
static sf_count_t
g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = g72x_read_block (psf, pg72x, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * sptr [k] ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* g72x_read_f */
static sf_count_t
g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = g72x_read_block (psf, pg72x, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * (double) (sptr [k]) ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* g72x_read_d */
static sf_count_t
g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
{
/* Prevent compiler warnings. */
mode ++ ;
offset ++ ;
psf_log_printf (psf, "seek unsupported\n") ;
/* No simple solution. To do properly, would need to seek
** to start of file and decode everything up to seek position.
** Maybe implement SEEK_SET to 0 only?
*/
return 0 ;
/*
** G72x_PRIVATE *pg72x ;
** int newblock, newsample, sample_curr ;
**
** if (psf->fdata == NULL)
** return 0 ;
** pg72x = (G72x_PRIVATE*) psf->fdata ;
**
** if (! (psf->datalength && psf->dataoffset))
** { psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
**
** sample_curr = (8 * psf->datalength) / G721_32_BITS_PER_SAMPLE ;
**
** switch (whence)
** { case SEEK_SET :
** if (offset < 0 || offset > sample_curr)
** { psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
** newblock = offset / pg72x->samplesperblock ;
** newsample = offset % pg72x->samplesperblock ;
** break ;
**
** case SEEK_CUR :
** if (psf->current + offset < 0 || psf->current + offset > sample_curr)
** { psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
** newblock = (8 * (psf->current + offset)) / pg72x->samplesperblock ;
** newsample = (8 * (psf->current + offset)) % pg72x->samplesperblock ;
** break ;
**
** case SEEK_END :
** if (offset > 0 || sample_curr + offset < 0)
** { psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
** newblock = (sample_curr + offset) / pg72x->samplesperblock ;
** newsample = (sample_curr + offset) % pg72x->samplesperblock ;
** break ;
**
** default :
** psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
**
** if (psf->mode == SFM_READ)
** { psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
** pg72x->block_curr = newblock ;
** psf_g72x_decode_block (psf, pg72x) ;
** pg72x->sample_curr = newsample ;
** }
** else
** { /+* What to do about write??? *+/
** psf->error = SFE_BAD_SEEK ;
** return PSF_SEEK_ERROR ;
** } ;
**
** psf->current = newblock * pg72x->samplesperblock + newsample ;
** return psf->current ;
**
*/
} /* g72x_seek */
/*==========================================================================================
** G72x Write Functions.
*/
static int
psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
{ int k ;
/* Encode the samples. */
g72x_encode_block (pg72x->private, pg72x->samples, pg72x->block) ;
/* Write the block to disk. */
if ((k = psf_fwrite (pg72x->block, 1, pg72x->blocksize, psf)) != pg72x->blocksize)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pg72x->blocksize) ;
pg72x->sample_curr = 0 ;
pg72x->block_curr ++ ;
/* Set samples to zero for next block. */
memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
return 1 ;
} /* psf_g72x_encode_block */
static int
g72x_write_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, const short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ count = pg72x->samplesperblock - pg72x->sample_curr ;
if (count > len - indx)
count = len - indx ;
memcpy (&(pg72x->samples [pg72x->sample_curr]), &(ptr [indx]), count * sizeof (short)) ;
indx += count ;
pg72x->sample_curr += count ;
total = indx ;
if (pg72x->sample_curr >= pg72x->samplesperblock)
psf_g72x_encode_block (psf, pg72x) ;
} ;
return total ;
} /* g72x_write_block */
static sf_count_t
g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
int writecount, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
while (len > 0)
{ writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = g72x_write_block (psf, pg72x, ptr, writecount) ;
total += count ;
len -= count ;
if (count != writecount)
break ;
} ;
return total ;
} /* g72x_write_s */
static sf_count_t
g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = ptr [total + k] >> 16 ;
count = g72x_write_block (psf, pg72x, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* g72x_write_i */
static sf_count_t
g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrintf (normfact * ptr [total + k]) ;
count = g72x_write_block (psf, pg72x, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* g72x_write_f */
static sf_count_t
g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
if (psf->fdata == NULL)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrint (normfact * ptr [total + k]) ;
count = g72x_write_block (psf, pg72x, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* g72x_write_d */
static int
g72x_close (SF_PRIVATE *psf)
{ G72x_PRIVATE *pg72x ;
pg72x = (G72x_PRIVATE*) psf->fdata ;
if (psf->mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
if (pg72x->sample_curr && pg72x->sample_curr < G72x_BLOCK_SIZE)
psf_g72x_encode_block (psf, pg72x) ;
if (psf->write_header)
psf->write_header (psf, SF_FALSE) ;
} ;
/* Only free the pointer allocated by g72x_(reader|writer)_init. */
free (pg72x->private) ;
return 0 ;
} /* g72x_close */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 3cc5439e-7247-486b-b2e6-11a4affa5744
*/

View File

@@ -1,628 +0,0 @@
/*
** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "float_cast.h"
#include "common.h"
#include "wav_w64.h"
#include "GSM610/gsm.h"
#define GSM610_BLOCKSIZE 33
#define GSM610_SAMPLES 160
typedef struct gsm610_tag
{ int blocks ;
int blockcount, samplecount ;
int samplesperblock, blocksize ;
int (*decode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
int (*encode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
short samples [WAV_W64_GSM610_SAMPLES] ;
unsigned char block [WAV_W64_GSM610_BLOCKSIZE] ;
/* Damn I hate typedef-ed pointers; yes, gsm is a pointer type. */
gsm gsm_data ;
} GSM610_PRIVATE ;
static sf_count_t gsm610_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static int gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;
static int gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len) ;
static int gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
static int gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
static int gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
static int gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
static sf_count_t gsm610_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int gsm610_close (SF_PRIVATE *psf) ;
/*============================================================================================
** WAV GSM610 initialisation function.
*/
int
gsm610_init (SF_PRIVATE *psf)
{ GSM610_PRIVATE *pgsm610 ;
int true_flag = 1 ;
if (psf->fdata != NULL)
{ psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
psf->sf.seekable = SF_FALSE ;
if ((pgsm610 = calloc (1, sizeof (GSM610_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->fdata = (void*) pgsm610 ;
memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
/*============================================================
Need separate gsm_data structs for encode and decode.
============================================================*/
if ((pgsm610->gsm_data = gsm_create ()) == NULL)
return SFE_MALLOC_FAILED ;
switch (psf->sf.format & SF_FORMAT_TYPEMASK)
{ case SF_FORMAT_WAV :
case SF_FORMAT_WAVEX :
case SF_FORMAT_W64 :
gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
pgsm610->encode_block = gsm610_wav_encode_block ;
pgsm610->decode_block = gsm610_wav_decode_block ;
pgsm610->samplesperblock = WAV_W64_GSM610_SAMPLES ;
pgsm610->blocksize = WAV_W64_GSM610_BLOCKSIZE ;
break ;
case SF_FORMAT_AIFF :
case SF_FORMAT_RAW :
pgsm610->encode_block = gsm610_encode_block ;
pgsm610->decode_block = gsm610_decode_block ;
pgsm610->samplesperblock = GSM610_SAMPLES ;
pgsm610->blocksize = GSM610_BLOCKSIZE ;
break ;
default :
return SFE_INTERNAL ;
break ;
} ;
if (psf->mode == SFM_READ)
{ if (psf->datalength % pgsm610->blocksize == 0)
pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
else if (psf->datalength % pgsm610->blocksize == 1 && pgsm610->blocksize == GSM610_BLOCKSIZE)
{ /*
** Weird AIFF specific case.
** AIFF chunks must be at an odd offset from the start of file and
** GSM610_BLOCKSIZE is odd which can result in an odd length SSND
** chunk. The SSND chunk then gets padded on write which means that
** when it is read the datalength is too big by 1.
*/
pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
}
else
{ psf_log_printf (psf, "*** Warning : data chunk seems to be truncated.\n") ;
pgsm610->blocks = psf->datalength / pgsm610->blocksize + 1 ;
} ;
psf->sf.frames = pgsm610->samplesperblock * pgsm610->blocks ;
pgsm610->decode_block (psf, pgsm610) ; /* Read first block. */
psf->read_short = gsm610_read_s ;
psf->read_int = gsm610_read_i ;
psf->read_float = gsm610_read_f ;
psf->read_double = gsm610_read_d ;
} ;
if (psf->mode == SFM_WRITE)
{ pgsm610->blockcount = 0 ;
pgsm610->samplecount = 0 ;
psf->write_short = gsm610_write_s ;
psf->write_int = gsm610_write_i ;
psf->write_float = gsm610_write_f ;
psf->write_double = gsm610_write_d ;
} ;
psf->codec_close = gsm610_close ;
psf->seek = gsm610_seek ;
psf->filelength = psf_get_filelen (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
return 0 ;
} /* gsm610_init */
/*============================================================================================
** GSM 6.10 Read Functions.
*/
static int
gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
{ int k ;
pgsm610->blockcount ++ ;
pgsm610->samplecount = 0 ;
if (pgsm610->blockcount > pgsm610->blocks)
{ memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
return 1 ;
} ;
if ((k = psf_fread (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, WAV_W64_GSM610_BLOCKSIZE) ;
if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
{ psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;
return 0 ;
} ;
if (gsm_decode (pgsm610->gsm_data, pgsm610->block + (WAV_W64_GSM610_BLOCKSIZE + 1) / 2, pgsm610->samples + WAV_W64_GSM610_SAMPLES / 2) < 0)
{ psf_log_printf (psf, "Error from gsm_decode() on frame : %d.5\n", pgsm610->blockcount) ;
return 0 ;
} ;
return 1 ;
} /* gsm610_wav_decode_block */
static int
gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
{ int k ;
pgsm610->blockcount ++ ;
pgsm610->samplecount = 0 ;
if (pgsm610->blockcount > pgsm610->blocks)
{ memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
return 1 ;
} ;
if ((k = psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
{ psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;
return 0 ;
} ;
return 1 ;
} /* gsm610_decode_block */
static int
gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= pgsm610->samplesperblock)
{ memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
return total ;
} ;
if (pgsm610->samplecount >= pgsm610->samplesperblock)
pgsm610->decode_block (psf, pgsm610) ;
count = pgsm610->samplesperblock - pgsm610->samplecount ;
count = (len - indx > count) ? count : len - indx ;
memcpy (&(ptr [indx]), &(pgsm610->samples [pgsm610->samplecount]), count * sizeof (short)) ;
indx += count ;
pgsm610->samplecount += count ;
total = indx ;
} ;
return total ;
} /* gsm610_read_block */
static sf_count_t
gsm610_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
int readcount, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
while (len > 0)
{ readcount = (len > 0x10000000) ? 0x1000000 : (int) len ;
count = gsm610_read_block (psf, pgsm610, ptr, readcount) ;
total += count ;
len -= count ;
if (count != readcount)
break ;
} ;
return total ;
} /* gsm610_read_s */
static sf_count_t
gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = sptr [k] << 16 ;
total += count ;
len -= readcount ;
} ;
return total ;
} /* gsm610_read_i */
static sf_count_t
gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * sptr [k] ;
total += count ;
len -= readcount ;
} ;
return total ;
} /* gsm610_read_f */
static sf_count_t
gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * sptr [k] ;
total += count ;
len -= readcount ;
} ;
return total ;
} /* gsm610_read_d */
static sf_count_t
gsm610_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
{ GSM610_PRIVATE *pgsm610 ;
int newblock, newsample ;
mode = mode ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
if (psf->dataoffset < 0)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
if (offset == 0)
{ int true_flag = 1 ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
pgsm610->blockcount = 0 ;
gsm_init (pgsm610->gsm_data) ;
if ((psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV ||
(psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_W64)
gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
pgsm610->decode_block (psf, pgsm610) ;
pgsm610->samplecount = 0 ;
return 0 ;
} ;
if (offset < 0 || offset > pgsm610->blocks * pgsm610->samplesperblock)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
newblock = offset / pgsm610->samplesperblock ;
newsample = offset % pgsm610->samplesperblock ;
if (psf->mode == SFM_READ)
{ if (psf->read_current != newblock * pgsm610->samplesperblock + newsample)
{ psf_fseek (psf, psf->dataoffset + newblock * pgsm610->samplesperblock, SEEK_SET) ;
pgsm610->blockcount = newblock ;
pgsm610->decode_block (psf, pgsm610) ;
pgsm610->samplecount = newsample ;
} ;
return newblock * pgsm610->samplesperblock + newsample ;
} ;
/* What to do about write??? */
psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} /* gsm610_seek */
/*==========================================================================================
** GSM 6.10 Write Functions.
*/
static int
gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
{ int k ;
/* Encode the samples. */
gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
/* Write the block to disk. */
if ((k = psf_fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
pgsm610->samplecount = 0 ;
pgsm610->blockcount ++ ;
/* Set samples to zero for next block. */
memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
return 1 ;
} /* gsm610_encode_block */
static int
gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
{ int k ;
/* Encode the samples. */
gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAV_W64_GSM610_SAMPLES/2, pgsm610->block+WAV_W64_GSM610_BLOCKSIZE/2) ;
/* Write the block to disk. */
if ((k = psf_fwrite (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, WAV_W64_GSM610_BLOCKSIZE) ;
pgsm610->samplecount = 0 ;
pgsm610->blockcount ++ ;
/* Set samples to zero for next block. */
memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
return 1 ;
} /* gsm610_wav_encode_block */
static int
gsm610_write_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ count = pgsm610->samplesperblock - pgsm610->samplecount ;
if (count > len - indx)
count = len - indx ;
memcpy (&(pgsm610->samples [pgsm610->samplecount]), &(ptr [indx]), count * sizeof (short)) ;
indx += count ;
pgsm610->samplecount += count ;
total = indx ;
if (pgsm610->samplecount >= pgsm610->samplesperblock)
pgsm610->encode_block (psf, pgsm610) ;
} ;
return total ;
} /* gsm610_write_block */
static sf_count_t
gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
int writecount, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
while (len > 0)
{ writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = gsm610_write_block (psf, pgsm610, ptr, writecount) ;
total += count ;
len -= count ;
if (count != writecount)
break ;
} ;
return total ;
} /* gsm610_write_s */
static sf_count_t
gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = ptr [total + k] >> 16 ;
count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
total += count ;
len -= writecount ;
} ;
return total ;
} /* gsm610_write_i */
static sf_count_t
gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrintf (normfact * ptr [total + k]) ;
count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
total += count ;
len -= writecount ;
} ;
return total ;
} /* gsm610_write_f */
static sf_count_t
gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrint (normfact * ptr [total + k]) ;
count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
total += count ;
len -= writecount ;
} ;
return total ;
} /* gsm610_write_d */
static int
gsm610_close (SF_PRIVATE *psf)
{ GSM610_PRIVATE *pgsm610 ;
if (psf->fdata == NULL)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
if (psf->mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
if (pgsm610->samplecount && pgsm610->samplecount < pgsm610->samplesperblock)
pgsm610->encode_block (psf, pgsm610) ;
} ;
if (pgsm610->gsm_data)
gsm_destroy (pgsm610->gsm_data) ;
return 0 ;
} /* gsm610_close */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 8575187d-af4f-4acf-b9dd-6ff705628345
*/

View File

@@ -1,225 +0,0 @@
/*
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
#define SFE_HTK_BAD_FILE_LEN 1666
#define SFE_HTK_NOT_WAVEFORM 1667
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int htk_close (SF_PRIVATE *psf) ;
static int htk_write_header (SF_PRIVATE *psf, int calc_length) ;
static int htk_read_header (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
htk_open (SF_PRIVATE *psf)
{ int subformat ;
int error = 0 ;
if (psf->is_pipe)
return SFE_HTK_NO_PIPE ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = htk_read_header (psf)))
return error ;
} ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_HTK)
return SFE_BAD_OPEN_FORMAT ;
psf->endian = SF_ENDIAN_BIG ;
if (htk_write_header (psf, SF_FALSE))
return psf->error ;
psf->write_header = htk_write_header ;
} ;
psf->container_close = htk_close ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
switch (subformat)
{ case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
error = pcm_init (psf) ;
break ;
default : break ;
} ;
return error ;
} /* htk_open */
/*------------------------------------------------------------------------------
*/
static int
htk_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
htk_write_header (psf, SF_TRUE) ;
return 0 ;
} /* htk_close */
static int
htk_write_header (SF_PRIVATE *psf, int calc_length)
{ sf_count_t current ;
int sample_count, sample_period ;
current = psf_ftell (psf) ;
if (calc_length)
psf->filelength = psf_get_filelen (psf) ;
/* Reset the current header length to zero. */
psf->header [0] = 0 ;
psf->headindex = 0 ;
psf_fseek (psf, 0, SEEK_SET) ;
if (psf->filelength > 12)
sample_count = (psf->filelength - 12) / 2 ;
else
sample_count = 0 ;
sample_period = 10000000 / psf->sf.samplerate ;
psf_binheader_writef (psf, "E444", sample_count, sample_period, 0x20000) ;
/* Header construction complete so write it out. */
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
psf->dataoffset = psf->headindex ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return psf->error ;
} /* htk_write_header */
/*
** Found the following info in a comment block within Bill Schottstaedt's
** sndlib library.
**
** HTK format files consist of a contiguous sequence of samples preceded by a
** header. Each sample is a vector of either 2-byte integers or 4-byte floats.
** 2-byte integers are used for compressed forms as described below and for
** vector quantised data as described later in section 5.11. HTK format data
** files can also be used to store speech waveforms as described in section 5.8.
**
** The HTK file format header is 12 bytes long and contains the following data
** nSamples -- number of samples in file (4-byte integer)
** sampPeriod -- sample period in 100ns units (4-byte integer)
** sampSize -- number of bytes per sample (2-byte integer)
** parmKind -- a code indicating the sample kind (2-byte integer)
**
** The parameter kind consists of a 6 bit code representing the basic
** parameter kind plus additional bits for each of the possible qualifiers.
** The basic parameter kind codes are
**
** 0 WAVEFORM sampled waveform
** 1 LPC linear prediction filter coefficients
** 2 LPREFC linear prediction reflection coefficients
** 3 LPCEPSTRA LPC cepstral coefficients
** 4 LPDELCEP LPC cepstra plus delta coefficients
** 5 IREFC LPC reflection coef in 16 bit integer format
** 6 MFCC mel-frequency cepstral coefficients
** 7 FBANK log mel-filter bank channel outputs
** 8 MELSPEC linear mel-filter bank channel outputs
** 9 USER user defined sample kind
** 10 DISCRETE vector quantised data
**
** and the bit-encoding for the qualifiers (in octal) is
** _E 000100 has energy
** _N 000200 absolute energy suppressed
** _D 000400 has delta coefficients
** _A 001000 has acceleration coefficients
** _C 002000 is compressed
** _Z 004000 has zero mean static coef.
** _K 010000 has CRC checksum
** _O 020000 has 0'th cepstral coef.
*/
static int
htk_read_header (SF_PRIVATE *psf)
{ int sample_count, sample_period, marker ;
psf_binheader_readf (psf, "pE444", 0, &sample_count, &sample_period, &marker) ;
if (2 * sample_count + 12 != psf->filelength)
return SFE_HTK_BAD_FILE_LEN ;
if (marker != 0x20000)
return SFE_HTK_NOT_WAVEFORM ;
psf->sf.channels = 1 ;
psf->sf.samplerate = 10000000 / sample_period ;
psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d => %d Hz\n",
sample_count, sample_period, psf->sf.samplerate) ;
psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
/* HTK always has a 12 byte header. */
psf->dataoffset = 12 ;
psf->endian = SF_ENDIAN_BIG ;
psf->datalength = psf->filelength - psf->dataoffset ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
if (! psf->sf.frames && psf->blockwidth)
psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
return 0 ;
} /* htk_read_header */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: c350e972-082e-4c20-8934-03391a723560
*/

View File

@@ -1,976 +0,0 @@
/*
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "sfendian.h"
#include "float_cast.h"
#include "common.h"
typedef struct IMA_ADPCM_PRIVATE_tag
{ int (*decode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
int (*encode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
int channels, blocksize, samplesperblock, blocks ;
int blockcount, samplecount ;
int previous [2] ;
int stepindx [2] ;
unsigned char *block ;
short *samples ;
#if HAVE_FLEXIBLE_ARRAY
short data [] ; /* ISO C99 struct flexible array. */
#else
short data [0] ; /* This is a hack and might not work. */
#endif
} IMA_ADPCM_PRIVATE ;
/*============================================================================================
** Predefined IMA ADPCM data.
*/
static int ima_indx_adjust [16] =
{ -1, -1, -1, -1, /* +0 - +3, decrease the step size */
2, 4, 6, 8, /* +4 - +7, increase the step size */
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
2, 4, 6, 8, /* -4 - -7, increase the step size */
} ;
static int ima_step_size [89] =
{ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767
} ;
static int ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
static int ima_writer_init (SF_PRIVATE *psf, int blockalign) ;
static int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
static int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len) ;
static sf_count_t ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int ima_close (SF_PRIVATE *psf) ;
static int wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
static int wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
/*-static int aiff_ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;-*/
static int aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
static int aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
/*============================================================================================
** IMA ADPCM Reader initialisation function.
*/
int
wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ int error ;
if (psf->fdata != NULL)
{ psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
if (psf->mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
psf->codec_close = ima_close ;
psf->seek = ima_seek ;
return 0 ;
} /* wav_w64_ima_init */
int
aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ int error ;
if (psf->mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
if (psf->mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
psf->codec_close = ima_close ;
return 0 ;
} /* aiff_ima_init */
static int
ima_close (SF_PRIVATE *psf)
{ IMA_ADPCM_PRIVATE *pima ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
if (psf->mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
if (pima->samplecount && pima->samplecount < pima->samplesperblock)
pima->encode_block (psf, pima) ;
psf->sf.frames = pima->samplesperblock * pima->blockcount / psf->sf.channels ;
} ;
return 0 ;
} /* ima_close */
/*============================================================================================
** IMA ADPCM Read Functions.
*/
static int
ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ IMA_ADPCM_PRIVATE *pima ;
int pimasize, count ;
if (psf->mode != SFM_READ)
return SFE_BAD_MODE_RW ;
pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
if (! (pima = malloc (pimasize)))
return SFE_MALLOC_FAILED ;
psf->fdata = (void*) pima ;
memset (pima, 0, pimasize) ;
pima->samples = pima->data ;
pima->block = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
pima->channels = psf->sf.channels ;
pima->blocksize = blockalign ;
pima->samplesperblock = samplesperblock ;
psf->filelength = psf_get_filelen (psf) ;
psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
psf->filelength - psf->dataoffset ;
if (psf->datalength % pima->blocksize)
pima->blocks = psf->datalength / pima->blocksize + 1 ;
else
pima->blocks = psf->datalength / pima->blocksize ;
switch (psf->sf.format & SF_FORMAT_TYPEMASK)
{ case SF_FORMAT_WAV :
case SF_FORMAT_W64 :
count = 2 * (pima->blocksize - 4 * pima->channels) / pima->channels + 1 ;
if (pima->samplesperblock != count)
psf_log_printf (psf, "*** Warning : samplesperblock should be %d.\n", count) ;
pima->decode_block = wav_w64_ima_decode_block ;
psf->sf.frames = pima->samplesperblock * pima->blocks ;
break ;
case SF_FORMAT_AIFF :
psf_log_printf (psf, "still need to check block count\n") ;
pima->decode_block = aiff_ima_decode_block ;
psf->sf.frames = pima->samplesperblock * pima->blocks / pima->channels ;
break ;
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
break ;
} ;
pima->decode_block (psf, pima) ; /* Read first block. */
psf->read_short = ima_read_s ;
psf->read_int = ima_read_i ;
psf->read_float = ima_read_f ;
psf->read_double = ima_read_d ;
return 0 ;
} /* ima_reader_init */
static int
aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ unsigned char *blockdata ;
int chan, k, diff, bytecode ;
short step, stepindx, predictor, *sampledata ;
static int count = 0 ;
count ++ ;
pima->blockcount += pima->channels ;
pima->samplecount = 0 ;
if (pima->blockcount > pima->blocks)
{ memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
return 1 ;
} ;
if ((k = psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
/* Read and check the block header. */
for (chan = 0 ; chan < pima->channels ; chan++)
{ blockdata = pima->block + chan * 34 ;
sampledata = pima->samples + chan ;
predictor = (blockdata [0] << 8) | (blockdata [1] & 0x80) ;
stepindx = blockdata [1] & 0x7F ;
{
if (count < 5)
printf ("\nchan: %d predictor: %d stepindx: %d (%d)\n",
chan, predictor, stepindx, ima_step_size [stepindx]) ;
}
/* FIXME : Do this a better way. */
if (stepindx < 0) stepindx = 0 ;
else if (stepindx > 88) stepindx = 88 ;
/*
** Pull apart the packed 4 bit samples and store them in their
** correct sample positions.
*/
for (k = 0 ; k < pima->blocksize - 2 ; k++)
{ bytecode = blockdata [k + 2] ;
sampledata [pima->channels * (2 * k + 0)] = bytecode & 0xF ;
sampledata [pima->channels * (2 * k + 1)] = (bytecode >> 4) & 0xF ;
} ;
/* Decode the encoded 4 bit samples. */
for (k = 0 ; k < pima->samplesperblock ; k ++)
{ step = ima_step_size [stepindx] ;
bytecode = pima->samples [pima->channels * k + chan] ;
stepindx += ima_indx_adjust [bytecode] ;
if (stepindx < 0) stepindx = 0 ;
else if (stepindx > 88) stepindx = 88 ;
diff = step >> 3 ;
if (bytecode & 1) diff += step >> 2 ;
if (bytecode & 2) diff += step >> 1 ;
if (bytecode & 4) diff += step ;
if (bytecode & 8) diff = -diff ;
predictor += diff ;
pima->samples [pima->channels * k + chan] = predictor ;
} ;
} ;
if (count < 5)
{
for (k = 0 ; k < 10 ; k++)
printf ("% 7d,", pima->samples [k]) ;
puts ("") ;
}
return 1 ;
} /* aiff_ima_decode_block */
static int
aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ int chan, k, step, diff, vpdiff, blockindx, indx ;
short bytecode, mask ;
static int count = 0 ;
if (0 && count == 0)
{ pima->samples [0] = 0 ;
printf ("blocksize : %d\n", pima->blocksize) ;
printf ("pima->stepindx [0] : %d\n", pima->stepindx [0]) ;
}
count ++ ;
/* Encode the block header. */
for (chan = 0 ; chan < pima->channels ; chan ++)
{ blockindx = chan * pima->blocksize ;
pima->block [blockindx] = (pima->samples [chan] >> 8) & 0xFF ;
pima->block [blockindx + 1] = (pima->samples [chan] & 0x80) + (pima->stepindx [chan] & 0x7F) ;
pima->previous [chan] = pima->samples [chan] ;
} ;
/* Encode second and later samples for every block as a 4 bit value. */
for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
{ chan = (pima->channels > 1) ? (k % 2) : 0 ;
diff = pima->samples [k] - pima->previous [chan] ;
bytecode = 0 ;
step = ima_step_size [pima->stepindx [chan]] ;
vpdiff = step >> 3 ;
if (diff < 0)
{ bytecode = 8 ;
diff = -diff ;
} ;
mask = 4 ;
while (mask)
{ if (diff >= step)
{ bytecode |= mask ;
diff -= step ;
vpdiff += step ;
} ;
step >>= 1 ;
mask >>= 1 ;
} ;
if (bytecode & 8)
pima->previous [chan] -= vpdiff ;
else
pima->previous [chan] += vpdiff ;
if (pima->previous [chan] > 32767)
pima->previous [chan] = 32767 ;
else if (pima->previous [chan] < -32768)
pima->previous [chan] = -32768 ;
pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
if (pima->stepindx [chan] < 0)
pima->stepindx [chan] = 0 ;
else if (pima->stepindx [chan] > 88)
pima->stepindx [chan] = 88 ;
pima->samples [k] = bytecode ;
} ;
/* Pack the 4 bit encoded samples. */
for (chan = 0 ; chan < pima->channels ; chan ++)
{ for (indx = pima->channels ; indx < pima->channels * pima->samplesperblock ; indx += 2 * pima->channels)
{ blockindx = chan * pima->blocksize + 2 + indx / 2 ;
if (0 && count ++ < 5)
printf ("chan: %d blockindx: %3d indx: %3d\n", chan, blockindx, indx) ;
pima->block [blockindx] = pima->samples [indx] & 0x0F ;
pima->block [blockindx] |= (pima->samples [indx + pima->channels] << 4) & 0xF0 ;
} ;
} ;
/* Write the block to disk. */
if ((k = psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->channels * pima->blocksize) ;
memset (pima->samples, 0, pima->channels * pima->samplesperblock * sizeof (short)) ;
pima->samplecount = 0 ;
pima->blockcount ++ ;
return 1 ;
} /* aiff_ima_encode_block */
static int
wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ int chan, k, current, blockindx, indx, indxstart, diff ;
short step, bytecode, stepindx [2] ;
pima->blockcount ++ ;
pima->samplecount = 0 ;
if (pima->blockcount > pima->blocks)
{ memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
return 1 ;
} ;
if ((k = psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
/* Read and check the block header. */
for (chan = 0 ; chan < pima->channels ; chan++)
{ current = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
if (current & 0x8000)
current -= 0x10000 ;
stepindx [chan] = pima->block [chan*4+2] ;
if (stepindx [chan] < 0)
stepindx [chan] = 0 ;
else if (stepindx [chan] > 88)
stepindx [chan] = 88 ;
if (pima->block [chan*4+3] != 0)
psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
pima->samples [chan] = current ;
} ;
/*
** Pull apart the packed 4 bit samples and store them in their
** correct sample positions.
*/
blockindx = 4 * pima->channels ;
indxstart = pima->channels ;
while (blockindx < pima->blocksize)
{ for (chan = 0 ; chan < pima->channels ; chan++)
{ indx = indxstart + chan ;
for (k = 0 ; k < 4 ; k++)
{ bytecode = pima->block [blockindx++] ;
pima->samples [indx] = bytecode & 0x0F ;
indx += pima->channels ;
pima->samples [indx] = (bytecode >> 4) & 0x0F ;
indx += pima->channels ;
} ;
} ;
indxstart += 8 * pima->channels ;
} ;
/* Decode the encoded 4 bit samples. */
for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
{ chan = (pima->channels > 1) ? (k % 2) : 0 ;
bytecode = pima->samples [k] & 0xF ;
step = ima_step_size [stepindx [chan]] ;
current = pima->samples [k - pima->channels] ;
diff = step >> 3 ;
if (bytecode & 1)
diff += step >> 2 ;
if (bytecode & 2)
diff += step >> 1 ;
if (bytecode & 4)
diff += step ;
if (bytecode & 8)
diff = -diff ;
current += diff ;
if (current > 32767)
current = 32767 ;
else if (current < -32768)
current = -32768 ;
stepindx [chan] += ima_indx_adjust [bytecode] ;
if (stepindx [chan] < 0)
stepindx [chan] = 0 ;
else if (stepindx [chan] > 88)
stepindx [chan] = 88 ;
pima->samples [k] = current ;
} ;
return 1 ;
} /* wav_w64_ima_decode_block */
static int
wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ int chan, k, step, diff, vpdiff, blockindx, indx, indxstart ;
short bytecode, mask ;
/* Encode the block header. */
for (chan = 0 ; chan < pima->channels ; chan++)
{ pima->block [chan*4] = pima->samples [chan] & 0xFF ;
pima->block [chan*4+1] = (pima->samples [chan] >> 8) & 0xFF ;
pima->block [chan*4+2] = pima->stepindx [chan] ;
pima->block [chan*4+3] = 0 ;
pima->previous [chan] = pima->samples [chan] ;
} ;
/* Encode the samples as 4 bit. */
for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
{ chan = (pima->channels > 1) ? (k % 2) : 0 ;
diff = pima->samples [k] - pima->previous [chan] ;
bytecode = 0 ;
step = ima_step_size [pima->stepindx [chan]] ;
vpdiff = step >> 3 ;
if (diff < 0)
{ bytecode = 8 ;
diff = -diff ;
} ;
mask = 4 ;
while (mask)
{ if (diff >= step)
{ bytecode |= mask ;
diff -= step ;
vpdiff += step ;
} ;
step >>= 1 ;
mask >>= 1 ;
} ;
if (bytecode & 8)
pima->previous [chan] -= vpdiff ;
else
pima->previous [chan] += vpdiff ;
if (pima->previous [chan] > 32767)
pima->previous [chan] = 32767 ;
else if (pima->previous [chan] < -32768)
pima->previous [chan] = -32768 ;
pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
if (pima->stepindx [chan] < 0)
pima->stepindx [chan] = 0 ;
else if (pima->stepindx [chan] > 88)
pima->stepindx [chan] = 88 ;
pima->samples [k] = bytecode ;
} ;
/* Pack the 4 bit encoded samples. */
blockindx = 4 * pima->channels ;
indxstart = pima->channels ;
while (blockindx < pima->blocksize)
{ for (chan = 0 ; chan < pima->channels ; chan++)
{ indx = indxstart + chan ;
for (k = 0 ; k < 4 ; k++)
{ pima->block [blockindx] = pima->samples [indx] & 0x0F ;
indx += pima->channels ;
pima->block [blockindx] |= (pima->samples [indx] << 4) & 0xF0 ;
indx += pima->channels ;
blockindx ++ ;
} ;
} ;
indxstart += 8 * pima->channels ;
} ;
/* Write the block to disk. */
if ((k = psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->blocksize) ;
memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
pima->samplecount = 0 ;
pima->blockcount ++ ;
return 1 ;
} /* wav_w64_ima_encode_block */
static int
ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ if (pima->blockcount >= pima->blocks && pima->samplecount >= pima->samplesperblock)
{ memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;
return total ;
} ;
if (pima->samplecount >= pima->samplesperblock)
pima->decode_block (psf, pima) ;
count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
count = (len - indx > count) ? count : len - indx ;
memcpy (&(ptr [indx]), &(pima->samples [pima->samplecount * pima->channels]), count * sizeof (short)) ;
indx += count ;
pima->samplecount += count / pima->channels ;
total = indx ;
} ;
return total ;
} /* ima_read_block */
static sf_count_t
ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
int readcount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
while (len > 0)
{ readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = ima_read_block (psf, pima, ptr, readcount) ;
total += count ;
len -= count ;
if (count != readcount)
break ;
} ;
return total ;
} /* ima_read_s */
static sf_count_t
ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = ((int) sptr [k]) << 16 ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* ima_read_i */
static sf_count_t
ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
float normfact ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * (float) (sptr [k]) ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* ima_read_f */
static sf_count_t
ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
double normfact ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * (double) (sptr [k]) ;
total += count ;
len -= readcount ;
if (count != readcount)
break ;
} ;
return total ;
} /* ima_read_d */
static sf_count_t
ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
{ IMA_ADPCM_PRIVATE *pima ;
int newblock, newsample ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
if (psf->datalength < 0 || psf->dataoffset < 0)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
if (offset == 0)
{ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
pima->blockcount = 0 ;
pima->decode_block (psf, pima) ;
pima->samplecount = 0 ;
return 0 ;
} ;
if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
newblock = offset / pima->samplesperblock ;
newsample = offset % pima->samplesperblock ;
if (mode == SFM_READ)
{ psf_fseek (psf, psf->dataoffset + newblock * pima->blocksize, SEEK_SET) ;
pima->blockcount = newblock ;
pima->decode_block (psf, pima) ;
pima->samplecount = newsample ;
}
else
{ /* What to do about write??? */
psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
return newblock * pima->samplesperblock + newsample ;
} /* ima_seek */
/*==========================================================================================
** IMA ADPCM Write Functions.
*/
static int
ima_writer_init (SF_PRIVATE *psf, int blockalign)
{ IMA_ADPCM_PRIVATE *pima ;
int samplesperblock ;
unsigned int pimasize ;
if (psf->mode != SFM_WRITE)
return SFE_BAD_MODE_RW ;
samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
if ((pima = calloc (1, pimasize)) == NULL)
return SFE_MALLOC_FAILED ;
psf->fdata = (void*) pima ;
pima->channels = psf->sf.channels ;
pima->blocksize = blockalign ;
pima->samplesperblock = samplesperblock ;
pima->block = (unsigned char*) pima->data ;
pima->samples = (short*) (pima->data + blockalign) ;
pima->samplecount = 0 ;
switch (psf->sf.format & SF_FORMAT_TYPEMASK)
{ case SF_FORMAT_WAV :
case SF_FORMAT_W64 :
pima->encode_block = wav_w64_ima_encode_block ;
break ;
case SF_FORMAT_AIFF :
pima->encode_block = aiff_ima_encode_block ;
break ;
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
break ;
} ;
psf->write_short = ima_write_s ;
psf->write_int = ima_write_i ;
psf->write_float = ima_write_f ;
psf->write_double = ima_write_d ;
return 0 ;
} /* ima_writer_init */
/*==========================================================================================
*/
static int
ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len)
{ int count, total = 0, indx = 0 ;
while (indx < len)
{ count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
if (count > len - indx)
count = len - indx ;
memcpy (&(pima->samples [pima->samplecount * pima->channels]), &(ptr [total]), count * sizeof (short)) ;
indx += count ;
pima->samplecount += count / pima->channels ;
total = indx ;
if (pima->samplecount >= pima->samplesperblock)
pima->encode_block (psf, pima) ;
} ;
return total ;
} /* ima_write_block */
static sf_count_t
ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
int writecount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
while (len)
{ writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
count = ima_write_block (psf, pima, ptr, writecount) ;
total += count ;
len -= count ;
if (count != writecount)
break ;
} ;
return total ;
} /* ima_write_s */
static sf_count_t
ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = ptr [total + k] >> 16 ;
count = ima_write_block (psf, pima, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* ima_write_i */
static sf_count_t
ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
float normfact ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrintf (normfact * ptr [total + k]) ;
count = ima_write_block (psf, pima, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* ima_write_f */
static sf_count_t
ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
double normfact ;
if (! psf->fdata)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
sptr [k] = lrint (normfact * ptr [total + k]) ;
count = ima_write_block (psf, pima, sptr, writecount) ;
total += count ;
len -= writecount ;
if (count != writecount)
break ;
} ;
return total ;
} /* ima_write_d */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 75a54b82-ad18-4758-9933-64e00a7f24e0
*/

View File

@@ -1,306 +0,0 @@
/*
** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfendian.h"
#include <stdlib.h>
#include "sndfile.h"
#include "common.h"
#define INTERLEAVE_CHANNELS 6
typedef struct
{ double buffer [SF_BUFFER_LEN / sizeof (double)] ;
sf_count_t channel_len ;
sf_count_t (*read_short) (SF_PRIVATE*, short *ptr, sf_count_t len) ;
sf_count_t (*read_int) (SF_PRIVATE*, int *ptr, sf_count_t len) ;
sf_count_t (*read_float) (SF_PRIVATE*, float *ptr, sf_count_t len) ;
sf_count_t (*read_double) (SF_PRIVATE*, double *ptr, sf_count_t len) ;
} INTERLEAVE_DATA ;
static sf_count_t interleave_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t interleave_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t interleave_read_float (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t interleave_seek (SF_PRIVATE*, int mode, sf_count_t samples_from_start) ;
int
interleave_init (SF_PRIVATE *psf)
{ INTERLEAVE_DATA *pdata ;
if (psf->mode != SFM_READ)
return SFE_INTERLEAVE_MODE ;
if (psf->interleave)
{ psf_log_printf (psf, "*** Weird, already have interleave.\n") ;
return 666 ;
} ;
/* Free this in sf_close() function. */
if (! (pdata = malloc (sizeof (INTERLEAVE_DATA))))
return SFE_MALLOC_FAILED ;
puts ("interleave_init") ;
psf->interleave = pdata ;
/* Save the existing methods. */
pdata->read_short = psf->read_short ;
pdata->read_int = psf->read_int ;
pdata->read_float = psf->read_float ;
pdata->read_double = psf->read_double ;
pdata->channel_len = psf->sf.frames * psf->bytewidth ;
/* Insert our new methods. */
psf->read_short = interleave_read_short ;
psf->read_int = interleave_read_int ;
psf->read_float = interleave_read_float ;
psf->read_double = interleave_read_double ;
psf->seek = interleave_seek ;
return 0 ;
} /* pcm_interleave_init */
/*------------------------------------------------------------------------------
*/
static sf_count_t
interleave_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ INTERLEAVE_DATA *pdata ;
sf_count_t offset, templen ;
int chan, count, k ;
short *inptr, *outptr ;
if (! (pdata = psf->interleave))
return 0 ;
inptr = (short*) pdata->buffer ;
for (chan = 0 ; chan < psf->sf.channels ; chan++)
{ outptr = ptr + chan ;
offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
if (psf_fseek (psf, offset, SEEK_SET) != offset)
{ psf->error = SFE_INTERLEAVE_SEEK ;
return 0 ;
} ;
templen = len / psf->sf.channels ;
while (templen > 0)
{ if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short))
count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short) ;
else
count = (int) templen ;
if (pdata->read_short (psf, inptr, count) != count)
{ psf->error = SFE_INTERLEAVE_READ ;
return 0 ;
} ;
for (k = 0 ; k < count ; k++)
{ *outptr = inptr [k] ;
outptr += psf->sf.channels ;
} ;
templen -= count ;
} ;
} ;
return len ;
} /* interleave_read_short */
static sf_count_t
interleave_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ INTERLEAVE_DATA *pdata ;
sf_count_t offset, templen ;
int chan, count, k ;
int *inptr, *outptr ;
if (! (pdata = psf->interleave))
return 0 ;
inptr = (int*) pdata->buffer ;
for (chan = 0 ; chan < psf->sf.channels ; chan++)
{ outptr = ptr + chan ;
offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
if (psf_fseek (psf, offset, SEEK_SET) != offset)
{ psf->error = SFE_INTERLEAVE_SEEK ;
return 0 ;
} ;
templen = len / psf->sf.channels ;
while (templen > 0)
{ if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int))
count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int) ;
else
count = (int) templen ;
if (pdata->read_int (psf, inptr, count) != count)
{ psf->error = SFE_INTERLEAVE_READ ;
return 0 ;
} ;
for (k = 0 ; k < count ; k++)
{ *outptr = inptr [k] ;
outptr += psf->sf.channels ;
} ;
templen -= count ;
} ;
} ;
return len ;
} /* interleave_read_int */
static sf_count_t
interleave_read_float (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ INTERLEAVE_DATA *pdata ;
sf_count_t offset, templen ;
int chan, count, k ;
float *inptr, *outptr ;
if (! (pdata = psf->interleave))
return 0 ;
inptr = (float*) pdata->buffer ;
for (chan = 0 ; chan < psf->sf.channels ; chan++)
{ outptr = ptr + chan ;
offset = psf->dataoffset + pdata->channel_len * chan + psf->read_current * psf->bytewidth ;
/*-printf ("chan : %d read_current : %6lld offset : %6lld\n", chan, psf->read_current, offset) ;-*/
if (psf_fseek (psf, offset, SEEK_SET) != offset)
{ psf->error = SFE_INTERLEAVE_SEEK ;
/*-puts ("interleave_seek error") ; exit (1) ;-*/
return 0 ;
} ;
templen = len / psf->sf.channels ;
while (templen > 0)
{ if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float))
count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float) ;
else
count = (int) templen ;
if (pdata->read_float (psf, inptr, count) != count)
{ psf->error = SFE_INTERLEAVE_READ ;
/*-puts ("interleave_read error") ; exit (1) ;-*/
return 0 ;
} ;
for (k = 0 ; k < count ; k++)
{ *outptr = inptr [k] ;
outptr += psf->sf.channels ;
} ;
templen -= count ;
} ;
} ;
return len ;
} /* interleave_read_float */
static sf_count_t
interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ INTERLEAVE_DATA *pdata ;
sf_count_t offset, templen ;
int chan, count, k ;
double *inptr, *outptr ;
if (! (pdata = psf->interleave))
return 0 ;
inptr = (double*) pdata->buffer ;
for (chan = 0 ; chan < psf->sf.channels ; chan++)
{ outptr = ptr + chan ;
offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
if (psf_fseek (psf, offset, SEEK_SET) != offset)
{ psf->error = SFE_INTERLEAVE_SEEK ;
return 0 ;
} ;
templen = len / psf->sf.channels ;
while (templen > 0)
{ if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double))
count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double) ;
else
count = (int) templen ;
if (pdata->read_double (psf, inptr, count) != count)
{ psf->error = SFE_INTERLEAVE_READ ;
return 0 ;
} ;
for (k = 0 ; k < count ; k++)
{ *outptr = inptr [k] ;
outptr += psf->sf.channels ;
} ;
templen -= count ;
} ;
} ;
return len ;
} /* interleave_read_double */
/*------------------------------------------------------------------------------
*/
static sf_count_t
interleave_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
{ psf = psf ; mode = mode ;
/*
** Do nothing here. This is a place holder to prevent the default
** seek function from being called.
*/
return samples_from_start ;
} /* interleave_seek */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 82314e13-0225-4408-a2f2-e6dab3f38904
*/

View File

@@ -1,331 +0,0 @@
/*
** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser 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.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
/* The IRCAM magic number is weird in that one byte in the number can have
** values of 0x1, 0x2, 0x03 or 0x04. Hence the need for a marker and a mask.
*/
#define IRCAM_BE_MASK (MAKE_MARKER (0xFF, 0xFF, 0x00, 0xFF))
#define IRCAM_BE_MARKER (MAKE_MARKER (0x64, 0xA3, 0x00, 0x00))
#define IRCAM_LE_MASK (MAKE_MARKER (0xFF, 0x00, 0xFF, 0xFF))
#define IRCAM_LE_MARKER (MAKE_MARKER (0x00, 0x00, 0xA3, 0x64))
#define IRCAM_02B_MARKER (MAKE_MARKER (0x64, 0xA3, 0x02, 0x00))
#define IRCAM_03L_MARKER (MAKE_MARKER (0x64, 0xA3, 0x03, 0x00))
#define IRCAM_DATA_OFFSET (1024)
/*------------------------------------------------------------------------------
** Typedefs.
*/
enum
{ IRCAM_PCM_16 = 0x00002,
IRCAM_FLOAT = 0x00004,
IRCAM_ALAW = 0x10001,
IRCAM_ULAW = 0x20001,
IRCAM_PCM_32 = 0x40004
} ;
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int ircam_close (SF_PRIVATE *psf) ;
static int ircam_write_header (SF_PRIVATE *psf, int calc_length) ;
static int ircam_read_header (SF_PRIVATE *psf) ;
static int get_encoding (int subformat) ;
static const char* get_encoding_str (int encoding) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
ircam_open (SF_PRIVATE *psf)
{ int subformat ;
int error = SFE_NO_ERROR ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = ircam_read_header (psf)))
return error ;
} ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_IRCAM)
return SFE_BAD_OPEN_FORMAT ;
psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)
psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
psf->dataoffset = IRCAM_DATA_OFFSET ;
if ((error = ircam_write_header (psf, SF_FALSE)))
return error ;
psf->write_header = ircam_write_header ;
} ;
psf->container_close = ircam_close ;
switch (subformat)
{ case SF_FORMAT_ULAW : /* 8-bit Ulaw encoding. */
error = ulaw_init (psf) ;
break ;
case SF_FORMAT_ALAW : /* 8-bit Alaw encoding. */
error = alaw_init (psf) ;
break ;
case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
error = pcm_init (psf) ;
break ;
case SF_FORMAT_FLOAT : /* 32-bit linear PCM. */
error = float32_init (psf) ;
break ;
default : break ;
} ;
return error ;
} /* ircam_open */
/*------------------------------------------------------------------------------
*/
static int
ircam_read_header (SF_PRIVATE *psf)
{ unsigned int marker, encoding ;
float samplerate ;
int error = SFE_NO_ERROR ;
psf_binheader_readf (psf, "epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;
if (((marker & IRCAM_BE_MASK) != IRCAM_BE_MARKER) && ((marker & IRCAM_LE_MASK) != IRCAM_LE_MARKER))
{ psf_log_printf (psf, "marker: 0x%X\n", marker) ;
return SFE_IRCAM_NO_MARKER ;
} ;
psf->endian = SF_ENDIAN_LITTLE ;
if (psf->sf.channels > 256)
{ psf_binheader_readf (psf, "Epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;
/* Sanity checking for endian-ness detection. */
if (psf->sf.channels > 256)
{ psf_log_printf (psf, "marker: 0x%X\n", marker) ;
return SFE_IRCAM_BAD_CHANNELS ;
} ;
psf->endian = SF_ENDIAN_BIG ;
} ;
psf_log_printf (psf, "marker: 0x%X\n", marker) ;
psf->sf.samplerate = (int) samplerate ;
psf_log_printf (psf, " Sample Rate : %d\n"
" Channels : %d\n"
" Encoding : %X => %s\n", psf->sf.samplerate, psf->sf.channels, encoding, get_encoding_str (encoding)) ;
switch (encoding)
{ case IRCAM_PCM_16 :
psf->bytewidth = 2 ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_16 ;
break ;
case IRCAM_PCM_32 :
psf->bytewidth = 4 ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_32 ;
break ;
case IRCAM_FLOAT :
psf->bytewidth = 4 ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_FLOAT ;
break ;
case IRCAM_ALAW :
psf->bytewidth = 1 ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ALAW ;
break ;
case IRCAM_ULAW :
psf->bytewidth = 1 ;
psf->blockwidth = psf->sf.channels * psf->bytewidth ;
psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ULAW ;
break ;
default :
error = SFE_IRCAM_UNKNOWN_FORMAT ;
break ;
} ;
if (psf->endian == SF_ENDIAN_BIG)
psf->sf.format |= SF_ENDIAN_BIG ;
else
psf->sf.format |= SF_ENDIAN_LITTLE ;
if (error)
return error ;
psf->dataoffset = IRCAM_DATA_OFFSET ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->sf.frames == 0 && psf->blockwidth)
psf->sf.frames = psf->datalength / psf->blockwidth ;
psf_log_printf (psf, " Samples : %d\n", psf->sf.frames) ;
psf_binheader_readf (psf, "p", IRCAM_DATA_OFFSET) ;
return 0 ;
} /* ircam_read_header */
static int
ircam_close (SF_PRIVATE *psf)
{
psf_log_printf (psf, "close\n") ;
return 0 ;
} /* ircam_close */
static int
ircam_write_header (SF_PRIVATE *psf, int calc_length)
{ int encoding ;
float samplerate ;
sf_count_t current ;
if (psf->pipeoffset > 0)
return 0 ;
current = psf_ftell (psf) ;
calc_length = calc_length ;
/* This also sets psf->endian. */
encoding = get_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ;
if (encoding == 0)
return SFE_BAD_OPEN_FORMAT ;
/* Reset the current header length to zero. */
psf->header [0] = 0 ;
psf->headindex = 0 ;
if (psf->is_pipe == SF_FALSE)
psf_fseek (psf, 0, SEEK_SET) ;
samplerate = psf->sf.samplerate ;
switch (psf->endian)
{ case SF_ENDIAN_BIG :
psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ;
psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ;
break ;
case SF_ENDIAN_LITTLE :
psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ;
psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ;
break ;
default : return SFE_BAD_OPEN_FORMAT ;
} ;
psf_binheader_writef (psf, "z", (size_t) (IRCAM_DATA_OFFSET - psf->headindex)) ;
/* Header construction complete so write it out. */
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
return psf->error ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return psf->error ;
} /* ircam_write_header */
static int
get_encoding (int subformat)
{ switch (subformat)
{ case SF_FORMAT_PCM_16 : return IRCAM_PCM_16 ;
case SF_FORMAT_PCM_32 : return IRCAM_PCM_32 ;
case SF_FORMAT_FLOAT : return IRCAM_FLOAT ;
case SF_FORMAT_ULAW : return IRCAM_ULAW ;
case SF_FORMAT_ALAW : return IRCAM_ALAW ;
default : break ;
} ;
return 0 ;
} /* get_encoding */
static const char*
get_encoding_str (int encoding)
{ switch (encoding)
{ case IRCAM_PCM_16 : return "16 bit PCM" ;
case IRCAM_FLOAT : return "32 bit float" ;
case IRCAM_ALAW : return "A law" ;
case IRCAM_ULAW : return "u law" ;
case IRCAM_PCM_32 : return "32 bit PCM" ;
} ;
return "Unknown encoding" ;
} /* get_encoding_str */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: f2714ab8-f286-4c94-9740-edaf673a1c71
*/

View File

@@ -1,39 +0,0 @@
; Auto-generated by create_symbols_file.py
LIBRARY libsndfile-1.dll
EXPORTS
sf_command @1
sf_open @2
sf_close @3
sf_seek @4
sf_error @7
sf_perror @8
sf_error_str @9
sf_error_number @10
sf_format_check @11
sf_read_raw @16
sf_readf_short @17
sf_readf_int @18
sf_readf_float @19
sf_readf_double @20
sf_read_short @21
sf_read_int @22
sf_read_float @23
sf_read_double @24
sf_write_raw @32
sf_writef_short @33
sf_writef_int @34
sf_writef_float @35
sf_writef_double @36
sf_write_short @37
sf_write_int @38
sf_write_float @39
sf_write_double @40
sf_strerror @50
sf_get_string @60
sf_set_string @61
sf_open_fd @70
sf_open_virtual @80
sf_write_sync @90

Some files were not shown because too many files have changed in this diff Show More