From 741ee37da87bb05ac027781f4a5ccbbd25f0c823 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 29 Oct 2009 11:29:58 -0500 Subject: First version of the script. --- cisco_ringtone_convert | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 cisco_ringtone_convert (limited to 'cisco_ringtone_convert') diff --git a/cisco_ringtone_convert b/cisco_ringtone_convert new file mode 100644 index 0000000..9cfc44a --- /dev/null +++ b/cisco_ringtone_convert @@ -0,0 +1,132 @@ +#!/usr/bin/python +# -*- mode: python; coding: utf-8 -*- + +# Copyright © 2009 Jeffrey C. Ollie +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# Based upon code originally posted by Jono Bacon to his blog: +# http://www.jonobacon.org/2006/12/27/using-gnonlin-with-gstreamer-and-python/ + +import sys +import optparse +import pygst +pygst.require('0.10') +import gst +import gobject + +# Cisco ringtones can be at most 16080 bytes long +max_ringtone_length_bytes = 16080 +ringtone_sample_rate = 8000.0 +ringtone_bytes_per_sample = 1 +max_ringtone_duration = max_ringtone_length_bytes / (ringtone_bytes_per_sample * ringtone_sample_rate) + +class Main: + def __init__(self, mainloop, source, destination, start, duration): + if duration > max_ringtone_duration: + sys.stderr.write('Cisco ring tones may be at most %4.2f seconds long, reducing duration.\n' % max_ringtone_duration) + duration = max_ringtone_duration + + self.mainloop = mainloop + + self.pipeline = gst.Pipeline() + + bus = self.pipeline.get_bus() + bus.add_signal_watch() + bus.connect('message', self.handle_message) + + self.gnlcomposition = gst.element_factory_make('gnlcomposition') + self.gnlcomposition.connect('pad-added', self.on_pad_added) + self.pipeline.add(self.gnlcomposition) + + self.gnlfilesource = gst.element_factory_make('gnlfilesource') + self.gnlfilesource.set_property('caps', gst.caps_from_string('audio/x-raw-int; audio/x-raw-float')) + self.gnlfilesource.set_property('location', source) + self.gnlfilesource.set_property('start', 0 * gst.SECOND) + self.gnlfilesource.set_property('duration', int(duration * gst.SECOND)) + self.gnlfilesource.set_property('media-start', int(start * gst.SECOND)) + self.gnlfilesource.set_property('media-duration', int(duration * gst.SECOND)) + + self.gnlcomposition.add(self.gnlfilesource) + + self.audioconvert = gst.element_factory_make('audioconvert') + self.pipeline.add(self.audioconvert) + + self.audioresample = gst.element_factory_make('audioresample') + self.pipeline.add(self.audioresample) + self.audioconvert.link(self.audioresample) + + self.mulawenc = gst.element_factory_make('mulawenc') + self.pipeline.add(self.mulawenc) + self.audioresample.link(self.mulawenc) + + self.capsfilter = gst.element_factory_make('capsfilter') + self.capsfilter.set_property('caps', + gst.caps_from_string('audio/x-mulaw,rate=8000,channels=1')) + self.pipeline.add(self.capsfilter) + self.mulawenc.link(self.capsfilter) + + self.filesink = gst.element_factory_make('filesink') + self.filesink.set_property('location', destination) + self.pipeline.add(self.filesink) + self.capsfilter.link(self.filesink) + + self.pipeline.set_state(gst.STATE_PLAYING) + + def on_pad_added(self, element, pad): + if element == self.gnlcomposition: + pad.link(self.audioconvert.get_compatible_pad(pad, pad.get_caps())) + + def handle_message(self, bus, message): + if message.type == gst.MESSAGE_EOS: + self.pipeline.set_state(gst.STATE_NULL) + self.mainloop.quit() + + elif message.type == gst.MESSAGE_ERROR: + error, debug = message.parse_error() + sys.stderr.write('Error %s: %s\n' % (error, debug)) + self.pipeline.set_state(gst.STATE_NULL) + self.mainloop.quit() + +parser = optparse.OptionParser(version='0.1') + +parser.add_option('-s', '--start', + action = 'store', + type = 'float', + dest = 'start', + default = 0.0, + help = 'Position in the audio file to start extracting ring tone from.', + metavar = 'SECONDS') + +parser.add_option('-d', '--duration', + action = 'store', + type = 'float', + dest = 'duration', + default = max_ringtone_duration, + help = 'Duration of ring tone to extract from the audio file.', + metavar = 'SECONDS') + +options, args = parser.parse_args() + +if len(args) != 2: + sys.stderr.write('Must specify a source and a destination!\n') + sys.exit(1) + +gobject.threads_init() +mainloop = gobject.MainLoop() +start=Main(mainloop, args[0], args[1], options.start, options.duration) +mainloop.run() + -- cgit