[gcompris/gcomprismusic] added convert to .wav song file feature
- From: Karthik Subramanian <karthiks src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcompris/gcomprismusic] added convert to .wav song file feature
- Date: Tue, 12 Jul 2011 06:21:57 +0000 (UTC)
commit cc8152adeb8c8d0fd33ae42401ca54c3cab44145
Author: Karthik Subramanian <itskarthik s gmail com>
Date: Tue Jul 12 11:51:25 2011 +0530
added convert to .wav song file feature
src/piano-activity/piano.py | 54 ++++-
src/piano-activity/pysynth.py | 284 ++++++++++++++++++++
.../resources/piano/convert_icon.svg | 185 +++++++++++++
3 files changed, 518 insertions(+), 5 deletions(-)
---
diff --git a/src/piano-activity/piano.py b/src/piano-activity/piano.py
index 8886295..e8e5208 100644
--- a/src/piano-activity/piano.py
+++ b/src/piano-activity/piano.py
@@ -24,6 +24,7 @@ import gcompris.skin
import gcompris.bonus
import gcompris.sound
import goocanvas
+import pysynth
import ConfigParser
import pango
import time
@@ -364,7 +365,7 @@ class Gcompris_piano:
self.loadicon = goocanvas.Image(
parent = self.rootitem,
x = 650,
- y = 270,
+ y = 300,
width = 60,
height = 60,
pixbuf = gcompris.utils.load_pixmap("piano/loadicon.svg")
@@ -384,6 +385,18 @@ class Gcompris_piano:
gcompris.utils.item_focus_init(self.labelicon, None)
gcompris.utils.item_focus_init(self.pianosizeicon, None)
+
+ # Convert Icon
+ self.converticon = goocanvas.Image(
+ parent = self.rootitem,
+ x = 650,
+ y = 390,
+ width = 60,
+ height = 60,
+ pixbuf = gcompris.utils.load_pixmap("piano/convert_icon.svg")
+ )
+ gcompris.utils.item_focus_init(self.converticon, None)
+
# Displays the status of whether notes are currently being saved or not
self.savestatus = goocanvas.Text(
parent = self.rootitem,
@@ -397,7 +410,7 @@ class Gcompris_piano:
)
self.pianosizeicon.connect("button-press-event", self.change_size)
-
+ self.converticon.connect("button-press-event", self.convert_notes)
self.saveicon.connect("button-press-event", self.save_notes)
self.labelicon.connect("button-press-event", self.show_label)
self.loadicon.connect("button-press-event", self.load_file)
@@ -426,6 +439,32 @@ class Gcompris_piano:
)
self.pianobg2.translate(375, 200)
+ def convert_notes(self, item, event, attr):
+
+ gcompris.file_selector_load( self.gcomprisBoard, self.selector_section, self.file_type, convert_load, self)
+
+ print 'Converting'
+
+ def convert_to_wav(self, filename):
+ file = open(filename, 'rb')
+ fname = filename.replace('.gcpiano','.wav')
+ try:
+ song = []
+ notes = file.read()
+ notesarray = notes.split(' ')
+ print notesarray
+ for note in notesarray:
+ if len(note)==3:
+ note[1]='#'
+ elif note=='':
+ break
+ song.append((''+note+'',3))
+ song.append(('r',3))
+ pysynth.make_wav(song,fn=fname)
+
+ except:
+ file.close()
+
def change_size(self, item, event, attr):
if self.pianosize == 1 :
self.setpiano(2)
@@ -456,13 +495,13 @@ class Gcompris_piano:
def save_notes(self, item, event, attr):
if self.save == False :
- self.save = True
+
gcompris.file_selector_save( self.gcomprisBoard, self.selector_section,
self.file_type,
general_save, self)
- self.savestatus.props.text = "Saving.."
+
else :
if self.save is True:
@@ -630,7 +669,7 @@ class Gcompris_piano:
self.setpiano(2)
self.pianosize = 2
self.currentsong = self.bday
- self.titletext.props.text = 'Happy Birthday tune (Pentatonic Scale)'
+ self.titletext.props.text = 'Happy Birthday tune'
self.notestext.props.text = 'G G A G C3 B G G A G D3 C3 G G G3 E3 C3 B A F3 F3 E3 D3 C3'
elif level == 6:
self.noteslength = 41
@@ -663,8 +702,13 @@ class Gcompris_piano:
def general_save( filename, filetype, fles):
#print filename
+ fles.save = True
+ fles.savestatus.props.text = "Saving.."
fles.piano_to_file(filename)
def general_load( filename, filetype, fles):
fles.file_to_piano(filename)
+def convert_load(filename, filetype, fles):
+
+ fles.convert_to_wav(filename)
diff --git a/src/piano-activity/pysynth.py b/src/piano-activity/pysynth.py
new file mode 100755
index 0000000..83ad648
--- /dev/null
+++ b/src/piano-activity/pysynth.py
@@ -0,0 +1,284 @@
+#!/usr/bin/env python
+# -*- coding: latin-1 -*-
+
+"""
+##########################################################################
+# * * * PySynth * * *
+# A very basic audio synthesizer in Python (www.python.org)
+#
+# Martin C. Doege, 2009-04-07 (mdoege compuserve com)
+##########################################################################
+# Based on a program by Tyler Eaves (tyler at tylereaves.com) found at
+# http://mail.python.org/pipermail/python-list/2000-August/049968.html
+##########################################################################
+
+# 'song' is a Python list (or tuple) in which the song is defined,
+# the format is [['note', value]]
+
+# Notes are 'a' through 'g' of course,
+# optionally with '#' or 'b' appended for sharps or flats.
+# Finally the octave number (defaults to octave 4 if not given).
+# An asterisk at the end makes the note a little louder (useful for the beat).
+# 'r' is a rest.
+
+# Note value is a number:
+# 1=Whole Note; 2=Half Note; 4=Quarter Note, etc.
+# Dotted notes can be written in two ways:
+# 1.33 = -2 = dotted half
+# 2.66 = -4 = dotted quarter
+# 5.33 = -8 = dotted eighth
+"""
+
+# Example 1: The C major scale
+song1 = [
+['c',4],['d',4],['e',4],['f',4],['g',4],['a',4],['b',4],['c5',2],['r',1],
+['c3',4],['d3',4],['e3',4],['f3',4],['g3',4],['a3',4],['b3',4],['c4',2],['r',1],
+['c1*', 1], ['c2*', 1], ['c3*', 1], ['c4*', 1], ['c5*', 1], ['c6*', 1], ['c7*', 1], ['c8*', 1],
+]
+
+# Example 2: Something a little more patriotic
+song2 = (
+ ('g', -8), ('e', 16),
+ ('c*', 4), ('e', 4), ('g', 4),
+ ('c5*', 2), ('e5', -8), ('d5', 16),
+ ('c5*', 4), ('e', 4), ('f#', 4),
+ ('g*', 2), ('g', 8), ('g', 8),
+ ('e5*', -4), ('d5', 8), ('c5', 4),
+ ('b*', 2), ('a', -8), ('b', 16),
+ ('c5*', 4), ('c5', 4), ('g', 4),
+ ('e*', 4), ('c', 4),
+)
+
+# Example 3: Beginning of Nocturne Op. 9 #2 by F. Chopin
+song3 = (
+ ('bb', 8),
+ ('g5*', 2), ('f5', 8), ('g5', 8), ('f5', -4), ('eb5', 4), ('bb', 8),
+ ('g5*', 4), ('c5', 8), ('c6', 4), ('g5', 8), ('bb5', -4), ('ab5', 4), ('g5', 8),
+ ('f5*', -4), ('g5', 4), ('d5', 8), ('eb5', -4), ('c5', -4),
+ ('bb*', 8), ('d6', 8), ('c6', 8), ('bb5', 16), ('ab5', 16), ('g5', 16), ('ab5', 16), ('c5', 16), ('d5', 16), ('eb5', -4),
+)
+
+# Example 4: J.S. Bach: Bourré(from BWV 996)
+song4_rh = (
+ ('e', 8), ('f#', 8),
+ ('g*', 4), ('f#', 8), ('e', 8), ('d#*', 4), ('e', 8), ('f#', 8),
+ ('b3*', 4), ('c#', 8), ('d#', 8), ('e*', 4), ('d', 8), ('c', 8),
+ ('b3*', 4), ('a3', 8), ('g3', 8), ('f#3*', 4), ('g3', 8), ('a3', 8),
+ ('b3*', 8), ('a3', 8), ('g3', 8), ('f#3', 8), ('e3*', 4), ('e', 8), ('f#', 8),
+ ('g*', 4), ('f#', 8), ('e', 8), ('d#*', 4), ('e', 8), ('f#', 8),
+ ('b3*', 4), ('c#', 8), ('d#', 8), ('e*', 4), ('d', 8), ('c', 8),
+ ('b3*', 4), ('a3', 8), ('g3', 8), ('g3*', 32), ('f#3*', 32), ('g3*', 32), ('f#3*', 32), ('g3*', 32), ('f#3*', 32), ('g3*', 32), ('f#3*', 6.4), ('g3', 8), ('g3*', -2),
+)
+# version without the trill:
+# ('b3*', 4), ('a3', 8), ('g3', 8), ('f#3*', -4), ('g3', 8), ('g3*', -2),
+
+song4_lh = (
+ ('g2', 8), ('f#2', 8),
+ ('e2*', 4), ('a2', 4), ('b2', 4), ('a2', 4),
+ ('g2*', 4), ('f#2', 4), ('e2', 4), ('f#2', 4),
+ ('g2*', 4), ('a2', 4), ('b2', 4), ('a2', 4),
+ ('g2*', 4), ('b2', 4), ('e2', 8), ('f#2', 8), ('g2', 8), ('f#2', 8),
+ ('e2*', 4), ('a2', 4), ('b2', 4), ('a2', 4),
+ ('g2*', 4), ('f#2', 4), ('e2', 4), ('f#2', 4),
+ ('g2*', 4), ('c3', 4), ('d3', 4), ('d3', 4),
+ ('b2*', -2),
+)
+
+##########################################################################
+# Compute and print piano key frequency table
+##########################################################################
+pitchhz = {}
+keys_s = ('a', 'a#', 'b', 'c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#')
+keys_f = ('a', 'bb', 'b', 'c', 'db', 'd', 'eb', 'e', 'f', 'gb', 'g', 'ab')
+
+if __name__ == '__main__':
+ print "Piano key frequencies (for equal temperament):"
+ print "Key number\tScientific name\tFrequency (Hz)"
+for k in range(88):
+ freq = 27.5 * 2.**(k/12.)
+ oct = (k+9) // 12
+ note = '%s%u' % (keys_s[k%12], oct)
+ if __name__ == '__main__':
+ print "%10u\t%15s\t%14.2f" % (k+1, note.upper(), freq)
+ pitchhz[note] = freq
+ note = '%s%u' % (keys_f[k%12], oct)
+ pitchhz[note] = freq
+
+##########################################################################
+#### Main program starts below
+##########################################################################
+# Some parameters:
+
+# Beats (quarters) per minute
+# e.g. bpm = 95
+
+# Octave shift (neg. integer -> lower; pos. integer -> higher)
+# e.g. transpose = 0
+
+# Pause between notes as a fraction (0. = legato and e.g., 0.5 = staccato)
+# e.g. pause = 0.05
+
+# Volume boost for asterisk notes (1. = no boost)
+# e.g. boost = 1.2
+
+# Output file name
+#fn = 'pysynth_output.wav'
+
+# Other parameters:
+
+# Influences the decay of harmonics over frequency. Lowering the
+# value eliminates even more harmonics at high frequencies.
+# Suggested range: between 3. and 5., depending on the frequency response
+# of speakers/headphones used
+harm_max = 4.
+##########################################################################
+
+import wave, math, struct
+
+def make_wav(song,bpm=120,transpose=0,pause=.05,boost=1.1,repeat=0,fn="out.wav"):
+ f=wave.open(fn,'w')
+
+ f.setnchannels(1)
+ f.setsampwidth(2)
+ f.setframerate(44100)
+ f.setcomptype('NONE','Not Compressed')
+
+ bpmfac = 120./bpm
+
+ def length(l):
+ return 88200./l*bpmfac
+
+ def waves2(hz,l):
+ a=44100./hz
+ b=float(l)/44100.*hz
+ return [a,round(b)]
+
+ def sixteenbit(x):
+ return struct.pack('h', round(32000*x))
+
+ def asin(x):
+ return math.sin(2.*math.pi*x)
+
+ def render2(a,b,vol):
+ b2 = (1.-pause)*b
+ l=waves2(a,b2)
+ ow=""
+ q=int(l[0]*l[1])
+
+ # harmonics are frequency-dependent:
+ lf = math.log(a)
+ lf_fac = (lf-3.) / harm_max
+ if lf_fac > 1: harm = 0
+ else: harm = 2. * (1-lf_fac)
+ decay = 2. / lf
+ t = (lf-3.) / (8.5-3.)
+ volfac = 1. + .8 * t * math.cos(math.pi/5.3*(lf-3.))
+
+ for x in range(q):
+ fac=1.
+ if x<100: fac=x/80.
+ if 100<=x<300: fac=1.25-(x-100)/800.
+ if x>q-400: fac=1.-((x-q+400)/400.)
+ s = float(x)/float(q)
+ dfac = 1. - s + s * decay
+ ow=ow+sixteenbit((asin(float(x)/l[0])
+ +harm*asin(float(x)/(l[0]/2.))
+ +.5*harm*asin(float(x)/(l[0]/4.)))/4.*fac*vol*dfac*volfac)
+ fill = max(int(ex_pos - curpos - q), 0)
+ f.writeframesraw((ow)+(sixteenbit(0)*fill))
+ return q + fill
+
+ ##########################################################################
+ # Write to output file (in WAV format)
+ ##########################################################################
+
+ print "Writing to file", fn
+ curpos = 0
+ ex_pos = 0.
+ for rp in range(repeat+1):
+ for nn, x in enumerate(song):
+ if not nn % 4:
+ print "[%u/%u]\t" % (nn+1,len(song))
+ if x[0]!='r':
+ if x[0][-1] == '*':
+ vol = boost
+ note = x[0][:-1]
+ else:
+ vol = 1.
+ note = x[0]
+ try:
+ a=pitchhz[note]
+ except:
+ a=pitchhz[note + '4'] # default to fourth octave
+ a = a * 2**transpose
+ if x[1] < 0:
+ b=length(-2.*x[1]/3.)
+ else:
+ b=length(x[1])
+ ex_pos = ex_pos + b
+ curpos = curpos + render2(a,b,vol)
+
+ if x[0]=='r':
+ b=length(x[1])
+ ex_pos = ex_pos + b
+ f.writeframesraw(sixteenbit(0)*int(b))
+ curpos = curpos + int(b)
+
+ f.writeframes('')
+ f.close()
+ print
+
+def mix_files(a, b, c, chann = 2, phase = -1.):
+ f1 = wave.open(a,'r')
+ f2 = wave.open(b,'r')
+ f3 = wave.open(c,'w')
+ f3.setnchannels(chann)
+ f3.setsampwidth(2)
+ f3.setframerate(44100)
+ f3.setcomptype('NONE','Not Compressed')
+ frames = min(f1.getnframes(), f2.getnframes())
+
+ print "Mixing files, total length %.2f s..." % (frames / 44100.)
+ d1 = f1.readframes(frames)
+ d2 = f2.readframes(frames)
+ for n in range(frames):
+ if not n%(5*44100): print n // 44100, 's'
+ if chann < 2:
+ d3 = struct.pack('h',
+ .5 * (struct.unpack('h', d1[2*n:2*n+2])[0] +
+ struct.unpack('h', d2[2*n:2*n+2])[0]))
+ else:
+ d3 = ( struct.pack('h',
+ phase * .3 * struct.unpack('h', d1[2*n:2*n+2])[0] +
+ .7 * struct.unpack('h', d2[2*n:2*n+2])[0]) +
+ struct.pack('h',
+ .7 * struct.unpack('h', d1[2*n:2*n+2])[0] +
+ phase * .3 * struct.unpack('h', d2[2*n:2*n+2])[0]) )
+ f3.writeframesraw(d3)
+ f3.close()
+
+##########################################################################
+# Synthesize demo songs
+##########################################################################
+
+if __name__ == '__main__':
+ print
+ print "Creating Demo Songs... (this might take about a minute)"
+ print
+
+ # SONG 1
+ make_wav(song1, fn = "pysynth_scale.wav")
+
+ # SONG 2
+ make_wav(song2, bpm = 95, boost = 1.2, fn = "pysynth_anthem.wav")
+
+ # SONG 3
+ make_wav(song3, bpm = 132/2, pause = 0., boost = 1.1, fn = "pysynth_chopin.wav")
+
+ # SONG 4
+ # right hand part
+ make_wav(song4_rh, bpm = 130, transpose = 1, pause = .1, boost = 1.15, repeat = 1, fn = "pysynth_bach_rh.wav")
+ # left hand part
+ make_wav(song4_lh, bpm = 130, transpose = 1, pause = .1, boost = 1.15, repeat = 1, fn = "pysynth_bach_lh.wav")
+ # mix both files together
+ mix_files("pysynth_bach_rh.wav", "pysynth_bach_lh.wav", "pysynth_bach.wav")
diff --git a/src/piano-activity/resources/piano/convert_icon.svg b/src/piano-activity/resources/piano/convert_icon.svg
new file mode 100644
index 0000000..8f492d3
--- /dev/null
+++ b/src/piano-activity/resources/piano/convert_icon.svg
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="218.16225"
+ height="217.35884"
+ id="svg3110"
+ version="1.1"
+ inkscape:version="0.48.1 "
+ sodipodi:docname="New document 2">
+ <defs
+ id="defs3112">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3946">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3948" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3950" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3693-7"
+ id="linearGradient2924"
+ gradientUnits="userSpaceOnUse"
+ x1="-495.71429"
+ y1="875.21936"
+ x2="-495.71429"
+ y2="209.50504" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3693-7">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3695-4" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3697-0" />
+ </linearGradient>
+ <filter
+ inkscape:collect="always"
+ id="filter3932"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.1415432"
+ id="feGaussianBlur3934" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3946"
+ id="linearGradient3952"
+ x1="-1181.7566"
+ y1="-115.88824"
+ x2="-154.17836"
+ y2="883.38348"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3693-7"
+ id="linearGradient3962"
+ gradientUnits="userSpaceOnUse"
+ x1="-495.71429"
+ y1="875.21936"
+ x2="-495.71429"
+ y2="209.50504" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3946"
+ id="linearGradient3964"
+ gradientUnits="userSpaceOnUse"
+ x1="-1181.7566"
+ y1="-115.88824"
+ x2="-154.17836"
+ y2="883.38348" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.24748737"
+ inkscape:cx="187.55357"
+ inkscape:cy="100.1766"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1280"
+ inkscape:window-height="744"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata3115">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-29.86263,-37.103949)">
+ <g
+ id="g3954"
+ transform="matrix(0.49056853,0,0,0.49056853,-2.6238144,-8.8524339)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#008000;stroke-width:30;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path2930"
+ sodipodi:cx="-495.71429"
+ sodipodi:cy="542.36218"
+ sodipodi:rx="332.85715"
+ sodipodi:ry="332.85715"
+ d="m -162.85715,542.36218 c 0,183.83193 -149.02522,332.85715 -332.85714,332.85715 -183.83193,0 -332.85715,-149.02522 -332.85715,-332.85715 0,-183.83192 149.02522,-332.85714 332.85715,-332.85714 183.83192,0 332.85714,149.02522 332.85714,332.85714 z"
+ transform="matrix(0.63921388,0,0,0.63685992,605.43889,-30.189412)" />
+ <path
+ d="m -162.85715,542.36218 c 0,183.83193 -149.02522,332.85715 -332.85714,332.85715 -183.83193,0 -332.85715,-149.02522 -332.85715,-332.85715 0,-183.83192 149.02522,-332.85714 332.85715,-332.85714 183.83192,0 332.85714,149.02522 332.85714,332.85714 z"
+ sodipodi:ry="332.85715"
+ sodipodi:rx="332.85715"
+ sodipodi:cy="542.36218"
+ sodipodi:cx="-495.71429"
+ id="path3790"
+ style="fill:#ccff00;fill-opacity:1;stroke:none"
+ sodipodi:type="arc"
+ transform="matrix(0.55942056,0,0,0.55736044,565.8842,12.928098)" />
+ <path
+ id="path2999"
+ d="m 288.55771,129.68947 c -102.83936,0 -186.19265,83.06921 -186.19265,185.52986 0,102.46065 83.35329,185.52986 186.19265,185.52986 102.83936,0 186.22009,-83.06921 186.22009,-185.52986 0,-102.46065 -83.38073,-185.52986 -186.22009,-185.52986 z m 47.03412,56.94228 c 2.78767,-0.39886 3.99568,4.54503 5.69447,6.11917 13.26093,23.48705 27.48896,46.85193 38.73882,71.33368 15.16784,32.80939 2.76333,80.09864 -30.6899,94.47886 -19.11489,6.05745 -23.58517,-23.40079 -8.21318,-30.90748 24.63895,-20.46337 11.39616,-55.9327 2.08067,-81.13568 l -27.24037,93.45901 c -12.56062,33.90618 -13.5354,79.84903 -48.34823,98.78494 -36.90266,18.94012 -83.6128,-18.47057 -76.13614,-59.80355 3.48816,-44.01304 63.65585,-64.42389 91.65904,-31.5024 l 30.38875,-99.46487 c 7.6151,-19.78493 10.13275,-43.11266 20.77934,-60.82342 0.46945,-0.29986 0.88849,-0.48129 1.28673,-0.53826 z"
+ style="fill:#008000;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.55942056,0,0,0.55736044,565.8842,12.928098)"
+ sodipodi:type="arc"
+ style="opacity:0.6419214;fill:url(#linearGradient3962);fill-opacity:1;stroke:none"
+ id="path2936"
+ sodipodi:cx="-495.71429"
+ sodipodi:cy="542.36218"
+ sodipodi:rx="332.85715"
+ sodipodi:ry="332.85715"
+ d="m -162.85715,542.36218 c 0,183.83193 -149.02522,332.85715 -332.85714,332.85715 -183.83193,0 -332.85715,-149.02522 -332.85715,-332.85715 0,-183.83192 149.02522,-332.85714 332.85715,-332.85714 183.83192,0 332.85714,149.02522 332.85714,332.85714 z" />
+ <path
+ style="opacity:0.23451329;fill:#ffffff;fill-opacity:0.96446701;stroke:none;filter:url(#filter3932)"
+ d="m 288.88587,127.45467 c -102.83935,0 -186.21065,83.04378 -186.21065,185.50441 0,59.85955 28.47349,113.09986 72.64148,147.02245 -29.94442,-32.9227 -48.18773,-76.59435 -48.18773,-124.52341 0,-102.46063 83.37129,-185.52491 186.21064,-185.52491 42.74474,0 82.12002,14.35399 113.54866,38.48197 -34.06874,-37.44551 -83.27972,-60.96051 -138.0024,-60.96051 z"
+ id="path2934"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.63921388,0,0,0.63685992,605.43889,-30.189412)"
+ d="m -162.85715,542.36218 c 0,183.83193 -149.02522,332.85715 -332.85714,332.85715 -183.83193,0 -332.85715,-149.02522 -332.85715,-332.85715 0,-183.83192 149.02522,-332.85714 332.85715,-332.85714 183.83192,0 332.85714,149.02522 332.85714,332.85714 z"
+ sodipodi:ry="332.85715"
+ sodipodi:rx="332.85715"
+ sodipodi:cy="542.36218"
+ sodipodi:cx="-495.71429"
+ id="path3936"
+ style="fill:none;stroke:url(#linearGradient3964);stroke-width:30;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]