<commit_before>    # -*- coding: utf-8 -*-
#
# Copyright (C) 2007 Parisson SARL
# Copyright (c) 2006-2007 <NAME> <<EMAIL>>

# This file is part of TimeSide.

# TimeSide 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.

# TimeSide 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 TimeSide.  If not, see <http://www.gnu.org/licenses/>.

# Authors: <NAME> <<EMAIL>>
#          <NAME> <<EMAIL>>

from timeside.core import Processor, implements, interfacedoc
from timeside.api import IEncoder
from numpy import array, frombuffer, getbuffer, float32
from timeside.core import FixedSizeInputAdapter

import numpy
import mutagen
import pygst
pygst.require('0.10')
import gst
import gobject
gobject.threads_init()


class Mp3Encoder(Processor):
    """ gstreamer-based mp3 encoder """
    implements(IEncoder)

    def __init__(self, output, streaming=False):
        if isinstance(output, basestring):
            self.filename = output
        else:
            self.filename = None

        self.streaming = streaming
        if not self.filename and not self.streaming:
            raise Exception('Must give an output')
        
        self.metadata = None
        self.eod = False
        
    @interfacedoc
    def setup(self, channels=None, samplerate=None, nframes=None):
        self.channels = channels
        super(Mp3Encoder, self).setup(channels, samplerate, nframes)
        #TODO: open file for writing
        # the output data format we want        
        self.pipe = '''appsrc name=src
                  ! audioconvert 
                  ! lamemp3enc target=quality quality=2 encoding-engine-quality=standard ! id3v2mux 
                  '''
        if self.filename and self.streaming:
            self.pipe += ''' ! tee name=t
            ! queue ! filesink location=%s
            t. ! queue ! appsink name=app sync=False
            ''' % self.filename
            
        elif self.filename :
            self.pipe += '! filesink location=%s sync=False ' % self.filename
        else:
            self.pipe += '! queue ! appsink name=app sync=False '
            
        self.pipeline = gst.parse_launch(self.pipe)
        # store a pointer to appsrc in our encoder object
        self.src = self.pipeline.get_by_name('src')
        # store a pointer to appsink in our encoder object
        self.app = self.pipeline.get_by_name('app')
        
        srccaps = gst.Caps("""audio/x-raw-float,
            endianness=(int)1234,
            channels=(int)%s,
            width=(int)32,
            rate=(int)%d""" % (int(channels), int(samplerate)))
        self.src.set_property("caps", srccaps)
        
        self.pipeline.set_state(gst.STATE_PLAYING)
    
    @staticmethod
    @interfacedoc
    def id():
        return "gst_mp3_enc"

    @staticmethod
    @interfacedoc
    def description():
        return "MP3 GStreamer based encoder"

    @staticmethod
    @interfacedoc
    def format():
        return "MP3"

    @staticmethod
    @interfacedoc
    def file_extension():
        return "mp3"

    @staticmethod
    @interfacedoc
    def mime_type():
        return "audio/mpeg"

    @interfacedoc
    def set_metadata(self, metadata):
        self.metadata = metadata
  
    def write_metadata(self, file):
        """Write all ID3v2.4 tags to file from self.metadata"""
        from mutagen import id3
        id3 = id3.ID3(file)
        for tag in self.metadata.keys():
            value = self.metadata[tag]
            frame = mutagen.id3.Frames[tag](3,value)
            try:
                id3.add(frame)
            except:
                raise IOError('EncoderError: cannot tag "'+tag+'"')
        try:
            id3.save()
        except:
            raise IOError('EncoderError: cannot write tags')
    
    @interfacedoc
    def process(self, frames, eod=False):
        self.eod = eod
        buf = self.numpy_array_to_gst_buffer(frames)
        self.src.emit('push-buffer', buf)
        if self.streaming:
            self.chunk = self.app.emit('pull-buffer')
        if self.eod and self.metadata and self.filename:
            self.write_metadata(self.filename)
        return frames, eod
        
    def numpy_array_to_gst_buffer(self, frames):
        """ gstreamer buffer to numpy array conversion """
        buf = gst.Buffer(getbuffer(frames))
        return buf


class Mp3EncoderSubprocess(object):
    """MP3 encoder in a subprocess pipe"""<commit_msg>use self.filename for tag writting<commit_after>    # -*- coding: utf-8 -*-
#
# Copyright (C) 2007 Parisson SARL
# Copyright (c) 2006-2007 <NAME> <<EMAIL>>

# This file is part of TimeSide.

# TimeSide 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.

# TimeSide 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 TimeSide.  If not, see <http://www.gnu.org/licenses/>.

# Authors: <NAME> <<EMAIL>>
#          <NAME> <<EMAIL>>

from timeside.core import Processor, implements, interfacedoc
from timeside.api import IEncoder
from numpy import array, frombuffer, getbuffer, float32
from timeside.core import FixedSizeInputAdapter

import numpy
import mutagen
import pygst
pygst.require('0.10')
import gst
import gobject
gobject.threads_init()


class Mp3Encoder(Processor):
    """ gstreamer-based mp3 encoder """
    implements(IEncoder)

    def __init__(self, output, streaming=False):
        if isinstance(output, basestring):
            self.filename = output
        else:
            self.filename = None

        self.streaming = streaming
        if not self.filename and not self.streaming:
            raise Exception('Must give an output')
        
        self.metadata = None
        self.eod = False
        
    @interfacedoc
    def setup(self, channels=None, samplerate=None, nframes=None):
        self.channels = channels
        super(Mp3Encoder, self).setup(channels, samplerate, nframes)
        #TODO: open file for writing
        # the output data format we want        
        self.pipe = '''appsrc name=src
                  ! audioconvert 
                  ! lamemp3enc target=quality quality=2 encoding-engine-quality=standard ! id3v2mux 
                  '''
        if self.filename and self.streaming:
            self.pipe += ''' ! tee name=t
            ! queue ! filesink location=%s
            t. ! queue ! appsink name=app sync=False
            ''' % self.filename
            
        elif self.filename :
            self.pipe += '! filesink location=%s sync=False ' % self.filename
        else:
            self.pipe += '! queue ! appsink name=app sync=False '
            
        self.pipeline = gst.parse_launch(self.pipe)
        # store a pointer to appsrc in our encoder object
        self.src = self.pipeline.get_by_name('src')
        # store a pointer to appsink in our encoder object
        self.app = self.pipeline.get_by_name('app')
        
        srccaps = gst.Caps("""audio/x-raw-float,
            endianness=(int)1234,
            channels=(int)%s,
            width=(int)32,
            rate=(int)%d""" % (int(channels), int(samplerate)))
        self.src.set_property("caps", srccaps)
        
        self.pipeline.set_state(gst.STATE_PLAYING)
    
    @staticmethod
    @interfacedoc
    def id():
        return "gst_mp3_enc"

    @staticmethod
    @interfacedoc
    def description():
        return "MP3 GStreamer based encoder"

    @staticmethod
    @interfacedoc
    def format():
        return "MP3"

    @staticmethod
    @interfacedoc
    def file_extension():
        return "mp3"

    @staticmethod
    @interfacedoc
    def mime_type():
        return "audio/mpeg"

    @interfacedoc
    def set_metadata(self, metadata):
        self.metadata = metadata
  
    def write_metadata(self):
        """Write all ID3v2.4 tags to file from self.metadata"""
        from mutagen import id3
        id3 = id3.ID3(self.filename)
        for tag in self.metadata.keys():
            value = self.metadata[tag]
            frame = mutagen.id3.Frames[tag](3,value)
            try:
                id3.add(frame)
            except:
                raise IOError('EncoderError: cannot tag "'+tag+'"')
        try:
            id3.save()
        except:
            raise IOError('EncoderError: cannot write tags')
    
    @interfacedoc
    def process(self, frames, eod=False):
        self.eod = eod
        buf = self.numpy_array_to_gst_buffer(frames)
        self.src.emit('push-buffer', buf)
        if self.streaming:
            self.chunk = self.app.emit('pull-buffer')
        if self.eod and self.metadata and self.filename:
            self.write_metadata()
        return frames, eod
        
    def numpy_array_to_gst_buffer(self, frames):
        """ gstreamer buffer to numpy array conversion """
        buf = gst.Buffer(getbuffer(frames))
        return buf


class Mp3EncoderSubprocess(object):
    """MP3 encoder in a subprocess pipe"""
{'fraction_non_alphanumeric': 0.09538493164765136, 'fraction_numerical': 0.01007297769554939, 'mean_word_length': 2.2683909976486394, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2452131', 'n_tokens_mistral': 2844, 'n_tokens_neox': 2749, 'n_words': 826}