
    rh8                    (   S r SSKJr  SSKrSSKJr  SSKJr  SSKJr  SSKJr  SSKJ	r	  SS	KJ
r
  \R                  " S
5      r/ SQrSSSSSSSSSSS.
rSSSSSSSSS.rS  rS!S"S#S$S%S&S'S(S)S*S+S+S,S-S..r " S/ S0\R$                  5      r " S1 S2\R(                  5      r " S3 S4\	R,                  5      r " S5 S6\5      r " S7 S8\5      r " S9 S:\R4                  5      r " S; S<\R4                  5      r\\/r\S=:X  a  SSKr\R>                  " \5        gg)>z
Classes and functions for creating and manipulating dynamic symbols. Rather than
subclasses, the :class:`~music21.dynamics.Dynamic` object is often specialized by parameters.
    )annotationsN)base)common)environment)exceptions21)spanner)styledynamics)pppppppppppppppppppppmpmfffpsfffffffffffffffffffffpianississimo
pianissimopiano
mezzopiano
mezzoforteforte
fortepiano	sforzando
fortissimofortississimo)
r   r   r   r   r   r   r   r   r   r   zextremely soft	very softsoftzmoderately softzmoderately loudloudz	very loudzextremely loud)r   r   r   r   r   r   r   r   c                    U b  U S::  a  gU S:  a  gU S:  a  gU S:  a  gU S	:  a  g
U S:  a  gU S:  a  gU S:  a  gU S:  a  gg)a9  
Given a decimal from 0 to 1, return a string representing a dynamic
with 0 being the softest (0.01 = 'ppp') and 1 being the loudest (0.9+ = 'fff')
0 returns "n" (niente), while ppp and fff are the loudest dynamics used.


>>> dynamics.dynamicStrFromDecimal(0.25)
'pp'
>>> dynamics.dynamicStrFromDecimal(1)
'fff'
r   ng)\(?r   g{Gz?r   gp=
ף?r   g
ףp=
?r         ?r   g?r   g?r   ?r   r    )r)   s    J/home/james-whalen/.local/lib/python3.13/site-packages/music21/dynamics.pydynamicStrFromDecimalr.   6   se     	yAF	
T	
T	
T	
T	
S	
T	
S	
S    r*   g        g?g333333?      ?gffffff?g?g?gffffff?g      ?g333333?r+   gffffff?)Nr)   r   r   r   r   r   r   r   r   r   r   r   r   c                      \ rS rSrSrg)DynamicExceptionl   r,   N)__name__
__module____qualname____firstlineno____static_attributes__r,   r/   r-   r2   r2   l   s    r/   r2   c                     ^  \ rS rSr% SrSr\R                  rSS/r	SSSS	.r
S
\S'   SU 4S jjrS rS rS r\" \\SS9rS rS r\" \\SS9rSrU =r$ )Dynamicq   a  
Object representation of Dynamics.

>>> pp1 = dynamics.Dynamic('pp')
>>> pp1.value
'pp'
>>> pp1.longName
'pianissimo'
>>> pp1.englishName
'very soft'

Dynamics can also be specified on a 0 to 1 scale with 1 being the
loudest (see dynamicStrFromDecimal() above)

>>> ppp = dynamics.Dynamic(0.15)  # on 0 to 1 scale
>>> ppp.value
'ppp'
>>> print('%.2f' % ppp.volumeScalar)
0.15

Note that we got lucky last time because the dynamic 0.15 exactly corresponds
to what we've considered the default for 'ppp'.  Here we assign 0.98 which
is close to the 0.9 that is the default for 'fff' -- but the 0.98 will
be retained in the .volumeScalar

>>> loud = dynamics.Dynamic(0.98)  # on 0 to 1 scale
>>> loud.value
'fff'
>>> print('%.2f' % loud.volumeScalar)
0.98

Transferring the .value ('fff') to a new Dynamic object will set the volumeScalar
back to 0.9

>>> loud2 = dynamics.Dynamic(loud.value)
>>> loud2.value
'fff'
>>> print('%.2f' % loud2.volumeScalar)
0.90

Custom dynamics are possible:

>>> myDyn = dynamics.Dynamic('rfzsfmp')
>>> myDyn.value
'rfzsfmp'
>>> print(myDyn.volumeScalar)
0.5
>>> myDyn.volumeScalar = 0.87
>>> myDyn.volumeScalar
0.87

Dynamics can be placed anywhere in a stream.


>>> s = stream.Stream()
>>> s.insert(0, note.Note('E-4', type='half'))
>>> s.insert(2, note.Note('F#5', type='half'))
>>> s.insert(0, dynamics.Dynamic('pp'))
>>> s.insert(1, dynamics.Dynamic('mf'))
>>> s.insert(3, dynamics.Dynamic('fff'))
>>> #_DOCS_SHOW s.show()

.. image:: images/dynamics_simple.*
    :width: 344


   longNameenglishNamez
            the name of this dynamic in Italian.


            >>> d = dynamics.Dynamic('pp')
            >>> d.longName
            'pianissimo'
            z
            the name of this dynamic in English.


            >>> d = dynamics.Dynamic('pp')
            >>> d.englishName
            'very soft'
            a}  
            Staff placement: 'above', 'below', or None.

            A setting of None implies that the placement will be determined
            by notation software and no particular placement is demanded.

            This is not placed in the `.style` property, since for some dynamics,
            the placement above or below an object has semantic
            meaning and is not purely presentational.  For instance, a dynamic
            placed between two staves in a piano part implies that it applies
            to both hands, while one placed below the lower staff would apply
            only to the left hand.
            )r=   r>   	placementzdict[str, str]	_DOC_ATTRc                  > [         TU ]  " S0 UD6  S U l        S U l        S U l        S U l        [        U[        5      (       d  Xl        [        U5      U l	        OXl	        SU R                  l        SU R                  l        S U l        g )Niir,   )super__init___volumeScalarr=   r>   _value
isinstancestrr.   valuer	   	absoluteX	absoluteYr?   )selfrH   keywords	__class__s      r-   rC   Dynamic.__init__   sx    $8$
 "%%%!&.u5DJJ  #

"

r/   c                ,    [        U R                  5      $ N)rG   rH   rK   s    r-   _reprInternalDynamic._reprInternal   s    4::r/   c                    U R                   $ rP   )rE   rQ   s    r-   	_getValueDynamic._getValue   s    {{r/   c                    Xl         U R                   [        ;   a  [        U R                      U l        OS U l        U R                   [        ;   a  [        U R                      U l        g S U l        g rP   )rE   	longNamesr=   englishNamesr>   rK   rH   s     r-   	_setValueDynamic._setValue   sO    ;;)#%dkk2DM DM;;,&+DKK8D#Dr/   a  
        Get or set the value of this dynamic, which sets the long and
        English names of this Dynamic. The value is a string specification.

        >>> p = dynamics.Dynamic('p')
        >>> p.value
        'p'
        >>> p.englishName
        'soft'
        >>> p.longName
        'piano'

        >>> p.value = 'f'
        >>> p.value
        'f'
        >>> p.englishName
        'loud'
        >>> p.longName
        'forte'
        )docc                   U R                   b  U R                   $ U R                  [        ;   a  [        U R                     $ U R                  nSU;   a  USS  nUS   S:X  a  US S nU[        ;   a	  [        U   $ [        S    $ )Ns   z)rD   rE   dynamicStrToScalar)rK   thisDynamics     r-   _getVolumeScalarDynamic._getVolumeScalar  s    )%%%[[..%dkk22++Kk!)!"o2#%)#2.00)+66)$//r/   c                    [         R                  " U5      (       a  SUs=::  a  S::  a
  O  OXl        g [        SU 35      e)Nr   r`   z cannot set as volume scalar to: )r   isNumrD   r2   rZ   s     r-   _setVolumeScalarDynamic._setVolumeScalar+  s4    <<1??!&"%EeW#MNNr/   a  
        Get or set the volume scalar for this dynamic. If not explicitly set, a
        default volume scalar will be provided. Any number between 0 and 1 can be
        used to set the volume scalar, overriding the expected behavior.

        As mezzo is at 0.5, the unit interval range is doubled for
        generating final output. The default output is 0.5.


        >>> d = dynamics.Dynamic('mf')
        >>> d.volumeScalar
        0.55...

        >>> d.volumeScalar = 0.1
        >>> d.volumeScalar
        0.1
        >>> d.value
        'mf'


        int(volumeScalar \* 127) gives the MusicXML <sound dynamics="x"/> tag

        >>> xmlOut = musicxml.m21ToXml.GeneralObjectExporter().parse(d).decode('utf-8')
        >>> print(xmlOut)
        <?xml...
        <direction>
            <direction-type>
              <dynamics default-x="-36" default-y="-80">
                <mf />
              </dynamics>
            </direction-type>
            <sound dynamics="12" />
        </direction>...
        )rE   rD   r>   r=   r?   rH   rP   )r4   r5   r6   r7   __doc__classSortOrderr	   	TextStyle_styleClass
_DOC_ORDERr@   __annotations__rC   rR   rU   r[   propertyrH   re   ri   volumeScalarr8   __classcell__rM   s   @r-   r:   r:   q   s    AD N//Km,J#!I~ >2
$ Y	E,0&O ,.> !E !Lr/   r:   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )DynamicWedgeiW  z1
Common base-class for Crescendo and Diminuendo.
c                ^   > [         TU ]  " U0 UD6  S U l        SU l        SU l        SU l        g )Nbelow   F)rB   rC   typer?   spreadnienterK   spannedElementsrL   rM   s      r-   rC   DynamicWedge.__init__\  s3    /6X6
 	 r/   )r|   r?   r{   rz   r4   r5   r6   r7   rk   rC   r8   rs   rt   s   @r-   rv   rv   W  s    	 	r/   rv   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )	Crescendoih  z
A spanner crescendo wedge.

>>> d = dynamics.Crescendo()
>>> d.spread
15
>>> d.spread = 20
>>> d.spread
20
>>> d.type
'crescendo'
c                4   > [         TU ]  " U0 UD6  SU l        g )N	crescendorB   rC   rz   r}   s      r-   rC   Crescendo.__init__v  s    /6X6	r/   rz   r   rt   s   @r-   r   r   h  s       r/   r   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )
Diminuendoi{  z^
A spanner diminuendo wedge.

>>> d = dynamics.Diminuendo()
>>> d.spread = 20
>>> d.spread
20
c                4   > [         TU ]  " U0 UD6  SU l        g )N
diminuendor   r}   s      r-   rC   Diminuendo.__init__  s    /6X6 	r/   r   r   rt   s   @r-   r   r   {  s    ! !r/   r   c                  $    \ rS rSrSrS rS rSrg)TestExternali  Tc                ^    [        S5      nU R                  (       a  UR                  5         g g )Nr   )r:   show)rK   as     r-   
testSingleTestExternal.testSingle  s     FO99FFH r/   c                    SSK Jn  UR                  5       nSn[         H$  n[	        U5      nUR                  X55        US-  nM&     U R                  (       a  UR                  5         gg)z*
present each dynamic in a single measure
r   stream   N)music21r   Stream
shortNamesr:   insertr   )rK   r   r   odynStrbs         r-   	testBasicTestExternal.testBasic  sU     	#MMO FAHHQNFA ! 99FFH r/   r,   N)r4   r5   r6   r7   r   r   r   r8   r,   r/   r-   r   r     s    D
r/   r   c                  8    \ rS rSrS rS rS rS rS rS r	Sr
g	)
Testi  c                2    SSK Jn  U" U [        5       5        g )Nr   )testCopyAll)music21.test.commonTestr   globals)rK   r   s     r-   testCopyAndDeepcopyTest.testCopyAndDeepcopy  s    7D')$r/   c                    [        5       nUR                  b   e[        S5      nU R                  UR                  S5        U R                  UR                  S5        U R                  UR                  S5        g )Nr   r   r%   )r:   r=   assertEqualrH   r>   )rK   noDynr   s      r-   r   Test.testBasic  s^    	~~%%%T]4(l35r/   c                   SSK Jn  SSK Jn  UR                  S5      nUR                  S   R                  5       R                  UR                  5      nU R                  [        U5      S5        UR                  S   R                  5       R                  UR                  5      nU R                  [        U5      S5        g )Nr   )corpus)r
   zopus41no1/movement2#      )r   r   r
   parsepartsflattengetElementsByClassr:   r   lenrv   )rK   r   r
   r   r   s        r-   testCorpusDynamicsWedgeTest.testCorpusDynamicsWedge  s    "$LL./GGAJ 33H4D4DEQ$GGAJ 33H4I4IJQ#r/   c                    SSK Jn  [        S5      nUR                  5       R	                  U5      R                  S5      nSnU R                  UR                  U5      SU5        g )Nr   )m21ToXmlr   zutf-8z<p />ra   )music21.musicxmlr   r:   GeneralObjectExporterr   decodeassertNotEqualfind)rK   r   dxmlOutmatchs        r-   testMusicxmlOutputTest.testMusicxmlOutput  sR    -CL//177:AA'JFKK.F;r/   c                    SSK Jn  SSK Jn  UR                  5       n/ SQn[	        S5       HM  n[        XE[        U5      -     5      nUR                  U5        UR                  UR                  S5      5        MO     g )Nr   r   note)r   r   r   r   r<   c1)	r   r   r   r   ranger:   r   appendNote)rK   r   r   r_   
selectionsir   s          r-   testDynamicsPositionATest.testDynamicsPositionA  s[    " MMO-
rA
s:#678AHHQKHHTYYt_% r/   c                V   SS K nSSKJn  SSKJn  SSKJn  UR                  5       n[        S5       Hb  nUR                  US-   S9nUR                  UR                  SS	95        UR                  UR                  S
S95        UR                  U5        Md     UR                  UR                  5      nU Hl  n[        S5       V	s/ s H  oS-  PM	     n
n	UR                  U
5        U
S S n
U
 H0  n[        S5      nSUR                  l        UR!                  X5        M2     Mn     g s  sn	f )Nr   r   r   )layout   r`   )numberT)isNewwholer      r0   r   r      )randomr   r   r   r   r   r   Measurer   SystemLayoutRestr   shuffler:   r	   rJ   r   )rK   r   r   r   r   r_   r   mstream_iteratorxoffsetsr   r   s                r-   testDynamicsPositionBTest.testDynamicsPositionB  s    " "MMOqAa!e,AHHV((t(45HHTYYGY,-HHQK	 
 ..v~~> A).r3A4xG3NN7#bqkGDM$&! 	 !3s   D&r,   N)r4   r5   r6   r7   r   r   r   r   r   r   r8   r,   r/   r-   r   r     s     %6	$<	&r/   r   __main__) rk   
__future__r   unittestr   r   r   r   r   r   r	   EnvironmentenvironLocalr   rX   rY   r.   rc   Music21Exceptionr2   Music21Objectr:   Spannerrv   r   r   TestCaser   r   ro   r4   mainTestr,   r/   r-   <module>r      s]   #        &&z2Q
#     $	&	 ("(("(*H 	
	

	


 &	|44 	
bd   bL7?? "   &! !"8$$ 0A8 AN ,-
zT r/   