2013-11-25 9 views
4

У меня есть следующие миди обертка для Python3:MIDIGetNumberOfDestinations возвращающиеся 0 при использовании Python C API

#include <Python.h> 
#include "structmember.h" 
#include <CoreMIDI/CoreMIDI.h> 
#include "stdio.h" 

#define MESSAGESIZE 3 

// CFStringRef to char* 
char * MYCFStringCopyUTF8String(CFStringRef aString) { 
    if (aString == NULL) { 
    return NULL; 
    } 

    CFIndex length = CFStringGetLength(aString); 
    CFIndex maxSize = 
    CFStringGetMaximumSizeForEncoding(length, 
            kCFStringEncodingUTF8); 
    char *buffer = (char *)malloc(maxSize); 
    if (CFStringGetCString(aString, buffer, maxSize, 
         kCFStringEncodingUTF8)) { 
    return buffer; 
    } 
    return NULL; 
} 

typedef struct { 
    PyObject_HEAD 
} Midi; 

static void Midi_dealloc(Midi* self) 
{ 
    Py_TYPE(self)->tp_free((PyObject*)self); 
} 

static int Midi_init(Midi *self) 
{ 
    ItemCount nDests = MIDIGetNumberOfDestinations(); 
    printf("INIT\n"); 
    for (ItemCount i = 0 ; i < nDests ; ++i) { 

     // Grab a reference to current device 
     MIDIDeviceRef device = MIDIGetDevice(i); 
     CFStringRef name = nil; 
     MIDIObjectGetStringProperty(device, kMIDIPropertyName, &name); 
     printf("%s\n", MYCFStringCopyUTF8String(name)); 
    } 
    printf("END\n");  
    return 0; 
} 

static PyObject * Midi_add(Midi* self, PyObject *args) 
{ 
     return Py_None; 
} 

static PyObject * Midi_bend(Midi* self, PyObject *args) 
{ 
     return Py_None; 
} 

static PyObject * Midi_play(Midi* self) 
{ 
    return Py_None; 
} 

static PyMethodDef Midi_methods[] = 
{ 
    {"add", (PyCFunction)Midi_add, METH_VARARGS, "Add note"}, 
    {"bend", (PyCFunction)Midi_bend, METH_VARARGS, "Bend note"}, 
    {"play", (PyCFunction)Midi_play, METH_NOARGS, "Play Notes"}, 
    {NULL} /* Sentinel */ 
}; 

static PyTypeObject MidiType = { 
    PyVarObject_HEAD_INIT(NULL, 0) 
    "midi.Midi",    /* tp_name */ 
    sizeof(Midi),    /* tp_basicsize */ 
    0,       /* tp_itemsize */ 
    (destructor)Midi_dealloc, /* tp_dealloc */ 
    0,       /* tp_print */ 
    0,       /* tp_getattr */ 
    0,       /* tp_setattr */ 
    0,       /* tp_reserved */ 
    0,       /* tp_repr */ 
    0,       /* tp_as_number */ 
    0,       /* tp_as_sequence */ 
    0,       /* tp_as_mapping */ 
    0,       /* tp_hash */ 
    0,       /* tp_call */ 
    0,       /* tp_str */ 
    0,       /* tp_getattro */ 
    0,       /* tp_setattro */ 
    0,       /* tp_as_buffer */ 
    Py_TPFLAGS_DEFAULT | 
     Py_TPFLAGS_BASETYPE, /* tp_flags */ 
    "Midi objects",   /* tp_doc */ 
    0,      /* tp_traverse */ 
    0,      /* tp_clear */ 
    0,      /* tp_richcompare */ 
    0,      /* tp_weaklistoffset */ 
    0,      /* tp_iter */ 
    0,      /* tp_iternext */ 
    Midi_methods,    /* tp_methods */ 
    0,     /* tp_members */ 
    0,       /* tp_getset */ 
    0,       /* tp_base */ 
    0,       /* tp_dict */ 
    0,       /* tp_descr_get */ 
    0,       /* tp_descr_set */ 
    0,       /* tp_dictoffset */ 
    (initproc)Midi_init,  /* tp_init */ 
}; 

static PyModuleDef midimodule = { 
    PyModuleDef_HEAD_INIT, 
    "midi", 
    "Midi Module", 
    -1, 
    NULL, NULL, NULL, NULL, NULL 
}; 

PyMODINIT_FUNC 
PyInit_midi(void) 
{ 
    PyObject* m; 

    MidiType.tp_new = PyType_GenericNew; 
    if (PyType_Ready(&MidiType) < 0) 
     return NULL; 

    m = PyModule_Create(&midimodule); 
    if (m == NULL) 
     return NULL; 

    Py_INCREF(&MidiType); 
    PyModule_AddObject(m, "Midi", (PyObject *)&MidiType); 
    return m; 
} 

Со следующим setup.py файл:

from distutils.core import setup, Extension 

module = Extension('midi', sources = ['midi.c'], extra_link_args=['-framework', 'CoreMIDI', '-framework', 'CoreFoundation']) 

setup (name = 'Midi', 
     version = '1.0', 
     description = 'Midi Controller', 
     ext_modules = [module]) 

Я тогда запустить этот питон код, но это дает мне:

import midi 
m = midi.Midi() 

но он выводит просто на Mavericks:

INIT 
END 

I.e. он не находит устройств.

Я также попытался это:

#import <CoreMIDI/CoreMIDI.h> 

char * MYCFStringCopyUTF8String(CFStringRef aString) { 
    if (aString == NULL) { 
    return NULL; 
    } 

    CFIndex length = CFStringGetLength(aString); 
    CFIndex maxSize = 
    CFStringGetMaximumSizeForEncoding(length, 
            kCFStringEncodingUTF8); 
    char *buffer = (char *)malloc(maxSize); 
    if (CFStringGetCString(aString, buffer, maxSize, 
         kCFStringEncodingUTF8)) { 
    return buffer; 
    } 
    return NULL; 
} 

int main(int argc, char *argv[]) 
{ 
    // How many MIDI devices do we have? 
    ItemCount deviceCount = MIDIGetNumberOfDevices(); 

    // Iterate through all MIDI devices 
    for (ItemCount i = 0 ; i < deviceCount ; ++i) { 

    // Grab a reference to current device 
    MIDIDeviceRef device = MIDIGetDevice(i); 
    CFStringRef name = nil; 
    MIDIObjectGetStringProperty(device, kMIDIPropertyName, &name); 
    printf("%s\n", MYCFStringCopyUTF8String(name)); 


} 
} 

С Нижеследующее файла:

SRCS =  midi2.c 
OBJS =  midi2.o 
LIBS =  -framework CoreMIDI -framework CoreFoundation 
TARGET = Midi2 

$(TARGET): $(OBJS) 
    $(CC) -o $(TARGET) $(SRCS) $(LIBS) 

all: $(TARGET) 

clean: 
    rm -f $(OBJS) $(TARGET) 

Какие правильно перечислены мои миди устройства. Что я делаю не так?

+0

MIDIGetNumberOfDestinations() возвращает «Число пунктов назначения в системе или 0, если произошла ошибка». Вы пытались каким-то образом отладить его? – twil

+0

@twil Что я могу отлаживать? Функция возвращает 2 при ее вызове из очень простой функции c и 0 при вызове с использованием API-интерфейса Python. Я думаю, что проблема связана с компоновщиком, хотя я не получаю ошибок при запуске установки python. Например, я могу изменить «CoreMIDI» на «Foo» в файле setup.py, и я не получаю ошибок. – Baz

+0

Почему вы вызываете 'MIDIGetNumberOfDestinations()' в примере Python, но 'MIDIGetNumberOfDevices()' в примере на C? –

ответ

3

Проблема была в том, что мой драйвер IAC был отключен. По умолчанию драйвер отключен.